blob: 367b4de0272ab033d4f0a96fd59c1bc34f1da5dc [file] [log] [blame]
Martin v. Löwise440e472004-06-01 15:22:42 +00001/* Generator object implementation */
2
3#include "Python.h"
4#include "frameobject.h"
5#include "genobject.h"
6#include "ceval.h"
7#include "structmember.h"
Phillip J. Eby2ba96612006-04-10 17:51:05 +00008#include "opcode.h"
Martin v. Löwise440e472004-06-01 15:22:42 +00009
10static int
11gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
12{
Phillip J. Eby8920bf22006-04-12 19:07:15 +000013 Py_VISIT(gen->gi_frame);
14 return 0;
Martin v. Löwise440e472004-06-01 15:22:42 +000015}
16
17static void
18gen_dealloc(PyGenObject *gen)
19{
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000020 PyObject *self = (PyObject *) gen;
21
Martin v. Löwise440e472004-06-01 15:22:42 +000022 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000023
Martin v. Löwise440e472004-06-01 15:22:42 +000024 if (gen->gi_weakreflist != NULL)
25 PyObject_ClearWeakRefs((PyObject *) gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000026
27
28 _PyObject_GC_TRACK(self);
29
Phillip J. Eby8920bf22006-04-12 19:07:15 +000030 if (gen->gi_frame!=NULL && gen->gi_frame->f_stacktop!=NULL) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000031 /* Generator is paused, so we need to close */
32 gen->ob_type->tp_del(self);
33 if (self->ob_refcnt > 0)
34 return; /* resurrected. :( */
35 }
36
37 _PyObject_GC_UNTRACK(self);
38 Py_XDECREF(gen->gi_frame);
Martin v. Löwise440e472004-06-01 15:22:42 +000039 PyObject_GC_Del(gen);
40}
41
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000042
Martin v. Löwise440e472004-06-01 15:22:42 +000043static PyObject *
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000044gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
Martin v. Löwise440e472004-06-01 15:22:42 +000045{
46 PyThreadState *tstate = PyThreadState_GET();
47 PyFrameObject *f = gen->gi_frame;
48 PyObject *result;
49
50 if (gen->gi_running) {
51 PyErr_SetString(PyExc_ValueError,
52 "generator already executing");
53 return NULL;
54 }
Phillip J. Eby8920bf22006-04-12 19:07:15 +000055 if (f==NULL || f->f_stacktop == NULL) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000056 /* Only set exception if called from send() */
57 if (arg && !exc) PyErr_SetNone(PyExc_StopIteration);
Martin v. Löwise440e472004-06-01 15:22:42 +000058 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000059 }
60
61 if (f->f_lasti == -1) {
62 if (arg && arg != Py_None) {
63 PyErr_SetString(PyExc_TypeError,
64 "can't send non-None value to a just-started generator");
65 return NULL;
66 }
67 } else {
68 /* Push arg onto the frame's value stack */
69 result = arg ? arg : Py_None;
70 Py_INCREF(result);
71 *(f->f_stacktop++) = result;
72 }
Martin v. Löwise440e472004-06-01 15:22:42 +000073
74 /* Generators always return to their most recent caller, not
75 * necessarily their creator. */
76 Py_XINCREF(tstate->frame);
77 assert(f->f_back == NULL);
78 f->f_back = tstate->frame;
79
80 gen->gi_running = 1;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000081 result = PyEval_EvalFrameEx(f, exc);
Martin v. Löwise440e472004-06-01 15:22:42 +000082 gen->gi_running = 0;
83
84 /* Don't keep the reference to f_back any longer than necessary. It
85 * may keep a chain of frames alive or it could create a reference
86 * cycle. */
Phillip J. Eby00148222005-08-13 03:29:00 +000087 assert(f->f_back == tstate->frame);
Raymond Hettinger75ccea32004-09-01 07:02:44 +000088 Py_CLEAR(f->f_back);
Martin v. Löwise440e472004-06-01 15:22:42 +000089
90 /* If the generator just returned (as opposed to yielding), signal
91 * that the generator is exhausted. */
92 if (result == Py_None && f->f_stacktop == NULL) {
93 Py_DECREF(result);
94 result = NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000095 /* Set exception if not called by gen_iternext() */
96 if (arg) PyErr_SetNone(PyExc_StopIteration);
97 }
98
99 if (!result || f->f_stacktop == NULL) {
100 /* generator can't be rerun, so release the frame */
101 Py_DECREF(f);
Phillip J. Eby8920bf22006-04-12 19:07:15 +0000102 gen->gi_frame = NULL;
Martin v. Löwise440e472004-06-01 15:22:42 +0000103 }
104
105 return result;
106}
107
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000108PyDoc_STRVAR(send_doc,
Neal Norwitz017749c2006-04-12 06:56:56 +0000109"send(arg) -> send 'arg' into generator,\n\
110return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000111
112static PyObject *
113gen_send(PyGenObject *gen, PyObject *arg)
114{
115 return gen_send_ex(gen, arg, 0);
116}
117
118PyDoc_STRVAR(close_doc,
119"close(arg) -> raise GeneratorExit inside generator.");
120
121static PyObject *
122gen_close(PyGenObject *gen, PyObject *args)
123{
124 PyObject *retval;
125 PyErr_SetNone(PyExc_GeneratorExit);
126 retval = gen_send_ex(gen, Py_None, 1);
127 if (retval) {
128 Py_DECREF(retval);
129 PyErr_SetString(PyExc_RuntimeError,
130 "generator ignored GeneratorExit");
131 return NULL;
132 }
133 if ( PyErr_ExceptionMatches(PyExc_StopIteration)
134 || PyErr_ExceptionMatches(PyExc_GeneratorExit) )
135 {
136 PyErr_Clear(); /* ignore these errors */
137 Py_INCREF(Py_None);
138 return Py_None;
139 }
140 return NULL;
141}
142
143static void
144gen_del(PyObject *self)
145{
146 PyObject *res;
147 PyObject *error_type, *error_value, *error_traceback;
148 PyGenObject *gen = (PyGenObject *)self;
149
Phillip J. Eby8920bf22006-04-12 19:07:15 +0000150 if (!gen->gi_frame || gen->gi_frame->f_stacktop==NULL)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000151 /* Generator isn't paused, so no need to close */
152 return;
153
154 /* Temporarily resurrect the object. */
155 assert(self->ob_refcnt == 0);
156 self->ob_refcnt = 1;
157
158 /* Save the current exception, if any. */
159 PyErr_Fetch(&error_type, &error_value, &error_traceback);
160
161 res = gen_close((PyGenObject *)self, NULL);
162
163 if (res == NULL)
164 PyErr_WriteUnraisable((PyObject *)self);
165 else
166 Py_DECREF(res);
167
168 /* Restore the saved exception. */
169 PyErr_Restore(error_type, error_value, error_traceback);
170
171 /* Undo the temporary resurrection; can't use DECREF here, it would
172 * cause a recursive call.
173 */
174 assert(self->ob_refcnt > 0);
175 if (--self->ob_refcnt == 0)
176 return; /* this is the normal path out */
177
178 /* close() resurrected it! Make it look like the original Py_DECREF
179 * never happened.
180 */
181 {
Martin v. Löwis725507b2006-03-07 12:08:51 +0000182 Py_ssize_t refcnt = self->ob_refcnt;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000183 _Py_NewReference(self);
184 self->ob_refcnt = refcnt;
185 }
186 assert(!PyType_IS_GC(self->ob_type) ||
187 _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
188
189 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
190 * we need to undo that. */
191 _Py_DEC_REFTOTAL;
192 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
193 * chain, so no more to do there.
194 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
195 * _Py_NewReference bumped tp_allocs: both of those need to be
196 * undone.
197 */
198#ifdef COUNT_ALLOCS
199 --self->ob_type->tp_frees;
200 --self->ob_type->tp_allocs;
201#endif
202}
203
204
205
206PyDoc_STRVAR(throw_doc,
Neal Norwitz017749c2006-04-12 06:56:56 +0000207"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
208return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000209
210static PyObject *
211gen_throw(PyGenObject *gen, PyObject *args)
212{
213 PyObject *typ;
214 PyObject *tb = NULL;
215 PyObject *val = NULL;
216
217 if (!PyArg_ParseTuple(args, "O|OO:throw", &typ, &val, &tb))
218 return NULL;
219
Armin Rigo967aa8b2006-02-14 15:50:44 +0000220 /* First, check the traceback argument, replacing None with
221 NULL. */
Tim Petersa5a80cb2006-04-12 06:44:36 +0000222 if (tb == Py_None)
Armin Rigo967aa8b2006-02-14 15:50:44 +0000223 tb = NULL;
Armin Rigo967aa8b2006-02-14 15:50:44 +0000224 else if (tb != NULL && !PyTraceBack_Check(tb)) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000225 PyErr_SetString(PyExc_TypeError,
226 "throw() third argument must be a traceback object");
227 return NULL;
228 }
229
230 Py_INCREF(typ);
231 Py_XINCREF(val);
232 Py_XINCREF(tb);
233
Brett Cannonbf364092006-03-01 04:25:17 +0000234 if (PyExceptionClass_Check(typ)) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000235 PyErr_NormalizeException(&typ, &val, &tb);
236 }
237
Brett Cannonbf364092006-03-01 04:25:17 +0000238 else if (PyExceptionInstance_Check(typ)) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000239 /* Raising an instance. The value should be a dummy. */
240 if (val && val != Py_None) {
241 PyErr_SetString(PyExc_TypeError,
242 "instance exception may not have a separate value");
243 goto failed_throw;
244 }
245 else {
246 /* Normalize to raise <class>, <instance> */
Armin Rigo967aa8b2006-02-14 15:50:44 +0000247 Py_XDECREF(val);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000248 val = typ;
Brett Cannonbf364092006-03-01 04:25:17 +0000249 typ = PyExceptionInstance_Class(typ);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000250 Py_INCREF(typ);
251 }
252 }
Phillip J. Ebybee07122006-03-25 00:05:50 +0000253
254 /* Allow raising builtin string exceptions */
255
256 else if (!PyString_CheckExact(typ)) {
Armin Rigo967aa8b2006-02-14 15:50:44 +0000257 /* Not something you can raise. throw() fails. */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000258 PyErr_Format(PyExc_TypeError,
259 "exceptions must be classes, or instances, not %s",
260 typ->ob_type->tp_name);
261 goto failed_throw;
262 }
263
Neal Norwitz017749c2006-04-12 06:56:56 +0000264 PyErr_Restore(typ, val, tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000265 return gen_send_ex(gen, Py_None, 1);
266
267failed_throw:
268 /* Didn't use our arguments, so restore their original refcounts */
269 Py_DECREF(typ);
270 Py_XDECREF(val);
271 Py_XDECREF(tb);
272 return NULL;
273}
274
275
276static PyObject *
277gen_iternext(PyGenObject *gen)
278{
279 return gen_send_ex(gen, NULL, 0);
280}
281
282
Martin v. Löwise440e472004-06-01 15:22:42 +0000283static PyMemberDef gen_memberlist[] = {
284 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
285 {"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
286 {NULL} /* Sentinel */
287};
288
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000289static PyMethodDef gen_methods[] = {
290 {"send",(PyCFunction)gen_send, METH_O, send_doc},
291 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
292 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
293 {NULL, NULL} /* Sentinel */
294};
295
Martin v. Löwise440e472004-06-01 15:22:42 +0000296PyTypeObject PyGen_Type = {
297 PyObject_HEAD_INIT(&PyType_Type)
298 0, /* ob_size */
299 "generator", /* tp_name */
300 sizeof(PyGenObject), /* tp_basicsize */
301 0, /* tp_itemsize */
302 /* methods */
303 (destructor)gen_dealloc, /* tp_dealloc */
304 0, /* tp_print */
305 0, /* tp_getattr */
306 0, /* tp_setattr */
307 0, /* tp_compare */
308 0, /* tp_repr */
309 0, /* tp_as_number */
310 0, /* tp_as_sequence */
311 0, /* tp_as_mapping */
312 0, /* tp_hash */
313 0, /* tp_call */
314 0, /* tp_str */
315 PyObject_GenericGetAttr, /* tp_getattro */
316 0, /* tp_setattro */
317 0, /* tp_as_buffer */
318 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
319 0, /* tp_doc */
320 (traverseproc)gen_traverse, /* tp_traverse */
321 0, /* tp_clear */
322 0, /* tp_richcompare */
323 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Raymond Hettinger6c7a00f2004-06-12 05:17:55 +0000324 PyObject_SelfIter, /* tp_iter */
Martin v. Löwise440e472004-06-01 15:22:42 +0000325 (iternextfunc)gen_iternext, /* tp_iternext */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000326 gen_methods, /* tp_methods */
Martin v. Löwise440e472004-06-01 15:22:42 +0000327 gen_memberlist, /* tp_members */
328 0, /* tp_getset */
329 0, /* tp_base */
330 0, /* tp_dict */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000331
332 0, /* tp_descr_get */
333 0, /* tp_descr_set */
334 0, /* tp_dictoffset */
335 0, /* tp_init */
336 0, /* tp_alloc */
337 0, /* tp_new */
338 0, /* tp_free */
339 0, /* tp_is_gc */
340 0, /* tp_bases */
341 0, /* tp_mro */
342 0, /* tp_cache */
343 0, /* tp_subclasses */
344 0, /* tp_weaklist */
345 gen_del, /* tp_del */
Martin v. Löwise440e472004-06-01 15:22:42 +0000346};
347
348PyObject *
349PyGen_New(PyFrameObject *f)
350{
351 PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
352 if (gen == NULL) {
353 Py_DECREF(f);
354 return NULL;
355 }
356 gen->gi_frame = f;
357 gen->gi_running = 0;
358 gen->gi_weakreflist = NULL;
359 _PyObject_GC_TRACK(gen);
360 return (PyObject *)gen;
361}
Phillip J. Eby2ba96612006-04-10 17:51:05 +0000362
363int
364PyGen_NeedsFinalizing(PyGenObject *gen)
365{
366 int i;
367 PyFrameObject *f = gen->gi_frame;
368
Phillip J. Eby8920bf22006-04-12 19:07:15 +0000369 if (f == NULL || f->f_stacktop==NULL || f->f_iblock<=0)
Phillip J. Eby2ba96612006-04-10 17:51:05 +0000370 return 0; /* no frame or no blockstack == no finalization */
371
372 for (i=f->f_iblock; i>=0; i--) {
373 if (f->f_blockstack[i].b_type != SETUP_LOOP)
374 /* any block type besides a loop requires cleanup */
375 return 1;
376 }
377
378 /* No blocks except loops, it's safe to skip finalization */
379 return 0;
380}