blob: f25b8a5f0ec3337fbff34e3fbb6c3def8fced92d [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"
Martin v. Löwise440e472004-06-01 15:22:42 +00005#include "structmember.h"
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006#include "opcode.h"
Martin v. Löwise440e472004-06-01 15:22:42 +00007
Nick Coghlan1f7ce622012-01-13 21:43:40 +10008static PyObject *gen_close(PyGenObject *gen, PyObject *args);
9static void gen_undelegate(PyGenObject *gen);
10
Martin v. Löwise440e472004-06-01 15:22:42 +000011static int
12gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
13{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000014 Py_VISIT((PyObject *)gen->gi_frame);
15 Py_VISIT(gen->gi_code);
16 return 0;
Martin v. Löwise440e472004-06-01 15:22:42 +000017}
18
19static void
20gen_dealloc(PyGenObject *gen)
21{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject *self = (PyObject *) gen;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000024 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026 if (gen->gi_weakreflist != NULL)
27 PyObject_ClearWeakRefs(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 _PyObject_GC_TRACK(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 if (gen->gi_frame != NULL && gen->gi_frame->f_stacktop != NULL) {
32 /* Generator is paused, so we need to close */
33 Py_TYPE(gen)->tp_del(self);
34 if (self->ob_refcnt > 0)
35 return; /* resurrected. :( */
36 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 _PyObject_GC_UNTRACK(self);
39 Py_CLEAR(gen->gi_frame);
40 Py_CLEAR(gen->gi_code);
41 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000042}
43
Benjamin Peterson099a78f2012-03-07 17:57:04 -060044static int
45gen_running(PyGenObject *gen)
46{
47 if (gen->gi_running) {
48 PyErr_SetString(PyExc_ValueError, "generator already executing");
49 return 1;
50 }
51 return 0;
52}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000053
Martin v. Löwise440e472004-06-01 15:22:42 +000054static PyObject *
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000055gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
Martin v. Löwise440e472004-06-01 15:22:42 +000056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057 PyThreadState *tstate = PyThreadState_GET();
58 PyFrameObject *f = gen->gi_frame;
59 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000060
Benjamin Peterson099a78f2012-03-07 17:57:04 -060061 assert(!gen->gi_running);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 if (f==NULL || f->f_stacktop == NULL) {
63 /* Only set exception if called from send() */
64 if (arg && !exc)
65 PyErr_SetNone(PyExc_StopIteration);
66 return NULL;
67 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 if (f->f_lasti == -1) {
70 if (arg && arg != Py_None) {
71 PyErr_SetString(PyExc_TypeError,
72 "can't send non-None value to a "
73 "just-started generator");
74 return NULL;
75 }
76 } else {
77 /* Push arg onto the frame's value stack */
78 result = arg ? arg : Py_None;
79 Py_INCREF(result);
80 *(f->f_stacktop++) = result;
81 }
Martin v. Löwise440e472004-06-01 15:22:42 +000082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 /* Generators always return to their most recent caller, not
84 * necessarily their creator. */
85 Py_XINCREF(tstate->frame);
86 assert(f->f_back == NULL);
87 f->f_back = tstate->frame;
Martin v. Löwise440e472004-06-01 15:22:42 +000088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 gen->gi_running = 1;
90 result = PyEval_EvalFrameEx(f, exc);
91 gen->gi_running = 0;
Martin v. Löwise440e472004-06-01 15:22:42 +000092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 /* Don't keep the reference to f_back any longer than necessary. It
94 * may keep a chain of frames alive or it could create a reference
95 * cycle. */
96 assert(f->f_back == tstate->frame);
97 Py_CLEAR(f->f_back);
Martin v. Löwise440e472004-06-01 15:22:42 +000098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 /* If the generator just returned (as opposed to yielding), signal
100 * that the generator is exhausted. */
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000101 if (result && f->f_stacktop == NULL) {
102 if (result == Py_None) {
103 /* Delay exception instantiation if we can */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 PyErr_SetNone(PyExc_StopIteration);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000105 } else {
106 PyObject *e = PyStopIteration_Create(result);
107 if (e != NULL) {
108 PyErr_SetObject(PyExc_StopIteration, e);
109 Py_DECREF(e);
110 }
111 }
112 Py_CLEAR(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 if (!result || f->f_stacktop == NULL) {
116 /* generator can't be rerun, so release the frame */
Antoine Pitroua370fcf2011-08-20 14:15:03 +0200117 /* first clean reference cycle through stored exception traceback */
118 PyObject *t, *v, *tb;
119 t = f->f_exc_type;
120 v = f->f_exc_value;
121 tb = f->f_exc_traceback;
122 f->f_exc_type = NULL;
123 f->f_exc_value = NULL;
124 f->f_exc_traceback = NULL;
125 Py_XDECREF(t);
126 Py_XDECREF(v);
127 Py_XDECREF(tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 gen->gi_frame = NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000129 Py_DECREF(f);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 }
Martin v. Löwise440e472004-06-01 15:22:42 +0000131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000133}
134
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000135PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000136"send(arg) -> send 'arg' into generator,\n\
137return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000138
139static PyObject *
140gen_send(PyGenObject *gen, PyObject *arg)
141{
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000142 int exc = 0;
143 PyObject *ret;
144 PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600145 if (gen_running(gen))
146 return NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000147 /* XXX (ncoghlan): Are the incref/decref on arg and yf strictly needed?
148 * Or would it be valid to rely on borrowed references?
149 */
150 Py_INCREF(arg);
151 if (yf) {
152 Py_INCREF(yf);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600153 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000154 if (PyGen_CheckExact(yf)) {
155 ret = gen_send((PyGenObject *)yf, arg);
156 } else {
157 if (arg == Py_None)
158 ret = PyIter_Next(yf);
159 else
160 ret = PyObject_CallMethod(yf, "send", "O", arg);
161 }
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600162 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000163 if (ret) {
164 Py_DECREF(yf);
165 goto done;
166 }
167 gen_undelegate(gen);
168 Py_CLEAR(arg);
169 if (PyGen_FetchStopIterationValue(&arg) < 0) {
170 exc = 1;
171 }
172 Py_DECREF(yf);
173 }
174 ret = gen_send_ex(gen, arg, exc);
175done:
176 Py_XDECREF(arg);
177 return ret;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000178}
179
180PyDoc_STRVAR(close_doc,
181"close(arg) -> raise GeneratorExit inside generator.");
182
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000183/*
184 * This helper function is used by gen_close and gen_throw to
185 * close a subiterator being delegated to by yield-from.
186 */
187
188static int
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600189gen_close_iter(PyGenObject *gen, PyObject *yf)
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000190{
191 PyObject *retval = NULL;
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600192 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000193
194 if (PyGen_CheckExact(yf)) {
195 retval = gen_close((PyGenObject *)yf, NULL);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600196 if (!retval)
197 err = -1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000198 } else {
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600199 PyObject *meth;
200 gen->gi_running = 1;
201 meth = PyObject_GetAttrString(yf, "close");
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000202 if (meth == NULL) {
203 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
204 PyErr_WriteUnraisable(yf);
205 }
206 PyErr_Clear();
207 } else {
208 retval = PyObject_CallFunction(meth, "");
209 Py_DECREF(meth);
210 if (!retval)
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600211 err = -1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000212 }
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600213 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000214 }
215 Py_XDECREF(retval);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600216 return err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000217}
218
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000219static PyObject *
220gen_close(PyGenObject *gen, PyObject *args)
221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 PyObject *retval;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000223 PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
224 int err = 0;
225
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600226 if (gen_running(gen))
227 return NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000228 if (yf) {
229 Py_INCREF(yf);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600230 err = gen_close_iter(gen, yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000231 gen_undelegate(gen);
232 Py_DECREF(yf);
233 }
234 if (err == 0)
235 PyErr_SetNone(PyExc_GeneratorExit);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 retval = gen_send_ex(gen, Py_None, 1);
237 if (retval) {
238 Py_DECREF(retval);
239 PyErr_SetString(PyExc_RuntimeError,
240 "generator ignored GeneratorExit");
241 return NULL;
242 }
243 if (PyErr_ExceptionMatches(PyExc_StopIteration)
244 || PyErr_ExceptionMatches(PyExc_GeneratorExit))
245 {
246 PyErr_Clear(); /* ignore these errors */
247 Py_INCREF(Py_None);
248 return Py_None;
249 }
250 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000251}
252
253static void
254gen_del(PyObject *self)
255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 PyObject *res;
257 PyObject *error_type, *error_value, *error_traceback;
258 PyGenObject *gen = (PyGenObject *)self;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
261 /* Generator isn't paused, so no need to close */
262 return;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 /* Temporarily resurrect the object. */
265 assert(self->ob_refcnt == 0);
266 self->ob_refcnt = 1;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 /* Save the current exception, if any. */
269 PyErr_Fetch(&error_type, &error_value, &error_traceback);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 res = gen_close(gen, NULL);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 if (res == NULL)
274 PyErr_WriteUnraisable(self);
275 else
276 Py_DECREF(res);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 /* Restore the saved exception. */
279 PyErr_Restore(error_type, error_value, error_traceback);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 /* Undo the temporary resurrection; can't use DECREF here, it would
282 * cause a recursive call.
283 */
284 assert(self->ob_refcnt > 0);
285 if (--self->ob_refcnt == 0)
286 return; /* this is the normal path out */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 /* close() resurrected it! Make it look like the original Py_DECREF
289 * never happened.
290 */
291 {
292 Py_ssize_t refcnt = self->ob_refcnt;
293 _Py_NewReference(self);
294 self->ob_refcnt = refcnt;
295 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000296 assert(PyType_IS_GC(Py_TYPE(self)) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
300 * we need to undo that. */
301 _Py_DEC_REFTOTAL;
302 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
303 * chain, so no more to do there.
304 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
305 * _Py_NewReference bumped tp_allocs: both of those need to be
306 * undone.
307 */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000308#ifdef COUNT_ALLOCS
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000309 --(Py_TYPE(self)->tp_frees);
310 --(Py_TYPE(self)->tp_allocs);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000311#endif
312}
313
314
315
316PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000317"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
318return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000319
320static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000321gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 PyObject *typ;
324 PyObject *tb = NULL;
325 PyObject *val = NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000326 PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
329 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000330
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600331 if (gen_running(gen))
332 return NULL;
333
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000334 if (yf) {
335 PyObject *ret;
336 int err;
337 Py_INCREF(yf);
338 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600339 err = gen_close_iter(gen, yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000340 Py_DECREF(yf);
341 gen_undelegate(gen);
342 if (err < 0)
343 return gen_send_ex(gen, Py_None, 1);
344 goto throw_here;
345 }
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600346 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000347 if (PyGen_CheckExact(yf)) {
348 ret = gen_throw((PyGenObject *)yf, args);
349 } else {
350 PyObject *meth = PyObject_GetAttrString(yf, "throw");
351 if (meth == NULL) {
352 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
353 Py_DECREF(yf);
354 return NULL;
355 }
356 PyErr_Clear();
357 Py_DECREF(yf);
358 gen_undelegate(gen);
Benjamin Peterson9fc30902012-03-07 18:11:31 -0600359 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000360 goto throw_here;
361 }
362 ret = PyObject_CallObject(meth, args);
363 Py_DECREF(meth);
364 }
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600365 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000366 Py_DECREF(yf);
367 if (!ret) {
368 PyObject *val;
369 gen_undelegate(gen);
370 if (PyGen_FetchStopIterationValue(&val) == 0) {
371 ret = gen_send_ex(gen, val, 0);
372 Py_DECREF(val);
373 } else {
374 ret = gen_send_ex(gen, Py_None, 1);
375 }
376 }
377 return ret;
378 }
379
380throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 /* First, check the traceback argument, replacing None with
382 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400383 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400385 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 else if (tb != NULL && !PyTraceBack_Check(tb)) {
387 PyErr_SetString(PyExc_TypeError,
388 "throw() third argument must be a traceback object");
389 return NULL;
390 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 Py_INCREF(typ);
393 Py_XINCREF(val);
394 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000395
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400396 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 else if (PyExceptionInstance_Check(typ)) {
400 /* Raising an instance. The value should be a dummy. */
401 if (val && val != Py_None) {
402 PyErr_SetString(PyExc_TypeError,
403 "instance exception may not have a separate value");
404 goto failed_throw;
405 }
406 else {
407 /* Normalize to raise <class>, <instance> */
408 Py_XDECREF(val);
409 val = typ;
410 typ = PyExceptionInstance_Class(typ);
411 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200412
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400413 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200414 /* Returns NULL if there's no traceback */
415 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 }
417 }
418 else {
419 /* Not something you can raise. throw() fails. */
420 PyErr_Format(PyExc_TypeError,
421 "exceptions must be classes or instances "
422 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000423 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 goto failed_throw;
425 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 PyErr_Restore(typ, val, tb);
428 return gen_send_ex(gen, Py_None, 1);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000429
430failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 /* Didn't use our arguments, so restore their original refcounts */
432 Py_DECREF(typ);
433 Py_XDECREF(val);
434 Py_XDECREF(tb);
435 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000436}
437
438
439static PyObject *
440gen_iternext(PyGenObject *gen)
441{
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000442 PyObject *val = NULL;
443 PyObject *ret;
444 int exc = 0;
445 PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600446 if (gen_running(gen))
447 return NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000448 if (yf) {
449 Py_INCREF(yf);
450 /* ceval.c ensures that yf is an iterator */
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600451 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000452 ret = Py_TYPE(yf)->tp_iternext(yf);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600453 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000454 if (ret) {
455 Py_DECREF(yf);
456 return ret;
457 }
458 gen_undelegate(gen);
459 if (PyGen_FetchStopIterationValue(&val) < 0)
460 exc = 1;
461 Py_DECREF(yf);
462 }
463 ret = gen_send_ex(gen, val, exc);
464 Py_XDECREF(val);
465 return ret;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000466}
467
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000468/*
469 * In certain recursive situations, a generator may lose its frame
470 * before we get a chance to clear f_yieldfrom, so we use this
471 * helper function.
472 */
473
474static void
475gen_undelegate(PyGenObject *gen) {
476 if (gen->gi_frame) {
477 Py_XDECREF(gen->gi_frame->f_yieldfrom);
478 gen->gi_frame->f_yieldfrom = NULL;
479 }
480}
481
482/*
483 * If StopIteration exception is set, fetches its 'value'
484 * attribute if any, otherwise sets pvalue to None.
485 *
486 * Returns 0 if no exception or StopIteration is set.
487 * If any other exception is set, returns -1 and leaves
488 * pvalue unchanged.
489 */
490
491int
492PyGen_FetchStopIterationValue(PyObject **pvalue) {
493 PyObject *et, *ev, *tb;
494 PyObject *value = NULL;
495
496 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
497 PyErr_Fetch(&et, &ev, &tb);
498 Py_XDECREF(et);
499 Py_XDECREF(tb);
500 if (ev) {
501 value = ((PyStopIterationObject *)ev)->value;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100502 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000503 Py_DECREF(ev);
504 }
505 } else if (PyErr_Occurred()) {
506 return -1;
507 }
508 if (value == NULL) {
509 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100510 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000511 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000512 *pvalue = value;
513 return 0;
514}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000515
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000516static PyObject *
517gen_repr(PyGenObject *gen)
518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return PyUnicode_FromFormat("<generator object %S at %p>",
520 ((PyCodeObject *)gen->gi_code)->co_name,
521 gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000522}
523
524
525static PyObject *
526gen_get_name(PyGenObject *gen)
527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
529 Py_INCREF(name);
530 return name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000531}
532
533
534PyDoc_STRVAR(gen__name__doc__,
535"Return the name of the generator's associated code object.");
536
537static PyGetSetDef gen_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 {"__name__", (getter)gen_get_name, NULL, gen__name__doc__},
539 {NULL}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000540};
541
542
Martin v. Löwise440e472004-06-01 15:22:42 +0000543static PyMemberDef gen_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
Benjamin Peterson657e9eb2012-03-07 18:17:03 -0600545 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
547 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000548};
549
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000550static PyMethodDef gen_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 {"send",(PyCFunction)gen_send, METH_O, send_doc},
552 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
553 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
554 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000555};
556
Martin v. Löwise440e472004-06-01 15:22:42 +0000557PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 PyVarObject_HEAD_INIT(&PyType_Type, 0)
559 "generator", /* tp_name */
560 sizeof(PyGenObject), /* tp_basicsize */
561 0, /* tp_itemsize */
562 /* methods */
563 (destructor)gen_dealloc, /* tp_dealloc */
564 0, /* tp_print */
565 0, /* tp_getattr */
566 0, /* tp_setattr */
567 0, /* tp_reserved */
568 (reprfunc)gen_repr, /* tp_repr */
569 0, /* tp_as_number */
570 0, /* tp_as_sequence */
571 0, /* tp_as_mapping */
572 0, /* tp_hash */
573 0, /* tp_call */
574 0, /* tp_str */
575 PyObject_GenericGetAttr, /* tp_getattro */
576 0, /* tp_setattro */
577 0, /* tp_as_buffer */
578 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
579 0, /* tp_doc */
580 (traverseproc)gen_traverse, /* tp_traverse */
581 0, /* tp_clear */
582 0, /* tp_richcompare */
583 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
584 PyObject_SelfIter, /* tp_iter */
585 (iternextfunc)gen_iternext, /* tp_iternext */
586 gen_methods, /* tp_methods */
587 gen_memberlist, /* tp_members */
588 gen_getsetlist, /* tp_getset */
589 0, /* tp_base */
590 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 0, /* tp_descr_get */
593 0, /* tp_descr_set */
594 0, /* tp_dictoffset */
595 0, /* tp_init */
596 0, /* tp_alloc */
597 0, /* tp_new */
598 0, /* tp_free */
599 0, /* tp_is_gc */
600 0, /* tp_bases */
601 0, /* tp_mro */
602 0, /* tp_cache */
603 0, /* tp_subclasses */
604 0, /* tp_weaklist */
605 gen_del, /* tp_del */
Martin v. Löwise440e472004-06-01 15:22:42 +0000606};
607
608PyObject *
609PyGen_New(PyFrameObject *f)
610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
612 if (gen == NULL) {
613 Py_DECREF(f);
614 return NULL;
615 }
616 gen->gi_frame = f;
617 Py_INCREF(f->f_code);
618 gen->gi_code = (PyObject *)(f->f_code);
619 gen->gi_running = 0;
620 gen->gi_weakreflist = NULL;
621 _PyObject_GC_TRACK(gen);
622 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000623}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000624
625int
626PyGen_NeedsFinalizing(PyGenObject *gen)
627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 int i;
629 PyFrameObject *f = gen->gi_frame;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000630
Benjamin Petersonf07c9a12011-07-03 17:23:22 -0500631 if (f == NULL || f->f_stacktop == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 return 0; /* no frame or empty blockstack == no finalization */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 /* Any block type besides a loop requires cleanup. */
Benjamin Petersonf07c9a12011-07-03 17:23:22 -0500635 for (i = 0; i < f->f_iblock; i++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 if (f->f_blockstack[i].b_type != SETUP_LOOP)
637 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 /* No blocks except loops, it's safe to skip finalization. */
640 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000641}