blob: 5d3b66c6ec4cca472581ce6379f59d0cfd035bfc [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);
Nick Coghlan1f7ce622012-01-13 21:43:40 +10009
Martin v. Löwise440e472004-06-01 15:22:42 +000010static int
11gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
12{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 Py_VISIT((PyObject *)gen->gi_frame);
14 Py_VISIT(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020015 Py_VISIT(gen->gi_name);
16 Py_VISIT(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 return 0;
Martin v. Löwise440e472004-06-01 15:22:42 +000018}
19
Antoine Pitrou58720d62013-08-05 23:26:40 +020020void
21_PyGen_Finalize(PyObject *self)
Antoine Pitrou796564c2013-07-30 19:59:21 +020022{
23 PyGenObject *gen = (PyGenObject *)self;
24 PyObject *res;
25 PyObject *error_type, *error_value, *error_traceback;
26
Yury Selivanov75445082015-05-11 22:57:16 -040027 /* If `gen` is a coroutine, and if it was never awaited on,
28 issue a RuntimeWarning. */
29 if (gen->gi_code != NULL
30 && ((PyCodeObject *)gen->gi_code)->co_flags & (CO_COROUTINE
31 | CO_ITERABLE_COROUTINE)
32 && gen->gi_frame != NULL
33 && gen->gi_frame->f_lasti == -1
34 && !PyErr_Occurred()
35 && PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
36 "coroutine '%.50S' was never awaited",
37 gen->gi_qualname))
38 return;
39
Antoine Pitrou796564c2013-07-30 19:59:21 +020040 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
41 /* Generator isn't paused, so no need to close */
42 return;
43
44 /* Save the current exception, if any. */
45 PyErr_Fetch(&error_type, &error_value, &error_traceback);
46
47 res = gen_close(gen, NULL);
48
49 if (res == NULL)
50 PyErr_WriteUnraisable(self);
51 else
52 Py_DECREF(res);
53
54 /* Restore the saved exception. */
55 PyErr_Restore(error_type, error_value, error_traceback);
56}
57
58static void
Martin v. Löwise440e472004-06-01 15:22:42 +000059gen_dealloc(PyGenObject *gen)
60{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyObject *self = (PyObject *) gen;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 if (gen->gi_weakreflist != NULL)
66 PyObject_ClearWeakRefs(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000067
Antoine Pitrou93963562013-05-14 20:37:52 +020068 _PyObject_GC_TRACK(self);
69
Antoine Pitrou796564c2013-07-30 19:59:21 +020070 if (PyObject_CallFinalizerFromDealloc(self))
71 return; /* resurrected. :( */
Antoine Pitrou93963562013-05-14 20:37:52 +020072
73 _PyObject_GC_UNTRACK(self);
74 Py_CLEAR(gen->gi_frame);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 Py_CLEAR(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020076 Py_CLEAR(gen->gi_name);
77 Py_CLEAR(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000079}
80
81static PyObject *
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000082gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
Martin v. Löwise440e472004-06-01 15:22:42 +000083{
Antoine Pitrou93963562013-05-14 20:37:52 +020084 PyThreadState *tstate = PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +020086 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000087
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050088 if (gen->gi_running) {
89 PyErr_SetString(PyExc_ValueError,
90 "generator already executing");
91 return NULL;
92 }
Antoine Pitrou93963562013-05-14 20:37:52 +020093 if (f == NULL || f->f_stacktop == NULL) {
94 /* Only set exception if called from send() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (arg && !exc)
96 PyErr_SetNone(PyExc_StopIteration);
97 return NULL;
98 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000099
Antoine Pitrou93963562013-05-14 20:37:52 +0200100 if (f->f_lasti == -1) {
101 if (arg && arg != Py_None) {
102 PyErr_SetString(PyExc_TypeError,
103 "can't send non-None value to a "
104 "just-started generator");
105 return NULL;
106 }
107 } else {
108 /* Push arg onto the frame's value stack */
109 result = arg ? arg : Py_None;
110 Py_INCREF(result);
111 *(f->f_stacktop++) = result;
112 }
113
114 /* Generators always return to their most recent caller, not
115 * necessarily their creator. */
116 Py_XINCREF(tstate->frame);
117 assert(f->f_back == NULL);
118 f->f_back = tstate->frame;
119
120 gen->gi_running = 1;
121 result = PyEval_EvalFrameEx(f, exc);
122 gen->gi_running = 0;
123
124 /* Don't keep the reference to f_back any longer than necessary. It
125 * may keep a chain of frames alive or it could create a reference
126 * cycle. */
127 assert(f->f_back == tstate->frame);
128 Py_CLEAR(f->f_back);
129
130 /* If the generator just returned (as opposed to yielding), signal
131 * that the generator is exhausted. */
132 if (result && f->f_stacktop == NULL) {
133 if (result == Py_None) {
134 /* Delay exception instantiation if we can */
135 PyErr_SetNone(PyExc_StopIteration);
136 } else {
137 PyObject *e = PyObject_CallFunctionObjArgs(
138 PyExc_StopIteration, result, NULL);
139 if (e != NULL) {
140 PyErr_SetObject(PyExc_StopIteration, e);
141 Py_DECREF(e);
142 }
143 }
144 Py_CLEAR(result);
145 }
Yury Selivanov68333392015-05-22 11:16:47 -0400146 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400147 /* Check for __future__ generator_stop and conditionally turn
148 * a leaking StopIteration into RuntimeError (with its cause
149 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400150 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400151 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400152 {
153 PyObject *exc, *val, *val2, *tb;
154 PyErr_Fetch(&exc, &val, &tb);
155 PyErr_NormalizeException(&exc, &val, &tb);
156 if (tb != NULL)
157 PyException_SetTraceback(val, tb);
158 Py_DECREF(exc);
159 Py_XDECREF(tb);
160 PyErr_SetString(PyExc_RuntimeError,
161 "generator raised StopIteration");
162 PyErr_Fetch(&exc, &val2, &tb);
163 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400164 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400165 PyException_SetCause(val2, val);
166 PyException_SetContext(val2, val);
167 PyErr_Restore(exc, val2, tb);
168 }
Yury Selivanov68333392015-05-22 11:16:47 -0400169 else {
170 PyObject *exc, *val, *tb;
171
172 /* Pop the exception before issuing a warning. */
173 PyErr_Fetch(&exc, &val, &tb);
174
175 if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
176 "generator '%.50S' raised StopIteration",
177 gen->gi_qualname)) {
178 /* Warning was converted to an error. */
179 Py_XDECREF(exc);
180 Py_XDECREF(val);
181 Py_XDECREF(tb);
182 }
183 else {
184 PyErr_Restore(exc, val, tb);
185 }
186 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400187 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200188
189 if (!result || f->f_stacktop == NULL) {
190 /* generator can't be rerun, so release the frame */
191 /* first clean reference cycle through stored exception traceback */
192 PyObject *t, *v, *tb;
193 t = f->f_exc_type;
194 v = f->f_exc_value;
195 tb = f->f_exc_traceback;
196 f->f_exc_type = NULL;
197 f->f_exc_value = NULL;
198 f->f_exc_traceback = NULL;
199 Py_XDECREF(t);
200 Py_XDECREF(v);
201 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200202 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200203 gen->gi_frame = NULL;
204 Py_DECREF(f);
205 }
206
207 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000208}
209
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000210PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211"send(arg) -> send 'arg' into generator,\n\
212return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000213
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500214PyObject *
215_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000216{
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500217 return gen_send_ex(gen, arg, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000218}
219
220PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400221"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000222
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000223/*
224 * This helper function is used by gen_close and gen_throw to
225 * close a subiterator being delegated to by yield-from.
226 */
227
Antoine Pitrou93963562013-05-14 20:37:52 +0200228static int
229gen_close_iter(PyObject *yf)
230{
231 PyObject *retval = NULL;
232 _Py_IDENTIFIER(close);
233
234 if (PyGen_CheckExact(yf)) {
235 retval = gen_close((PyGenObject *)yf, NULL);
236 if (retval == NULL)
237 return -1;
238 } else {
239 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
240 if (meth == NULL) {
241 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
242 PyErr_WriteUnraisable(yf);
243 PyErr_Clear();
244 } else {
245 retval = PyObject_CallFunction(meth, "");
246 Py_DECREF(meth);
247 if (retval == NULL)
248 return -1;
249 }
250 }
251 Py_XDECREF(retval);
252 return 0;
253}
254
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500255static PyObject *
256gen_yf(PyGenObject *gen)
257{
Antoine Pitrou93963562013-05-14 20:37:52 +0200258 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500259 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200260
261 if (f && f->f_stacktop) {
262 PyObject *bytecode = f->f_code->co_code;
263 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
264
265 if (code[f->f_lasti + 1] != YIELD_FROM)
266 return NULL;
267 yf = f->f_stacktop[-1];
268 Py_INCREF(yf);
269 }
270
271 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500272}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000273
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000274static PyObject *
275gen_close(PyGenObject *gen, PyObject *args)
276{
Antoine Pitrou93963562013-05-14 20:37:52 +0200277 PyObject *retval;
278 PyObject *yf = gen_yf(gen);
279 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000280
Antoine Pitrou93963562013-05-14 20:37:52 +0200281 if (yf) {
282 gen->gi_running = 1;
283 err = gen_close_iter(yf);
284 gen->gi_running = 0;
285 Py_DECREF(yf);
286 }
287 if (err == 0)
288 PyErr_SetNone(PyExc_GeneratorExit);
289 retval = gen_send_ex(gen, Py_None, 1);
290 if (retval) {
291 Py_DECREF(retval);
292 PyErr_SetString(PyExc_RuntimeError,
293 "generator ignored GeneratorExit");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 return NULL;
295 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200296 if (PyErr_ExceptionMatches(PyExc_StopIteration)
297 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
298 PyErr_Clear(); /* ignore these errors */
299 Py_INCREF(Py_None);
300 return Py_None;
301 }
302 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000303}
304
Antoine Pitrou93963562013-05-14 20:37:52 +0200305
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000306PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000307"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
308return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000309
310static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000311gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyObject *typ;
314 PyObject *tb = NULL;
315 PyObject *val = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500316 PyObject *yf = gen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000317 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
320 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000321
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000322 if (yf) {
323 PyObject *ret;
324 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000325 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500326 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200327 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500328 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000329 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000330 if (err < 0)
331 return gen_send_ex(gen, Py_None, 1);
332 goto throw_here;
333 }
334 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500335 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000336 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500337 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000338 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000339 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000340 if (meth == NULL) {
341 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
342 Py_DECREF(yf);
343 return NULL;
344 }
345 PyErr_Clear();
346 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000347 goto throw_here;
348 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500349 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000350 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500351 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000352 Py_DECREF(meth);
353 }
354 Py_DECREF(yf);
355 if (!ret) {
356 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500357 /* Pop subiterator from stack */
358 ret = *(--gen->gi_frame->f_stacktop);
359 assert(ret == yf);
360 Py_DECREF(ret);
361 /* Termination repetition of YIELD_FROM */
362 gen->gi_frame->f_lasti++;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000363 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000364 ret = gen_send_ex(gen, val, 0);
365 Py_DECREF(val);
366 } else {
367 ret = gen_send_ex(gen, Py_None, 1);
368 }
369 }
370 return ret;
371 }
372
373throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 /* First, check the traceback argument, replacing None with
375 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400376 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400378 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 else if (tb != NULL && !PyTraceBack_Check(tb)) {
380 PyErr_SetString(PyExc_TypeError,
381 "throw() third argument must be a traceback object");
382 return NULL;
383 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 Py_INCREF(typ);
386 Py_XINCREF(val);
387 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000388
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400389 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 else if (PyExceptionInstance_Check(typ)) {
393 /* Raising an instance. The value should be a dummy. */
394 if (val && val != Py_None) {
395 PyErr_SetString(PyExc_TypeError,
396 "instance exception may not have a separate value");
397 goto failed_throw;
398 }
399 else {
400 /* Normalize to raise <class>, <instance> */
401 Py_XDECREF(val);
402 val = typ;
403 typ = PyExceptionInstance_Class(typ);
404 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200405
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400406 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200407 /* Returns NULL if there's no traceback */
408 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 }
410 }
411 else {
412 /* Not something you can raise. throw() fails. */
413 PyErr_Format(PyExc_TypeError,
414 "exceptions must be classes or instances "
415 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000416 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 goto failed_throw;
418 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 PyErr_Restore(typ, val, tb);
421 return gen_send_ex(gen, Py_None, 1);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000422
423failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 /* Didn't use our arguments, so restore their original refcounts */
425 Py_DECREF(typ);
426 Py_XDECREF(val);
427 Py_XDECREF(tb);
428 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000429}
430
431
432static PyObject *
433gen_iternext(PyGenObject *gen)
434{
Yury Selivanov75445082015-05-11 22:57:16 -0400435 if (((PyCodeObject*)gen->gi_code)->co_flags & CO_COROUTINE) {
436 PyErr_SetString(PyExc_TypeError,
437 "coroutine-objects do not support iteration");
438 return NULL;
439 }
440
Antoine Pitrou667f5452014-07-08 18:43:23 -0400441 return gen_send_ex(gen, NULL, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000442}
443
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000444/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000445 * If StopIteration exception is set, fetches its 'value'
446 * attribute if any, otherwise sets pvalue to None.
447 *
448 * Returns 0 if no exception or StopIteration is set.
449 * If any other exception is set, returns -1 and leaves
450 * pvalue unchanged.
451 */
452
453int
Nick Coghlanc40bc092012-06-17 15:15:49 +1000454_PyGen_FetchStopIterationValue(PyObject **pvalue) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000455 PyObject *et, *ev, *tb;
456 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500457
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000458 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
459 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200460 if (ev) {
461 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300462 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200463 value = ((PyStopIterationObject *)ev)->value;
464 Py_INCREF(value);
465 Py_DECREF(ev);
466 } else if (et == PyExc_StopIteration) {
467 /* avoid normalisation and take ev as value */
468 value = ev;
469 } else {
470 /* normalisation required */
471 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300472 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200473 PyErr_Restore(et, ev, tb);
474 return -1;
475 }
476 value = ((PyStopIterationObject *)ev)->value;
477 Py_INCREF(value);
478 Py_DECREF(ev);
479 }
480 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000481 Py_XDECREF(et);
482 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000483 } else if (PyErr_Occurred()) {
484 return -1;
485 }
486 if (value == NULL) {
487 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100488 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000489 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000490 *pvalue = value;
491 return 0;
492}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000493
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000494static PyObject *
495gen_repr(PyGenObject *gen)
496{
Yury Selivanov75445082015-05-11 22:57:16 -0400497 if (PyGen_CheckCoroutineExact(gen)) {
498 return PyUnicode_FromFormat("<coroutine object %S at %p>",
499 gen->gi_qualname, gen);
500 }
501 else {
502 return PyUnicode_FromFormat("<generator object %S at %p>",
503 gen->gi_qualname, gen);
504 }
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000505}
506
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000507static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200508gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000509{
Victor Stinner40ee3012014-06-16 15:59:28 +0200510 Py_INCREF(op->gi_name);
511 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000512}
513
Victor Stinner40ee3012014-06-16 15:59:28 +0200514static int
515gen_set_name(PyGenObject *op, PyObject *value)
516{
517 PyObject *tmp;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000518
Victor Stinner40ee3012014-06-16 15:59:28 +0200519 /* Not legal to del gen.gi_name or to set it to anything
520 * other than a string object. */
521 if (value == NULL || !PyUnicode_Check(value)) {
522 PyErr_SetString(PyExc_TypeError,
523 "__name__ must be set to a string object");
524 return -1;
525 }
526 tmp = op->gi_name;
527 Py_INCREF(value);
528 op->gi_name = value;
529 Py_DECREF(tmp);
530 return 0;
531}
532
533static PyObject *
534gen_get_qualname(PyGenObject *op)
535{
536 Py_INCREF(op->gi_qualname);
537 return op->gi_qualname;
538}
539
Yury Selivanov75445082015-05-11 22:57:16 -0400540static PyObject *
541gen_get_iter(PyGenObject *gen)
542{
543 if (((PyCodeObject*)gen->gi_code)->co_flags & CO_COROUTINE) {
544 PyErr_SetString(PyExc_TypeError,
545 "coroutine-objects do not support iteration");
546 return NULL;
547 }
548
549 Py_INCREF(gen);
Yury Selivanovdf52e672015-05-11 23:23:05 -0400550 return (PyObject *)gen;
Yury Selivanov75445082015-05-11 22:57:16 -0400551}
552
Victor Stinner40ee3012014-06-16 15:59:28 +0200553static int
554gen_set_qualname(PyGenObject *op, PyObject *value)
555{
556 PyObject *tmp;
557
558 /* Not legal to del gen.__qualname__ or to set it to anything
559 * other than a string object. */
560 if (value == NULL || !PyUnicode_Check(value)) {
561 PyErr_SetString(PyExc_TypeError,
562 "__qualname__ must be set to a string object");
563 return -1;
564 }
565 tmp = op->gi_qualname;
566 Py_INCREF(value);
567 op->gi_qualname = value;
568 Py_DECREF(tmp);
569 return 0;
570}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000571
572static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200573 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
574 PyDoc_STR("name of the generator")},
575 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
576 PyDoc_STR("qualified name of the generator")},
577 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000578};
579
Martin v. Löwise440e472004-06-01 15:22:42 +0000580static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200581 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
582 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
583 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000585};
586
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000587static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500588 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
590 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
591 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000592};
593
Martin v. Löwise440e472004-06-01 15:22:42 +0000594PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 PyVarObject_HEAD_INIT(&PyType_Type, 0)
596 "generator", /* tp_name */
597 sizeof(PyGenObject), /* tp_basicsize */
598 0, /* tp_itemsize */
599 /* methods */
600 (destructor)gen_dealloc, /* tp_dealloc */
601 0, /* tp_print */
602 0, /* tp_getattr */
603 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400604 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 (reprfunc)gen_repr, /* tp_repr */
606 0, /* tp_as_number */
607 0, /* tp_as_sequence */
608 0, /* tp_as_mapping */
609 0, /* tp_hash */
610 0, /* tp_call */
611 0, /* tp_str */
612 PyObject_GenericGetAttr, /* tp_getattro */
613 0, /* tp_setattro */
614 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200615 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
616 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 0, /* tp_doc */
618 (traverseproc)gen_traverse, /* tp_traverse */
619 0, /* tp_clear */
620 0, /* tp_richcompare */
621 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov75445082015-05-11 22:57:16 -0400622 (getiterfunc)gen_get_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 (iternextfunc)gen_iternext, /* tp_iternext */
624 gen_methods, /* tp_methods */
625 gen_memberlist, /* tp_members */
626 gen_getsetlist, /* tp_getset */
627 0, /* tp_base */
628 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 0, /* tp_descr_get */
631 0, /* tp_descr_set */
632 0, /* tp_dictoffset */
633 0, /* tp_init */
634 0, /* tp_alloc */
635 0, /* tp_new */
636 0, /* tp_free */
637 0, /* tp_is_gc */
638 0, /* tp_bases */
639 0, /* tp_mro */
640 0, /* tp_cache */
641 0, /* tp_subclasses */
642 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200643 0, /* tp_del */
644 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200645 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000646};
647
648PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200649PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
652 if (gen == NULL) {
653 Py_DECREF(f);
654 return NULL;
655 }
656 gen->gi_frame = f;
Antoine Pitrou58720d62013-08-05 23:26:40 +0200657 f->f_gen = (PyObject *) gen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 Py_INCREF(f->f_code);
659 gen->gi_code = (PyObject *)(f->f_code);
660 gen->gi_running = 0;
661 gen->gi_weakreflist = NULL;
Victor Stinner40ee3012014-06-16 15:59:28 +0200662 if (name != NULL)
663 gen->gi_name = name;
664 else
665 gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;
666 Py_INCREF(gen->gi_name);
667 if (qualname != NULL)
668 gen->gi_qualname = qualname;
669 else
670 gen->gi_qualname = gen->gi_name;
671 Py_INCREF(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 _PyObject_GC_TRACK(gen);
673 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000674}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000675
Victor Stinner40ee3012014-06-16 15:59:28 +0200676PyObject *
677PyGen_New(PyFrameObject *f)
678{
679 return PyGen_NewWithQualName(f, NULL, NULL);
680}
681
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000682int
683PyGen_NeedsFinalizing(PyGenObject *gen)
684{
Antoine Pitrou93963562013-05-14 20:37:52 +0200685 int i;
686 PyFrameObject *f = gen->gi_frame;
687
688 if (f == NULL || f->f_stacktop == NULL)
689 return 0; /* no frame or empty blockstack == no finalization */
690
691 /* Any block type besides a loop requires cleanup. */
692 for (i = 0; i < f->f_iblock; i++)
693 if (f->f_blockstack[i].b_type != SETUP_LOOP)
694 return 1;
695
696 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698}
Yury Selivanov75445082015-05-11 22:57:16 -0400699
700/*
701 * This helper function returns an awaitable for `o`:
702 * - `o` if `o` is a coroutine-object;
703 * - `type(o)->tp_as_async->am_await(o)`
704 *
705 * Raises a TypeError if it's not possible to return
706 * an awaitable and returns NULL.
707 */
708PyObject *
709_PyGen_GetAwaitableIter(PyObject *o)
710{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400711 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400712 PyTypeObject *ot;
713
714 if (PyGen_CheckCoroutineExact(o)) {
715 /* Fast path. It's a central function for 'await'. */
716 Py_INCREF(o);
717 return o;
718 }
719
720 ot = Py_TYPE(o);
721 if (ot->tp_as_async != NULL) {
722 getter = ot->tp_as_async->am_await;
723 }
724 if (getter != NULL) {
725 PyObject *res = (*getter)(o);
726 if (res != NULL) {
727 if (!PyIter_Check(res)) {
728 PyErr_Format(PyExc_TypeError,
729 "__await__() returned non-iterator "
730 "of type '%.100s'",
731 Py_TYPE(res)->tp_name);
732 Py_CLEAR(res);
733 }
734 else {
735 if (PyGen_CheckCoroutineExact(res)) {
736 /* __await__ must return an *iterator*, not
737 a coroutine or another awaitable (see PEP 492) */
738 PyErr_SetString(PyExc_TypeError,
739 "__await__() returned a coroutine");
740 Py_CLEAR(res);
741 }
742 }
743 }
744 return res;
745 }
746
747 PyErr_Format(PyExc_TypeError,
748 "object %.100s can't be used in 'await' expression",
749 ot->tp_name);
750
751 return NULL;
752}