blob: e41779e8a2304cb338383ed64c5c896b593126a1 [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);
359 goto throw_here;
360 }
361 ret = PyObject_CallObject(meth, args);
362 Py_DECREF(meth);
363 }
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600364 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000365 Py_DECREF(yf);
366 if (!ret) {
367 PyObject *val;
368 gen_undelegate(gen);
369 if (PyGen_FetchStopIterationValue(&val) == 0) {
370 ret = gen_send_ex(gen, val, 0);
371 Py_DECREF(val);
372 } else {
373 ret = gen_send_ex(gen, Py_None, 1);
374 }
375 }
376 return ret;
377 }
378
379throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 /* First, check the traceback argument, replacing None with
381 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400382 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400384 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 else if (tb != NULL && !PyTraceBack_Check(tb)) {
386 PyErr_SetString(PyExc_TypeError,
387 "throw() third argument must be a traceback object");
388 return NULL;
389 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 Py_INCREF(typ);
392 Py_XINCREF(val);
393 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000394
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400395 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 else if (PyExceptionInstance_Check(typ)) {
399 /* Raising an instance. The value should be a dummy. */
400 if (val && val != Py_None) {
401 PyErr_SetString(PyExc_TypeError,
402 "instance exception may not have a separate value");
403 goto failed_throw;
404 }
405 else {
406 /* Normalize to raise <class>, <instance> */
407 Py_XDECREF(val);
408 val = typ;
409 typ = PyExceptionInstance_Class(typ);
410 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200411
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400412 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200413 /* Returns NULL if there's no traceback */
414 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 }
416 }
417 else {
418 /* Not something you can raise. throw() fails. */
419 PyErr_Format(PyExc_TypeError,
420 "exceptions must be classes or instances "
421 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000422 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 goto failed_throw;
424 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 PyErr_Restore(typ, val, tb);
427 return gen_send_ex(gen, Py_None, 1);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000428
429failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 /* Didn't use our arguments, so restore their original refcounts */
431 Py_DECREF(typ);
432 Py_XDECREF(val);
433 Py_XDECREF(tb);
434 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000435}
436
437
438static PyObject *
439gen_iternext(PyGenObject *gen)
440{
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000441 PyObject *val = NULL;
442 PyObject *ret;
443 int exc = 0;
444 PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600445 if (gen_running(gen))
446 return NULL;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000447 if (yf) {
448 Py_INCREF(yf);
449 /* ceval.c ensures that yf is an iterator */
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600450 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000451 ret = Py_TYPE(yf)->tp_iternext(yf);
Benjamin Peterson099a78f2012-03-07 17:57:04 -0600452 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000453 if (ret) {
454 Py_DECREF(yf);
455 return ret;
456 }
457 gen_undelegate(gen);
458 if (PyGen_FetchStopIterationValue(&val) < 0)
459 exc = 1;
460 Py_DECREF(yf);
461 }
462 ret = gen_send_ex(gen, val, exc);
463 Py_XDECREF(val);
464 return ret;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000465}
466
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000467/*
468 * In certain recursive situations, a generator may lose its frame
469 * before we get a chance to clear f_yieldfrom, so we use this
470 * helper function.
471 */
472
473static void
474gen_undelegate(PyGenObject *gen) {
475 if (gen->gi_frame) {
476 Py_XDECREF(gen->gi_frame->f_yieldfrom);
477 gen->gi_frame->f_yieldfrom = NULL;
478 }
479}
480
481/*
482 * If StopIteration exception is set, fetches its 'value'
483 * attribute if any, otherwise sets pvalue to None.
484 *
485 * Returns 0 if no exception or StopIteration is set.
486 * If any other exception is set, returns -1 and leaves
487 * pvalue unchanged.
488 */
489
490int
491PyGen_FetchStopIterationValue(PyObject **pvalue) {
492 PyObject *et, *ev, *tb;
493 PyObject *value = NULL;
494
495 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
496 PyErr_Fetch(&et, &ev, &tb);
497 Py_XDECREF(et);
498 Py_XDECREF(tb);
499 if (ev) {
500 value = ((PyStopIterationObject *)ev)->value;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100501 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000502 Py_DECREF(ev);
503 }
504 } else if (PyErr_Occurred()) {
505 return -1;
506 }
507 if (value == NULL) {
508 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100509 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000510 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000511 *pvalue = value;
512 return 0;
513}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000514
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000515static PyObject *
516gen_repr(PyGenObject *gen)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 return PyUnicode_FromFormat("<generator object %S at %p>",
519 ((PyCodeObject *)gen->gi_code)->co_name,
520 gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000521}
522
523
524static PyObject *
525gen_get_name(PyGenObject *gen)
526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
528 Py_INCREF(name);
529 return name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000530}
531
532
533PyDoc_STRVAR(gen__name__doc__,
534"Return the name of the generator's associated code object.");
535
536static PyGetSetDef gen_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 {"__name__", (getter)gen_get_name, NULL, gen__name__doc__},
538 {NULL}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000539};
540
541
Martin v. Löwise440e472004-06-01 15:22:42 +0000542static PyMemberDef gen_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
544 {"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY},
545 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
546 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000547};
548
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000549static PyMethodDef gen_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 {"send",(PyCFunction)gen_send, METH_O, send_doc},
551 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
552 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
553 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000554};
555
Martin v. Löwise440e472004-06-01 15:22:42 +0000556PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 PyVarObject_HEAD_INIT(&PyType_Type, 0)
558 "generator", /* tp_name */
559 sizeof(PyGenObject), /* tp_basicsize */
560 0, /* tp_itemsize */
561 /* methods */
562 (destructor)gen_dealloc, /* tp_dealloc */
563 0, /* tp_print */
564 0, /* tp_getattr */
565 0, /* tp_setattr */
566 0, /* tp_reserved */
567 (reprfunc)gen_repr, /* tp_repr */
568 0, /* tp_as_number */
569 0, /* tp_as_sequence */
570 0, /* tp_as_mapping */
571 0, /* tp_hash */
572 0, /* tp_call */
573 0, /* tp_str */
574 PyObject_GenericGetAttr, /* tp_getattro */
575 0, /* tp_setattro */
576 0, /* tp_as_buffer */
577 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
578 0, /* tp_doc */
579 (traverseproc)gen_traverse, /* tp_traverse */
580 0, /* tp_clear */
581 0, /* tp_richcompare */
582 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
583 PyObject_SelfIter, /* tp_iter */
584 (iternextfunc)gen_iternext, /* tp_iternext */
585 gen_methods, /* tp_methods */
586 gen_memberlist, /* tp_members */
587 gen_getsetlist, /* tp_getset */
588 0, /* tp_base */
589 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 0, /* tp_descr_get */
592 0, /* tp_descr_set */
593 0, /* tp_dictoffset */
594 0, /* tp_init */
595 0, /* tp_alloc */
596 0, /* tp_new */
597 0, /* tp_free */
598 0, /* tp_is_gc */
599 0, /* tp_bases */
600 0, /* tp_mro */
601 0, /* tp_cache */
602 0, /* tp_subclasses */
603 0, /* tp_weaklist */
604 gen_del, /* tp_del */
Martin v. Löwise440e472004-06-01 15:22:42 +0000605};
606
607PyObject *
608PyGen_New(PyFrameObject *f)
609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
611 if (gen == NULL) {
612 Py_DECREF(f);
613 return NULL;
614 }
615 gen->gi_frame = f;
616 Py_INCREF(f->f_code);
617 gen->gi_code = (PyObject *)(f->f_code);
618 gen->gi_running = 0;
619 gen->gi_weakreflist = NULL;
620 _PyObject_GC_TRACK(gen);
621 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000622}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000623
624int
625PyGen_NeedsFinalizing(PyGenObject *gen)
626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 int i;
628 PyFrameObject *f = gen->gi_frame;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000629
Benjamin Petersonf07c9a12011-07-03 17:23:22 -0500630 if (f == NULL || f->f_stacktop == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 return 0; /* no frame or empty blockstack == no finalization */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 /* Any block type besides a loop requires cleanup. */
Benjamin Petersonf07c9a12011-07-03 17:23:22 -0500634 for (i = 0; i < f->f_iblock; i++)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 if (f->f_blockstack[i].b_type != SETUP_LOOP)
636 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 /* No blocks except loops, it's safe to skip finalization. */
639 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000640}