blob: c028db51455fbe2135679e1939dcbb05aaf6d325 [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
Yury Selivanov5376ba92015-06-22 12:19:30 -040030 && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE
Yury Selivanov75445082015-05-11 22:57:16 -040031 && gen->gi_frame != NULL
32 && gen->gi_frame->f_lasti == -1
33 && !PyErr_Occurred()
34 && PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
35 "coroutine '%.50S' was never awaited",
36 gen->gi_qualname))
37 return;
38
Antoine Pitrou796564c2013-07-30 19:59:21 +020039 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
40 /* Generator isn't paused, so no need to close */
41 return;
42
43 /* Save the current exception, if any. */
44 PyErr_Fetch(&error_type, &error_value, &error_traceback);
45
46 res = gen_close(gen, NULL);
47
48 if (res == NULL)
49 PyErr_WriteUnraisable(self);
50 else
51 Py_DECREF(res);
52
53 /* Restore the saved exception. */
54 PyErr_Restore(error_type, error_value, error_traceback);
55}
56
57static void
Martin v. Löwise440e472004-06-01 15:22:42 +000058gen_dealloc(PyGenObject *gen)
59{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 PyObject *self = (PyObject *) gen;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 if (gen->gi_weakreflist != NULL)
65 PyObject_ClearWeakRefs(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000066
Antoine Pitrou93963562013-05-14 20:37:52 +020067 _PyObject_GC_TRACK(self);
68
Antoine Pitrou796564c2013-07-30 19:59:21 +020069 if (PyObject_CallFinalizerFromDealloc(self))
70 return; /* resurrected. :( */
Antoine Pitrou93963562013-05-14 20:37:52 +020071
72 _PyObject_GC_UNTRACK(self);
73 Py_CLEAR(gen->gi_frame);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 Py_CLEAR(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020075 Py_CLEAR(gen->gi_name);
76 Py_CLEAR(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000078}
79
80static PyObject *
Yury Selivanov77c96812016-02-13 17:59:05 -050081gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
Martin v. Löwise440e472004-06-01 15:22:42 +000082{
Antoine Pitrou93963562013-05-14 20:37:52 +020083 PyThreadState *tstate = PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +020085 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000086
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050087 if (gen->gi_running) {
Yury Selivanov5376ba92015-06-22 12:19:30 -040088 char *msg = "generator already executing";
89 if (PyCoro_CheckExact(gen))
90 msg = "coroutine already executing";
91 PyErr_SetString(PyExc_ValueError, msg);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050092 return NULL;
93 }
Antoine Pitrou93963562013-05-14 20:37:52 +020094 if (f == NULL || f->f_stacktop == NULL) {
Yury Selivanov77c96812016-02-13 17:59:05 -050095 if (PyCoro_CheckExact(gen) && !closing) {
96 /* `gen` is an exhausted coroutine: raise an error,
97 except when called from gen_close(), which should
98 always be a silent method. */
99 PyErr_SetString(
100 PyExc_RuntimeError,
101 "cannot reuse already awaited coroutine");
102 } else if (arg && !exc) {
103 /* `gen` is an exhausted generator:
104 only set exception if called from send(). */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 PyErr_SetNone(PyExc_StopIteration);
Yury Selivanov77c96812016-02-13 17:59:05 -0500106 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 return NULL;
108 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000109
Antoine Pitrou93963562013-05-14 20:37:52 +0200110 if (f->f_lasti == -1) {
111 if (arg && arg != Py_None) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400112 char *msg = "can't send non-None value to a "
113 "just-started generator";
114 if (PyCoro_CheckExact(gen))
115 msg = "can't send non-None value to a "
116 "just-started coroutine";
117 PyErr_SetString(PyExc_TypeError, msg);
Antoine Pitrou93963562013-05-14 20:37:52 +0200118 return NULL;
119 }
120 } else {
121 /* Push arg onto the frame's value stack */
122 result = arg ? arg : Py_None;
123 Py_INCREF(result);
124 *(f->f_stacktop++) = result;
125 }
126
127 /* Generators always return to their most recent caller, not
128 * necessarily their creator. */
129 Py_XINCREF(tstate->frame);
130 assert(f->f_back == NULL);
131 f->f_back = tstate->frame;
132
133 gen->gi_running = 1;
134 result = PyEval_EvalFrameEx(f, exc);
135 gen->gi_running = 0;
136
137 /* Don't keep the reference to f_back any longer than necessary. It
138 * may keep a chain of frames alive or it could create a reference
139 * cycle. */
140 assert(f->f_back == tstate->frame);
141 Py_CLEAR(f->f_back);
142
143 /* If the generator just returned (as opposed to yielding), signal
144 * that the generator is exhausted. */
145 if (result && f->f_stacktop == NULL) {
146 if (result == Py_None) {
147 /* Delay exception instantiation if we can */
148 PyErr_SetNone(PyExc_StopIteration);
149 } else {
150 PyObject *e = PyObject_CallFunctionObjArgs(
151 PyExc_StopIteration, result, NULL);
152 if (e != NULL) {
153 PyErr_SetObject(PyExc_StopIteration, e);
154 Py_DECREF(e);
155 }
156 }
157 Py_CLEAR(result);
158 }
Yury Selivanov68333392015-05-22 11:16:47 -0400159 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400160 /* Check for __future__ generator_stop and conditionally turn
161 * a leaking StopIteration into RuntimeError (with its cause
162 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400163 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400164 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400165 {
166 PyObject *exc, *val, *val2, *tb;
Yury Selivanov5376ba92015-06-22 12:19:30 -0400167 char *msg = "generator raised StopIteration";
168 if (PyCoro_CheckExact(gen))
169 msg = "coroutine raised StopIteration";
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400170 PyErr_Fetch(&exc, &val, &tb);
171 PyErr_NormalizeException(&exc, &val, &tb);
172 if (tb != NULL)
173 PyException_SetTraceback(val, tb);
174 Py_DECREF(exc);
175 Py_XDECREF(tb);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400176 PyErr_SetString(PyExc_RuntimeError, msg);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400177 PyErr_Fetch(&exc, &val2, &tb);
178 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400179 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400180 PyException_SetCause(val2, val);
181 PyException_SetContext(val2, val);
182 PyErr_Restore(exc, val2, tb);
183 }
Yury Selivanov68333392015-05-22 11:16:47 -0400184 else {
185 PyObject *exc, *val, *tb;
186
187 /* Pop the exception before issuing a warning. */
188 PyErr_Fetch(&exc, &val, &tb);
189
Martin Panter7e3a91a2016-02-10 04:40:48 +0000190 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
Yury Selivanov68333392015-05-22 11:16:47 -0400191 "generator '%.50S' raised StopIteration",
192 gen->gi_qualname)) {
193 /* Warning was converted to an error. */
194 Py_XDECREF(exc);
195 Py_XDECREF(val);
196 Py_XDECREF(tb);
197 }
198 else {
199 PyErr_Restore(exc, val, tb);
200 }
201 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400202 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200203
204 if (!result || f->f_stacktop == NULL) {
205 /* generator can't be rerun, so release the frame */
206 /* first clean reference cycle through stored exception traceback */
207 PyObject *t, *v, *tb;
208 t = f->f_exc_type;
209 v = f->f_exc_value;
210 tb = f->f_exc_traceback;
211 f->f_exc_type = NULL;
212 f->f_exc_value = NULL;
213 f->f_exc_traceback = NULL;
214 Py_XDECREF(t);
215 Py_XDECREF(v);
216 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200217 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200218 gen->gi_frame = NULL;
219 Py_DECREF(f);
220 }
221
222 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000223}
224
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000225PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000226"send(arg) -> send 'arg' into generator,\n\
227return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000228
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500229PyObject *
230_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000231{
Yury Selivanov77c96812016-02-13 17:59:05 -0500232 return gen_send_ex(gen, arg, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000233}
234
235PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400236"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000237
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000238/*
239 * This helper function is used by gen_close and gen_throw to
240 * close a subiterator being delegated to by yield-from.
241 */
242
Antoine Pitrou93963562013-05-14 20:37:52 +0200243static int
244gen_close_iter(PyObject *yf)
245{
246 PyObject *retval = NULL;
247 _Py_IDENTIFIER(close);
248
249 if (PyGen_CheckExact(yf)) {
250 retval = gen_close((PyGenObject *)yf, NULL);
251 if (retval == NULL)
252 return -1;
253 } else {
254 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
255 if (meth == NULL) {
256 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
257 PyErr_WriteUnraisable(yf);
258 PyErr_Clear();
259 } else {
260 retval = PyObject_CallFunction(meth, "");
261 Py_DECREF(meth);
262 if (retval == NULL)
263 return -1;
264 }
265 }
266 Py_XDECREF(retval);
267 return 0;
268}
269
Yury Selivanovc724bae2016-03-02 11:30:46 -0500270PyObject *
271_PyGen_yf(PyGenObject *gen)
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500272{
Antoine Pitrou93963562013-05-14 20:37:52 +0200273 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500274 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200275
276 if (f && f->f_stacktop) {
277 PyObject *bytecode = f->f_code->co_code;
278 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
279
Serhiy Storchakab0f80b02016-05-24 09:15:14 +0300280 if (code[f->f_lasti + 2] != YIELD_FROM)
Antoine Pitrou93963562013-05-14 20:37:52 +0200281 return NULL;
282 yf = f->f_stacktop[-1];
283 Py_INCREF(yf);
284 }
285
286 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500287}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000288
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000289static PyObject *
290gen_close(PyGenObject *gen, PyObject *args)
291{
Antoine Pitrou93963562013-05-14 20:37:52 +0200292 PyObject *retval;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500293 PyObject *yf = _PyGen_yf(gen);
Antoine Pitrou93963562013-05-14 20:37:52 +0200294 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000295
Antoine Pitrou93963562013-05-14 20:37:52 +0200296 if (yf) {
297 gen->gi_running = 1;
298 err = gen_close_iter(yf);
299 gen->gi_running = 0;
300 Py_DECREF(yf);
301 }
302 if (err == 0)
303 PyErr_SetNone(PyExc_GeneratorExit);
Yury Selivanov77c96812016-02-13 17:59:05 -0500304 retval = gen_send_ex(gen, Py_None, 1, 1);
Antoine Pitrou93963562013-05-14 20:37:52 +0200305 if (retval) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400306 char *msg = "generator ignored GeneratorExit";
307 if (PyCoro_CheckExact(gen))
308 msg = "coroutine ignored GeneratorExit";
Antoine Pitrou93963562013-05-14 20:37:52 +0200309 Py_DECREF(retval);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400310 PyErr_SetString(PyExc_RuntimeError, msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 return NULL;
312 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200313 if (PyErr_ExceptionMatches(PyExc_StopIteration)
314 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
315 PyErr_Clear(); /* ignore these errors */
316 Py_INCREF(Py_None);
317 return Py_None;
318 }
319 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000320}
321
Antoine Pitrou93963562013-05-14 20:37:52 +0200322
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000323PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
325return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000326
327static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 PyObject *typ;
331 PyObject *tb = NULL;
332 PyObject *val = NULL;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500333 PyObject *yf = _PyGen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000334 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
337 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000338
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000339 if (yf) {
340 PyObject *ret;
341 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000342 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500343 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200344 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500345 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000346 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000347 if (err < 0)
Yury Selivanov77c96812016-02-13 17:59:05 -0500348 return gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000349 goto throw_here;
350 }
351 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500352 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000353 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500354 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000355 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000356 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000357 if (meth == NULL) {
358 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
359 Py_DECREF(yf);
360 return NULL;
361 }
362 PyErr_Clear();
363 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000364 goto throw_here;
365 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500366 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000367 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500368 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000369 Py_DECREF(meth);
370 }
371 Py_DECREF(yf);
372 if (!ret) {
373 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500374 /* Pop subiterator from stack */
375 ret = *(--gen->gi_frame->f_stacktop);
376 assert(ret == yf);
377 Py_DECREF(ret);
378 /* Termination repetition of YIELD_FROM */
Serhiy Storchakab0f80b02016-05-24 09:15:14 +0300379 gen->gi_frame->f_lasti += 2;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000380 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500381 ret = gen_send_ex(gen, val, 0, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000382 Py_DECREF(val);
383 } else {
Yury Selivanov77c96812016-02-13 17:59:05 -0500384 ret = gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000385 }
386 }
387 return ret;
388 }
389
390throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 /* First, check the traceback argument, replacing None with
392 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400393 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400395 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 else if (tb != NULL && !PyTraceBack_Check(tb)) {
397 PyErr_SetString(PyExc_TypeError,
398 "throw() third argument must be a traceback object");
399 return NULL;
400 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 Py_INCREF(typ);
403 Py_XINCREF(val);
404 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000405
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400406 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 else if (PyExceptionInstance_Check(typ)) {
410 /* Raising an instance. The value should be a dummy. */
411 if (val && val != Py_None) {
412 PyErr_SetString(PyExc_TypeError,
413 "instance exception may not have a separate value");
414 goto failed_throw;
415 }
416 else {
417 /* Normalize to raise <class>, <instance> */
418 Py_XDECREF(val);
419 val = typ;
420 typ = PyExceptionInstance_Class(typ);
421 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200422
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400423 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200424 /* Returns NULL if there's no traceback */
425 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 }
427 }
428 else {
429 /* Not something you can raise. throw() fails. */
430 PyErr_Format(PyExc_TypeError,
431 "exceptions must be classes or instances "
432 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000433 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 goto failed_throw;
435 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 PyErr_Restore(typ, val, tb);
Yury Selivanov77c96812016-02-13 17:59:05 -0500438 return gen_send_ex(gen, Py_None, 1, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000439
440failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 /* Didn't use our arguments, so restore their original refcounts */
442 Py_DECREF(typ);
443 Py_XDECREF(val);
444 Py_XDECREF(tb);
445 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000446}
447
448
449static PyObject *
450gen_iternext(PyGenObject *gen)
451{
Yury Selivanov77c96812016-02-13 17:59:05 -0500452 return gen_send_ex(gen, NULL, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000453}
454
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000455/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000456 * If StopIteration exception is set, fetches its 'value'
457 * attribute if any, otherwise sets pvalue to None.
458 *
459 * Returns 0 if no exception or StopIteration is set.
460 * If any other exception is set, returns -1 and leaves
461 * pvalue unchanged.
462 */
463
464int
Nick Coghlanc40bc092012-06-17 15:15:49 +1000465_PyGen_FetchStopIterationValue(PyObject **pvalue) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000466 PyObject *et, *ev, *tb;
467 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500468
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000469 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
470 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200471 if (ev) {
472 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300473 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200474 value = ((PyStopIterationObject *)ev)->value;
475 Py_INCREF(value);
476 Py_DECREF(ev);
477 } else if (et == PyExc_StopIteration) {
478 /* avoid normalisation and take ev as value */
479 value = ev;
480 } else {
481 /* normalisation required */
482 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300483 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200484 PyErr_Restore(et, ev, tb);
485 return -1;
486 }
487 value = ((PyStopIterationObject *)ev)->value;
488 Py_INCREF(value);
489 Py_DECREF(ev);
490 }
491 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000492 Py_XDECREF(et);
493 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000494 } else if (PyErr_Occurred()) {
495 return -1;
496 }
497 if (value == NULL) {
498 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100499 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000500 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000501 *pvalue = value;
502 return 0;
503}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000504
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000505static PyObject *
506gen_repr(PyGenObject *gen)
507{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400508 return PyUnicode_FromFormat("<generator object %S at %p>",
509 gen->gi_qualname, gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000510}
511
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000512static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200513gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000514{
Victor Stinner40ee3012014-06-16 15:59:28 +0200515 Py_INCREF(op->gi_name);
516 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000517}
518
Victor Stinner40ee3012014-06-16 15:59:28 +0200519static int
520gen_set_name(PyGenObject *op, PyObject *value)
521{
Victor Stinner40ee3012014-06-16 15:59:28 +0200522 /* Not legal to del gen.gi_name or to set it to anything
523 * other than a string object. */
524 if (value == NULL || !PyUnicode_Check(value)) {
525 PyErr_SetString(PyExc_TypeError,
526 "__name__ must be set to a string object");
527 return -1;
528 }
Victor Stinner40ee3012014-06-16 15:59:28 +0200529 Py_INCREF(value);
Serhiy Storchakaec397562016-04-06 09:50:03 +0300530 Py_XSETREF(op->gi_name, value);
Victor Stinner40ee3012014-06-16 15:59:28 +0200531 return 0;
532}
533
534static PyObject *
535gen_get_qualname(PyGenObject *op)
536{
537 Py_INCREF(op->gi_qualname);
538 return op->gi_qualname;
539}
540
541static int
542gen_set_qualname(PyGenObject *op, PyObject *value)
543{
Victor Stinner40ee3012014-06-16 15:59:28 +0200544 /* Not legal to del gen.__qualname__ or to set it to anything
545 * other than a string object. */
546 if (value == NULL || !PyUnicode_Check(value)) {
547 PyErr_SetString(PyExc_TypeError,
548 "__qualname__ must be set to a string object");
549 return -1;
550 }
Victor Stinner40ee3012014-06-16 15:59:28 +0200551 Py_INCREF(value);
Serhiy Storchakaec397562016-04-06 09:50:03 +0300552 Py_XSETREF(op->gi_qualname, value);
Victor Stinner40ee3012014-06-16 15:59:28 +0200553 return 0;
554}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000555
Yury Selivanove13f8f32015-07-03 00:23:30 -0400556static PyObject *
557gen_getyieldfrom(PyGenObject *gen)
558{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500559 PyObject *yf = _PyGen_yf(gen);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400560 if (yf == NULL)
561 Py_RETURN_NONE;
562 return yf;
563}
564
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000565static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200566 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
567 PyDoc_STR("name of the generator")},
568 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
569 PyDoc_STR("qualified name of the generator")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400570 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
571 PyDoc_STR("object being iterated by yield from, or None")},
Victor Stinner40ee3012014-06-16 15:59:28 +0200572 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000573};
574
Martin v. Löwise440e472004-06-01 15:22:42 +0000575static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200576 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
577 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
578 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000580};
581
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000582static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500583 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
585 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
586 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000587};
588
Martin v. Löwise440e472004-06-01 15:22:42 +0000589PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 PyVarObject_HEAD_INIT(&PyType_Type, 0)
591 "generator", /* tp_name */
592 sizeof(PyGenObject), /* tp_basicsize */
593 0, /* tp_itemsize */
594 /* methods */
595 (destructor)gen_dealloc, /* tp_dealloc */
596 0, /* tp_print */
597 0, /* tp_getattr */
598 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400599 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 (reprfunc)gen_repr, /* tp_repr */
601 0, /* tp_as_number */
602 0, /* tp_as_sequence */
603 0, /* tp_as_mapping */
604 0, /* tp_hash */
605 0, /* tp_call */
606 0, /* tp_str */
607 PyObject_GenericGetAttr, /* tp_getattro */
608 0, /* tp_setattro */
609 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200610 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
611 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 0, /* tp_doc */
613 (traverseproc)gen_traverse, /* tp_traverse */
614 0, /* tp_clear */
615 0, /* tp_richcompare */
616 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov5376ba92015-06-22 12:19:30 -0400617 PyObject_SelfIter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 (iternextfunc)gen_iternext, /* tp_iternext */
619 gen_methods, /* tp_methods */
620 gen_memberlist, /* tp_members */
621 gen_getsetlist, /* tp_getset */
622 0, /* tp_base */
623 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 0, /* tp_descr_get */
626 0, /* tp_descr_set */
627 0, /* tp_dictoffset */
628 0, /* tp_init */
629 0, /* tp_alloc */
630 0, /* tp_new */
631 0, /* tp_free */
632 0, /* tp_is_gc */
633 0, /* tp_bases */
634 0, /* tp_mro */
635 0, /* tp_cache */
636 0, /* tp_subclasses */
637 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200638 0, /* tp_del */
639 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200640 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000641};
642
Yury Selivanov5376ba92015-06-22 12:19:30 -0400643static PyObject *
644gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
645 PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000646{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400647 PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 if (gen == NULL) {
649 Py_DECREF(f);
650 return NULL;
651 }
652 gen->gi_frame = f;
Antoine Pitrou58720d62013-08-05 23:26:40 +0200653 f->f_gen = (PyObject *) gen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 Py_INCREF(f->f_code);
655 gen->gi_code = (PyObject *)(f->f_code);
656 gen->gi_running = 0;
657 gen->gi_weakreflist = NULL;
Victor Stinner40ee3012014-06-16 15:59:28 +0200658 if (name != NULL)
659 gen->gi_name = name;
660 else
661 gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;
662 Py_INCREF(gen->gi_name);
663 if (qualname != NULL)
664 gen->gi_qualname = qualname;
665 else
666 gen->gi_qualname = gen->gi_name;
667 Py_INCREF(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 _PyObject_GC_TRACK(gen);
669 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000670}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000671
Victor Stinner40ee3012014-06-16 15:59:28 +0200672PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400673PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
674{
675 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
676}
677
678PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200679PyGen_New(PyFrameObject *f)
680{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400681 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
Victor Stinner40ee3012014-06-16 15:59:28 +0200682}
683
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000684int
685PyGen_NeedsFinalizing(PyGenObject *gen)
686{
Antoine Pitrou93963562013-05-14 20:37:52 +0200687 int i;
688 PyFrameObject *f = gen->gi_frame;
689
690 if (f == NULL || f->f_stacktop == NULL)
691 return 0; /* no frame or empty blockstack == no finalization */
692
693 /* Any block type besides a loop requires cleanup. */
694 for (i = 0; i < f->f_iblock; i++)
695 if (f->f_blockstack[i].b_type != SETUP_LOOP)
696 return 1;
697
698 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000700}
Yury Selivanov75445082015-05-11 22:57:16 -0400701
Yury Selivanov5376ba92015-06-22 12:19:30 -0400702/* Coroutine Object */
703
704typedef struct {
705 PyObject_HEAD
706 PyCoroObject *cw_coroutine;
707} PyCoroWrapper;
708
709static int
710gen_is_coroutine(PyObject *o)
711{
712 if (PyGen_CheckExact(o)) {
713 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
714 if (code->co_flags & CO_ITERABLE_COROUTINE) {
715 return 1;
716 }
717 }
718 return 0;
719}
720
Yury Selivanov75445082015-05-11 22:57:16 -0400721/*
722 * This helper function returns an awaitable for `o`:
723 * - `o` if `o` is a coroutine-object;
724 * - `type(o)->tp_as_async->am_await(o)`
725 *
726 * Raises a TypeError if it's not possible to return
727 * an awaitable and returns NULL.
728 */
729PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400730_PyCoro_GetAwaitableIter(PyObject *o)
Yury Selivanov75445082015-05-11 22:57:16 -0400731{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400732 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400733 PyTypeObject *ot;
734
Yury Selivanov5376ba92015-06-22 12:19:30 -0400735 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
736 /* 'o' is a coroutine. */
Yury Selivanov75445082015-05-11 22:57:16 -0400737 Py_INCREF(o);
738 return o;
739 }
740
741 ot = Py_TYPE(o);
742 if (ot->tp_as_async != NULL) {
743 getter = ot->tp_as_async->am_await;
744 }
745 if (getter != NULL) {
746 PyObject *res = (*getter)(o);
747 if (res != NULL) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400748 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
749 /* __await__ must return an *iterator*, not
750 a coroutine or another awaitable (see PEP 492) */
751 PyErr_SetString(PyExc_TypeError,
752 "__await__() returned a coroutine");
753 Py_CLEAR(res);
754 } else if (!PyIter_Check(res)) {
Yury Selivanov75445082015-05-11 22:57:16 -0400755 PyErr_Format(PyExc_TypeError,
756 "__await__() returned non-iterator "
757 "of type '%.100s'",
758 Py_TYPE(res)->tp_name);
759 Py_CLEAR(res);
760 }
Yury Selivanov75445082015-05-11 22:57:16 -0400761 }
762 return res;
763 }
764
765 PyErr_Format(PyExc_TypeError,
766 "object %.100s can't be used in 'await' expression",
767 ot->tp_name);
Yury Selivanov75445082015-05-11 22:57:16 -0400768 return NULL;
769}
Yury Selivanov5376ba92015-06-22 12:19:30 -0400770
771static PyObject *
772coro_repr(PyCoroObject *coro)
773{
774 return PyUnicode_FromFormat("<coroutine object %S at %p>",
775 coro->cr_qualname, coro);
776}
777
778static PyObject *
779coro_await(PyCoroObject *coro)
780{
781 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
782 if (cw == NULL) {
783 return NULL;
784 }
785 Py_INCREF(coro);
786 cw->cw_coroutine = coro;
787 _PyObject_GC_TRACK(cw);
788 return (PyObject *)cw;
789}
790
Yury Selivanove13f8f32015-07-03 00:23:30 -0400791static PyObject *
792coro_get_cr_await(PyCoroObject *coro)
793{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500794 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400795 if (yf == NULL)
796 Py_RETURN_NONE;
797 return yf;
798}
799
Yury Selivanov5376ba92015-06-22 12:19:30 -0400800static PyGetSetDef coro_getsetlist[] = {
801 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
802 PyDoc_STR("name of the coroutine")},
803 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
804 PyDoc_STR("qualified name of the coroutine")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400805 {"cr_await", (getter)coro_get_cr_await, NULL,
806 PyDoc_STR("object being awaited on, or None")},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400807 {NULL} /* Sentinel */
808};
809
810static PyMemberDef coro_memberlist[] = {
811 {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
812 {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
813 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
814 {NULL} /* Sentinel */
815};
816
817PyDoc_STRVAR(coro_send_doc,
818"send(arg) -> send 'arg' into coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400819return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400820
821PyDoc_STRVAR(coro_throw_doc,
822"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400823return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400824
825PyDoc_STRVAR(coro_close_doc,
826"close() -> raise GeneratorExit inside coroutine.");
827
828static PyMethodDef coro_methods[] = {
829 {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
830 {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
831 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
832 {NULL, NULL} /* Sentinel */
833};
834
835static PyAsyncMethods coro_as_async = {
836 (unaryfunc)coro_await, /* am_await */
837 0, /* am_aiter */
838 0 /* am_anext */
839};
840
841PyTypeObject PyCoro_Type = {
842 PyVarObject_HEAD_INIT(&PyType_Type, 0)
843 "coroutine", /* tp_name */
844 sizeof(PyCoroObject), /* tp_basicsize */
845 0, /* tp_itemsize */
846 /* methods */
847 (destructor)gen_dealloc, /* tp_dealloc */
848 0, /* tp_print */
849 0, /* tp_getattr */
850 0, /* tp_setattr */
851 &coro_as_async, /* tp_as_async */
852 (reprfunc)coro_repr, /* tp_repr */
853 0, /* tp_as_number */
854 0, /* tp_as_sequence */
855 0, /* tp_as_mapping */
856 0, /* tp_hash */
857 0, /* tp_call */
858 0, /* tp_str */
859 PyObject_GenericGetAttr, /* tp_getattro */
860 0, /* tp_setattro */
861 0, /* tp_as_buffer */
862 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
863 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
864 0, /* tp_doc */
865 (traverseproc)gen_traverse, /* tp_traverse */
866 0, /* tp_clear */
867 0, /* tp_richcompare */
868 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
869 0, /* tp_iter */
870 0, /* tp_iternext */
871 coro_methods, /* tp_methods */
872 coro_memberlist, /* tp_members */
873 coro_getsetlist, /* tp_getset */
874 0, /* tp_base */
875 0, /* tp_dict */
876 0, /* tp_descr_get */
877 0, /* tp_descr_set */
878 0, /* tp_dictoffset */
879 0, /* tp_init */
880 0, /* tp_alloc */
881 0, /* tp_new */
882 0, /* tp_free */
883 0, /* tp_is_gc */
884 0, /* tp_bases */
885 0, /* tp_mro */
886 0, /* tp_cache */
887 0, /* tp_subclasses */
888 0, /* tp_weaklist */
889 0, /* tp_del */
890 0, /* tp_version_tag */
891 _PyGen_Finalize, /* tp_finalize */
892};
893
894static void
895coro_wrapper_dealloc(PyCoroWrapper *cw)
896{
897 _PyObject_GC_UNTRACK((PyObject *)cw);
898 Py_CLEAR(cw->cw_coroutine);
899 PyObject_GC_Del(cw);
900}
901
902static PyObject *
903coro_wrapper_iternext(PyCoroWrapper *cw)
904{
Yury Selivanov77c96812016-02-13 17:59:05 -0500905 return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400906}
907
908static PyObject *
909coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
910{
Yury Selivanov77c96812016-02-13 17:59:05 -0500911 return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400912}
913
914static PyObject *
915coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
916{
917 return gen_throw((PyGenObject *)cw->cw_coroutine, args);
918}
919
920static PyObject *
921coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
922{
923 return gen_close((PyGenObject *)cw->cw_coroutine, args);
924}
925
926static int
927coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
928{
929 Py_VISIT((PyObject *)cw->cw_coroutine);
930 return 0;
931}
932
933static PyMethodDef coro_wrapper_methods[] = {
Yury Selivanov66f88282015-06-24 11:04:15 -0400934 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
935 {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
936 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400937 {NULL, NULL} /* Sentinel */
938};
939
940PyTypeObject _PyCoroWrapper_Type = {
941 PyVarObject_HEAD_INIT(&PyType_Type, 0)
942 "coroutine_wrapper",
943 sizeof(PyCoroWrapper), /* tp_basicsize */
944 0, /* tp_itemsize */
945 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
946 0, /* tp_print */
947 0, /* tp_getattr */
948 0, /* tp_setattr */
949 0, /* tp_as_async */
950 0, /* tp_repr */
951 0, /* tp_as_number */
952 0, /* tp_as_sequence */
953 0, /* tp_as_mapping */
954 0, /* tp_hash */
955 0, /* tp_call */
956 0, /* tp_str */
957 PyObject_GenericGetAttr, /* tp_getattro */
958 0, /* tp_setattro */
959 0, /* tp_as_buffer */
960 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
961 "A wrapper object implementing __await__ for coroutines.",
962 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
963 0, /* tp_clear */
964 0, /* tp_richcompare */
965 0, /* tp_weaklistoffset */
966 PyObject_SelfIter, /* tp_iter */
967 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
968 coro_wrapper_methods, /* tp_methods */
969 0, /* tp_members */
970 0, /* tp_getset */
971 0, /* tp_base */
972 0, /* tp_dict */
973 0, /* tp_descr_get */
974 0, /* tp_descr_set */
975 0, /* tp_dictoffset */
976 0, /* tp_init */
977 0, /* tp_alloc */
978 0, /* tp_new */
979 PyObject_Del, /* tp_free */
980};
981
982PyObject *
983PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
984{
985 return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
986}
Yury Selivanova6f6edb2016-06-09 15:08:31 -0400987
988
989/* __aiter__ wrapper; see http://bugs.python.org/issue27243 for details. */
990
991typedef struct {
992 PyObject_HEAD
993 PyObject *aw_aiter;
994} PyAIterWrapper;
995
996
997static PyObject *
998aiter_wrapper_iternext(PyAIterWrapper *aw)
999{
1000 PyErr_SetObject(PyExc_StopIteration, aw->aw_aiter);
1001 return NULL;
1002}
1003
1004static int
1005aiter_wrapper_traverse(PyAIterWrapper *aw, visitproc visit, void *arg)
1006{
1007 Py_VISIT((PyObject *)aw->aw_aiter);
1008 return 0;
1009}
1010
1011static void
1012aiter_wrapper_dealloc(PyAIterWrapper *aw)
1013{
1014 _PyObject_GC_UNTRACK((PyObject *)aw);
1015 Py_CLEAR(aw->aw_aiter);
1016 PyObject_GC_Del(aw);
1017}
1018
1019static PyAsyncMethods aiter_wrapper_as_async = {
1020 PyObject_SelfIter, /* am_await */
1021 0, /* am_aiter */
1022 0 /* am_anext */
1023};
1024
1025PyTypeObject _PyAIterWrapper_Type = {
1026 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1027 "aiter_wrapper",
1028 sizeof(PyAIterWrapper), /* tp_basicsize */
1029 0, /* tp_itemsize */
1030 (destructor)aiter_wrapper_dealloc, /* destructor tp_dealloc */
1031 0, /* tp_print */
1032 0, /* tp_getattr */
1033 0, /* tp_setattr */
1034 &aiter_wrapper_as_async, /* tp_as_async */
1035 0, /* tp_repr */
1036 0, /* tp_as_number */
1037 0, /* tp_as_sequence */
1038 0, /* tp_as_mapping */
1039 0, /* tp_hash */
1040 0, /* tp_call */
1041 0, /* tp_str */
1042 PyObject_GenericGetAttr, /* tp_getattro */
1043 0, /* tp_setattro */
1044 0, /* tp_as_buffer */
1045 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1046 "A wrapper object for __aiter__ bakwards compatibility.",
1047 (traverseproc)aiter_wrapper_traverse, /* tp_traverse */
1048 0, /* tp_clear */
1049 0, /* tp_richcompare */
1050 0, /* tp_weaklistoffset */
1051 PyObject_SelfIter, /* tp_iter */
1052 (iternextfunc)aiter_wrapper_iternext, /* tp_iternext */
1053 0, /* tp_methods */
1054 0, /* tp_members */
1055 0, /* tp_getset */
1056 0, /* tp_base */
1057 0, /* tp_dict */
1058 0, /* tp_descr_get */
1059 0, /* tp_descr_set */
1060 0, /* tp_dictoffset */
1061 0, /* tp_init */
1062 0, /* tp_alloc */
1063 0, /* tp_new */
1064 PyObject_Del, /* tp_free */
1065};
1066
1067
1068PyObject *
1069_PyAIterWrapper_New(PyObject *aiter)
1070{
1071 PyAIterWrapper *aw = PyObject_GC_New(PyAIterWrapper,
1072 &_PyAIterWrapper_Type);
1073 if (aw == NULL) {
1074 return NULL;
1075 }
1076 Py_INCREF(aiter);
1077 aw->aw_aiter = aiter;
1078 _PyObject_GC_TRACK(aw);
1079 return (PyObject *)aw;
1080}