blob: a3eae6a6b989676528f8867e016f976ddd277981 [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{
13 return visit((PyObject *)gen->gi_frame, arg);
14}
15
16static void
17gen_dealloc(PyGenObject *gen)
18{
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000019 PyObject *self = (PyObject *) gen;
20
Martin v. Löwise440e472004-06-01 15:22:42 +000021 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000022
Martin v. Löwise440e472004-06-01 15:22:42 +000023 if (gen->gi_weakreflist != NULL)
24 PyObject_ClearWeakRefs((PyObject *) gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000025
26
27 _PyObject_GC_TRACK(self);
28
29 if (gen->gi_frame->f_stacktop!=NULL) {
30 /* Generator is paused, so we need to close */
31 gen->ob_type->tp_del(self);
32 if (self->ob_refcnt > 0)
33 return; /* resurrected. :( */
34 }
35
36 _PyObject_GC_UNTRACK(self);
37 Py_XDECREF(gen->gi_frame);
Martin v. Löwise440e472004-06-01 15:22:42 +000038 PyObject_GC_Del(gen);
39}
40
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000041
Martin v. Löwise440e472004-06-01 15:22:42 +000042static PyObject *
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000043gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
Martin v. Löwise440e472004-06-01 15:22:42 +000044{
45 PyThreadState *tstate = PyThreadState_GET();
46 PyFrameObject *f = gen->gi_frame;
47 PyObject *result;
48
49 if (gen->gi_running) {
50 PyErr_SetString(PyExc_ValueError,
51 "generator already executing");
52 return NULL;
53 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000054 if ((PyObject *)f == Py_None || f->f_stacktop == NULL) {
55 /* Only set exception if called from send() */
56 if (arg && !exc) PyErr_SetNone(PyExc_StopIteration);
Martin v. Löwise440e472004-06-01 15:22:42 +000057 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000058 }
59
60 if (f->f_lasti == -1) {
61 if (arg && arg != Py_None) {
62 PyErr_SetString(PyExc_TypeError,
63 "can't send non-None value to a just-started generator");
64 return NULL;
65 }
66 } else {
67 /* Push arg onto the frame's value stack */
68 result = arg ? arg : Py_None;
69 Py_INCREF(result);
70 *(f->f_stacktop++) = result;
71 }
Martin v. Löwise440e472004-06-01 15:22:42 +000072
73 /* Generators always return to their most recent caller, not
74 * necessarily their creator. */
75 Py_XINCREF(tstate->frame);
76 assert(f->f_back == NULL);
77 f->f_back = tstate->frame;
78
79 gen->gi_running = 1;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000080 result = PyEval_EvalFrameEx(f, exc);
Martin v. Löwise440e472004-06-01 15:22:42 +000081 gen->gi_running = 0;
82
83 /* Don't keep the reference to f_back any longer than necessary. It
84 * may keep a chain of frames alive or it could create a reference
85 * cycle. */
Phillip J. Eby00148222005-08-13 03:29:00 +000086 assert(f->f_back == tstate->frame);
Raymond Hettinger75ccea32004-09-01 07:02:44 +000087 Py_CLEAR(f->f_back);
Martin v. Löwise440e472004-06-01 15:22:42 +000088
89 /* If the generator just returned (as opposed to yielding), signal
90 * that the generator is exhausted. */
91 if (result == Py_None && f->f_stacktop == NULL) {
92 Py_DECREF(result);
93 result = NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000094 /* Set exception if not called by gen_iternext() */
95 if (arg) PyErr_SetNone(PyExc_StopIteration);
96 }
97
98 if (!result || f->f_stacktop == NULL) {
99 /* generator can't be rerun, so release the frame */
100 Py_DECREF(f);
101 gen->gi_frame = (PyFrameObject *)Py_None;
102 Py_INCREF(Py_None);
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,
109"send(arg) -> send 'arg' into generator, return next yielded value or raise StopIteration.");
110
111static PyObject *
112gen_send(PyGenObject *gen, PyObject *arg)
113{
114 return gen_send_ex(gen, arg, 0);
115}
116
117PyDoc_STRVAR(close_doc,
118"close(arg) -> raise GeneratorExit inside generator.");
119
120static PyObject *
121gen_close(PyGenObject *gen, PyObject *args)
122{
123 PyObject *retval;
124 PyErr_SetNone(PyExc_GeneratorExit);
125 retval = gen_send_ex(gen, Py_None, 1);
126 if (retval) {
127 Py_DECREF(retval);
128 PyErr_SetString(PyExc_RuntimeError,
129 "generator ignored GeneratorExit");
130 return NULL;
131 }
132 if ( PyErr_ExceptionMatches(PyExc_StopIteration)
133 || PyErr_ExceptionMatches(PyExc_GeneratorExit) )
134 {
135 PyErr_Clear(); /* ignore these errors */
136 Py_INCREF(Py_None);
137 return Py_None;
138 }
139 return NULL;
140}
141
142static void
143gen_del(PyObject *self)
144{
145 PyObject *res;
146 PyObject *error_type, *error_value, *error_traceback;
147 PyGenObject *gen = (PyGenObject *)self;
148
149 if ((PyObject *)gen->gi_frame == Py_None || gen->gi_frame->f_stacktop==NULL)
150 /* Generator isn't paused, so no need to close */
151 return;
152
153 /* Temporarily resurrect the object. */
154 assert(self->ob_refcnt == 0);
155 self->ob_refcnt = 1;
156
157 /* Save the current exception, if any. */
158 PyErr_Fetch(&error_type, &error_value, &error_traceback);
159
160 res = gen_close((PyGenObject *)self, NULL);
161
162 if (res == NULL)
163 PyErr_WriteUnraisable((PyObject *)self);
164 else
165 Py_DECREF(res);
166
167 /* Restore the saved exception. */
168 PyErr_Restore(error_type, error_value, error_traceback);
169
170 /* Undo the temporary resurrection; can't use DECREF here, it would
171 * cause a recursive call.
172 */
173 assert(self->ob_refcnt > 0);
174 if (--self->ob_refcnt == 0)
175 return; /* this is the normal path out */
176
177 /* close() resurrected it! Make it look like the original Py_DECREF
178 * never happened.
179 */
180 {
Martin v. Löwis725507b2006-03-07 12:08:51 +0000181 Py_ssize_t refcnt = self->ob_refcnt;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000182 _Py_NewReference(self);
183 self->ob_refcnt = refcnt;
184 }
185 assert(!PyType_IS_GC(self->ob_type) ||
186 _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
187
188 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
189 * we need to undo that. */
190 _Py_DEC_REFTOTAL;
191 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
192 * chain, so no more to do there.
193 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
194 * _Py_NewReference bumped tp_allocs: both of those need to be
195 * undone.
196 */
197#ifdef COUNT_ALLOCS
198 --self->ob_type->tp_frees;
199 --self->ob_type->tp_allocs;
200#endif
201}
202
203
204
205PyDoc_STRVAR(throw_doc,
206"throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration.");
207
208static PyObject *
209gen_throw(PyGenObject *gen, PyObject *args)
210{
211 PyObject *typ;
212 PyObject *tb = NULL;
213 PyObject *val = NULL;
214
215 if (!PyArg_ParseTuple(args, "O|OO:throw", &typ, &val, &tb))
216 return NULL;
217
Armin Rigo967aa8b2006-02-14 15:50:44 +0000218 /* First, check the traceback argument, replacing None with
219 NULL. */
220 if (tb == Py_None) {
221 Py_DECREF(tb);
222 tb = NULL;
223 }
224 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
264 PyErr_Restore(typ,val,tb);
265 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
369 if ((PyObject *)f == Py_None || f->f_stacktop==NULL || f->f_iblock<=0)
370 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}