blob: 104d90b3e6c7fa743045d6e4bb9b9e7303a82cb3 [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
27 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
28 /* Generator isn't paused, so no need to close */
29 return;
30
31 /* Save the current exception, if any. */
32 PyErr_Fetch(&error_type, &error_value, &error_traceback);
33
Benjamin Peterson2f40ed42016-09-05 10:14:54 -070034 /* If `gen` is a coroutine, and if it was never awaited on,
35 issue a RuntimeWarning. */
36 if (gen->gi_code != NULL
37 && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE
38 && gen->gi_frame->f_lasti == -1
39 && !PyErr_Occurred()
40 && PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
41 "coroutine '%.50S' was never awaited",
42 gen->gi_qualname)) {
43 res = NULL; /* oops, exception */
44 }
45 else {
46 res = gen_close(gen, NULL);
47 }
Antoine Pitrou796564c2013-07-30 19:59:21 +020048
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);
Benjamin Petersonbdddb112016-09-05 10:39:57 -070074 if (gen->gi_frame != NULL) {
75 gen->gi_frame->f_gen = NULL;
76 Py_CLEAR(gen->gi_frame);
77 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 Py_CLEAR(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020079 Py_CLEAR(gen->gi_name);
80 Py_CLEAR(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000082}
83
84static PyObject *
Yury Selivanov77c96812016-02-13 17:59:05 -050085gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
Martin v. Löwise440e472004-06-01 15:22:42 +000086{
Antoine Pitrou93963562013-05-14 20:37:52 +020087 PyThreadState *tstate = PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +020089 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000090
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050091 if (gen->gi_running) {
Yury Selivanov5376ba92015-06-22 12:19:30 -040092 char *msg = "generator already executing";
93 if (PyCoro_CheckExact(gen))
94 msg = "coroutine already executing";
95 PyErr_SetString(PyExc_ValueError, msg);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050096 return NULL;
97 }
Antoine Pitrou93963562013-05-14 20:37:52 +020098 if (f == NULL || f->f_stacktop == NULL) {
Yury Selivanov77c96812016-02-13 17:59:05 -050099 if (PyCoro_CheckExact(gen) && !closing) {
100 /* `gen` is an exhausted coroutine: raise an error,
101 except when called from gen_close(), which should
102 always be a silent method. */
103 PyErr_SetString(
104 PyExc_RuntimeError,
105 "cannot reuse already awaited coroutine");
106 } else if (arg && !exc) {
107 /* `gen` is an exhausted generator:
108 only set exception if called from send(). */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 PyErr_SetNone(PyExc_StopIteration);
Yury Selivanov77c96812016-02-13 17:59:05 -0500110 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 return NULL;
112 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000113
Antoine Pitrou93963562013-05-14 20:37:52 +0200114 if (f->f_lasti == -1) {
115 if (arg && arg != Py_None) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400116 char *msg = "can't send non-None value to a "
117 "just-started generator";
118 if (PyCoro_CheckExact(gen))
119 msg = "can't send non-None value to a "
120 "just-started coroutine";
121 PyErr_SetString(PyExc_TypeError, msg);
Antoine Pitrou93963562013-05-14 20:37:52 +0200122 return NULL;
123 }
124 } else {
125 /* Push arg onto the frame's value stack */
126 result = arg ? arg : Py_None;
127 Py_INCREF(result);
128 *(f->f_stacktop++) = result;
129 }
130
131 /* Generators always return to their most recent caller, not
132 * necessarily their creator. */
133 Py_XINCREF(tstate->frame);
134 assert(f->f_back == NULL);
135 f->f_back = tstate->frame;
136
137 gen->gi_running = 1;
138 result = PyEval_EvalFrameEx(f, exc);
139 gen->gi_running = 0;
140
141 /* Don't keep the reference to f_back any longer than necessary. It
142 * may keep a chain of frames alive or it could create a reference
143 * cycle. */
144 assert(f->f_back == tstate->frame);
145 Py_CLEAR(f->f_back);
146
147 /* If the generator just returned (as opposed to yielding), signal
148 * that the generator is exhausted. */
149 if (result && f->f_stacktop == NULL) {
150 if (result == Py_None) {
151 /* Delay exception instantiation if we can */
152 PyErr_SetNone(PyExc_StopIteration);
153 } else {
154 PyObject *e = PyObject_CallFunctionObjArgs(
155 PyExc_StopIteration, result, NULL);
156 if (e != NULL) {
157 PyErr_SetObject(PyExc_StopIteration, e);
158 Py_DECREF(e);
159 }
160 }
161 Py_CLEAR(result);
162 }
Yury Selivanov68333392015-05-22 11:16:47 -0400163 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400164 /* Check for __future__ generator_stop and conditionally turn
165 * a leaking StopIteration into RuntimeError (with its cause
166 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400167 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400168 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400169 {
170 PyObject *exc, *val, *val2, *tb;
Yury Selivanov5376ba92015-06-22 12:19:30 -0400171 char *msg = "generator raised StopIteration";
172 if (PyCoro_CheckExact(gen))
173 msg = "coroutine raised StopIteration";
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400174 PyErr_Fetch(&exc, &val, &tb);
175 PyErr_NormalizeException(&exc, &val, &tb);
176 if (tb != NULL)
177 PyException_SetTraceback(val, tb);
178 Py_DECREF(exc);
179 Py_XDECREF(tb);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400180 PyErr_SetString(PyExc_RuntimeError, msg);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400181 PyErr_Fetch(&exc, &val2, &tb);
182 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400183 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400184 PyException_SetCause(val2, val);
185 PyException_SetContext(val2, val);
186 PyErr_Restore(exc, val2, tb);
187 }
Yury Selivanov68333392015-05-22 11:16:47 -0400188 else {
189 PyObject *exc, *val, *tb;
190
191 /* Pop the exception before issuing a warning. */
192 PyErr_Fetch(&exc, &val, &tb);
193
Martin Panter7e3a91a2016-02-10 04:40:48 +0000194 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
Yury Selivanov68333392015-05-22 11:16:47 -0400195 "generator '%.50S' raised StopIteration",
196 gen->gi_qualname)) {
197 /* Warning was converted to an error. */
198 Py_XDECREF(exc);
199 Py_XDECREF(val);
200 Py_XDECREF(tb);
201 }
202 else {
203 PyErr_Restore(exc, val, tb);
204 }
205 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400206 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200207
208 if (!result || f->f_stacktop == NULL) {
209 /* generator can't be rerun, so release the frame */
210 /* first clean reference cycle through stored exception traceback */
211 PyObject *t, *v, *tb;
212 t = f->f_exc_type;
213 v = f->f_exc_value;
214 tb = f->f_exc_traceback;
215 f->f_exc_type = NULL;
216 f->f_exc_value = NULL;
217 f->f_exc_traceback = NULL;
218 Py_XDECREF(t);
219 Py_XDECREF(v);
220 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200221 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200222 gen->gi_frame = NULL;
223 Py_DECREF(f);
224 }
225
226 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000227}
228
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000229PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000230"send(arg) -> send 'arg' into generator,\n\
231return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000232
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500233PyObject *
234_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000235{
Yury Selivanov77c96812016-02-13 17:59:05 -0500236 return gen_send_ex(gen, arg, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000237}
238
239PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400240"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000241
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000242/*
243 * This helper function is used by gen_close and gen_throw to
244 * close a subiterator being delegated to by yield-from.
245 */
246
Antoine Pitrou93963562013-05-14 20:37:52 +0200247static int
248gen_close_iter(PyObject *yf)
249{
250 PyObject *retval = NULL;
251 _Py_IDENTIFIER(close);
252
253 if (PyGen_CheckExact(yf)) {
254 retval = gen_close((PyGenObject *)yf, NULL);
255 if (retval == NULL)
256 return -1;
257 } else {
258 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
259 if (meth == NULL) {
260 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
261 PyErr_WriteUnraisable(yf);
262 PyErr_Clear();
263 } else {
Victor Stinner3466bde2016-09-05 18:16:01 -0700264 retval = _PyObject_CallNoArg(meth);
Antoine Pitrou93963562013-05-14 20:37:52 +0200265 Py_DECREF(meth);
266 if (retval == NULL)
267 return -1;
268 }
269 }
270 Py_XDECREF(retval);
271 return 0;
272}
273
Yury Selivanovc724bae2016-03-02 11:30:46 -0500274PyObject *
275_PyGen_yf(PyGenObject *gen)
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500276{
Antoine Pitrou93963562013-05-14 20:37:52 +0200277 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500278 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200279
280 if (f && f->f_stacktop) {
281 PyObject *bytecode = f->f_code->co_code;
282 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
283
Serhiy Storchakab0f80b02016-05-24 09:15:14 +0300284 if (code[f->f_lasti + 2] != YIELD_FROM)
Antoine Pitrou93963562013-05-14 20:37:52 +0200285 return NULL;
286 yf = f->f_stacktop[-1];
287 Py_INCREF(yf);
288 }
289
290 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500291}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000292
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000293static PyObject *
294gen_close(PyGenObject *gen, PyObject *args)
295{
Antoine Pitrou93963562013-05-14 20:37:52 +0200296 PyObject *retval;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500297 PyObject *yf = _PyGen_yf(gen);
Antoine Pitrou93963562013-05-14 20:37:52 +0200298 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000299
Antoine Pitrou93963562013-05-14 20:37:52 +0200300 if (yf) {
301 gen->gi_running = 1;
302 err = gen_close_iter(yf);
303 gen->gi_running = 0;
304 Py_DECREF(yf);
305 }
306 if (err == 0)
307 PyErr_SetNone(PyExc_GeneratorExit);
Yury Selivanov77c96812016-02-13 17:59:05 -0500308 retval = gen_send_ex(gen, Py_None, 1, 1);
Antoine Pitrou93963562013-05-14 20:37:52 +0200309 if (retval) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400310 char *msg = "generator ignored GeneratorExit";
311 if (PyCoro_CheckExact(gen))
312 msg = "coroutine ignored GeneratorExit";
Antoine Pitrou93963562013-05-14 20:37:52 +0200313 Py_DECREF(retval);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400314 PyErr_SetString(PyExc_RuntimeError, msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 return NULL;
316 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200317 if (PyErr_ExceptionMatches(PyExc_StopIteration)
318 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
319 PyErr_Clear(); /* ignore these errors */
320 Py_INCREF(Py_None);
321 return Py_None;
322 }
323 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000324}
325
Antoine Pitrou93963562013-05-14 20:37:52 +0200326
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000327PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
329return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000330
331static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000332gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 PyObject *typ;
335 PyObject *tb = NULL;
336 PyObject *val = NULL;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500337 PyObject *yf = _PyGen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000338 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
341 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000342
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000343 if (yf) {
344 PyObject *ret;
345 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000346 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500347 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200348 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500349 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000350 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000351 if (err < 0)
Yury Selivanov77c96812016-02-13 17:59:05 -0500352 return gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000353 goto throw_here;
354 }
355 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500356 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000357 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500358 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000359 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000360 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000361 if (meth == NULL) {
362 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
363 Py_DECREF(yf);
364 return NULL;
365 }
366 PyErr_Clear();
367 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000368 goto throw_here;
369 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500370 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000371 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500372 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000373 Py_DECREF(meth);
374 }
375 Py_DECREF(yf);
376 if (!ret) {
377 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500378 /* Pop subiterator from stack */
379 ret = *(--gen->gi_frame->f_stacktop);
380 assert(ret == yf);
381 Py_DECREF(ret);
382 /* Termination repetition of YIELD_FROM */
Serhiy Storchakab0f80b02016-05-24 09:15:14 +0300383 gen->gi_frame->f_lasti += 2;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000384 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500385 ret = gen_send_ex(gen, val, 0, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000386 Py_DECREF(val);
387 } else {
Yury Selivanov77c96812016-02-13 17:59:05 -0500388 ret = gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000389 }
390 }
391 return ret;
392 }
393
394throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 /* First, check the traceback argument, replacing None with
396 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400397 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400399 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 else if (tb != NULL && !PyTraceBack_Check(tb)) {
401 PyErr_SetString(PyExc_TypeError,
402 "throw() third argument must be a traceback object");
403 return NULL;
404 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 Py_INCREF(typ);
407 Py_XINCREF(val);
408 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000409
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400410 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 else if (PyExceptionInstance_Check(typ)) {
414 /* Raising an instance. The value should be a dummy. */
415 if (val && val != Py_None) {
416 PyErr_SetString(PyExc_TypeError,
417 "instance exception may not have a separate value");
418 goto failed_throw;
419 }
420 else {
421 /* Normalize to raise <class>, <instance> */
422 Py_XDECREF(val);
423 val = typ;
424 typ = PyExceptionInstance_Class(typ);
425 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200426
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400427 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200428 /* Returns NULL if there's no traceback */
429 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 }
431 }
432 else {
433 /* Not something you can raise. throw() fails. */
434 PyErr_Format(PyExc_TypeError,
435 "exceptions must be classes or instances "
436 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000437 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 goto failed_throw;
439 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 PyErr_Restore(typ, val, tb);
Yury Selivanov77c96812016-02-13 17:59:05 -0500442 return gen_send_ex(gen, Py_None, 1, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000443
444failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 /* Didn't use our arguments, so restore their original refcounts */
446 Py_DECREF(typ);
447 Py_XDECREF(val);
448 Py_XDECREF(tb);
449 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000450}
451
452
453static PyObject *
454gen_iternext(PyGenObject *gen)
455{
Yury Selivanov77c96812016-02-13 17:59:05 -0500456 return gen_send_ex(gen, NULL, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000457}
458
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000459/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000460 * If StopIteration exception is set, fetches its 'value'
461 * attribute if any, otherwise sets pvalue to None.
462 *
463 * Returns 0 if no exception or StopIteration is set.
464 * If any other exception is set, returns -1 and leaves
465 * pvalue unchanged.
466 */
467
468int
Nick Coghlanc40bc092012-06-17 15:15:49 +1000469_PyGen_FetchStopIterationValue(PyObject **pvalue) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000470 PyObject *et, *ev, *tb;
471 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500472
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000473 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
474 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200475 if (ev) {
476 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300477 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200478 value = ((PyStopIterationObject *)ev)->value;
479 Py_INCREF(value);
480 Py_DECREF(ev);
481 } else if (et == PyExc_StopIteration) {
482 /* avoid normalisation and take ev as value */
483 value = ev;
484 } else {
485 /* normalisation required */
486 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300487 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200488 PyErr_Restore(et, ev, tb);
489 return -1;
490 }
491 value = ((PyStopIterationObject *)ev)->value;
492 Py_INCREF(value);
493 Py_DECREF(ev);
494 }
495 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000496 Py_XDECREF(et);
497 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000498 } else if (PyErr_Occurred()) {
499 return -1;
500 }
501 if (value == NULL) {
502 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100503 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000504 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000505 *pvalue = value;
506 return 0;
507}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000508
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000509static PyObject *
510gen_repr(PyGenObject *gen)
511{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400512 return PyUnicode_FromFormat("<generator object %S at %p>",
513 gen->gi_qualname, gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000514}
515
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000516static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200517gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000518{
Victor Stinner40ee3012014-06-16 15:59:28 +0200519 Py_INCREF(op->gi_name);
520 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000521}
522
Victor Stinner40ee3012014-06-16 15:59:28 +0200523static int
524gen_set_name(PyGenObject *op, PyObject *value)
525{
Victor Stinner40ee3012014-06-16 15:59:28 +0200526 /* Not legal to del gen.gi_name or to set it to anything
527 * other than a string object. */
528 if (value == NULL || !PyUnicode_Check(value)) {
529 PyErr_SetString(PyExc_TypeError,
530 "__name__ must be set to a string object");
531 return -1;
532 }
Victor Stinner40ee3012014-06-16 15:59:28 +0200533 Py_INCREF(value);
Serhiy Storchakaec397562016-04-06 09:50:03 +0300534 Py_XSETREF(op->gi_name, value);
Victor Stinner40ee3012014-06-16 15:59:28 +0200535 return 0;
536}
537
538static PyObject *
539gen_get_qualname(PyGenObject *op)
540{
541 Py_INCREF(op->gi_qualname);
542 return op->gi_qualname;
543}
544
545static int
546gen_set_qualname(PyGenObject *op, PyObject *value)
547{
Victor Stinner40ee3012014-06-16 15:59:28 +0200548 /* Not legal to del gen.__qualname__ or to set it to anything
549 * other than a string object. */
550 if (value == NULL || !PyUnicode_Check(value)) {
551 PyErr_SetString(PyExc_TypeError,
552 "__qualname__ must be set to a string object");
553 return -1;
554 }
Victor Stinner40ee3012014-06-16 15:59:28 +0200555 Py_INCREF(value);
Serhiy Storchakaec397562016-04-06 09:50:03 +0300556 Py_XSETREF(op->gi_qualname, value);
Victor Stinner40ee3012014-06-16 15:59:28 +0200557 return 0;
558}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000559
Yury Selivanove13f8f32015-07-03 00:23:30 -0400560static PyObject *
561gen_getyieldfrom(PyGenObject *gen)
562{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500563 PyObject *yf = _PyGen_yf(gen);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400564 if (yf == NULL)
565 Py_RETURN_NONE;
566 return yf;
567}
568
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000569static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200570 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
571 PyDoc_STR("name of the generator")},
572 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
573 PyDoc_STR("qualified name of the generator")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400574 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
575 PyDoc_STR("object being iterated by yield from, or None")},
Victor Stinner40ee3012014-06-16 15:59:28 +0200576 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000577};
578
Martin v. Löwise440e472004-06-01 15:22:42 +0000579static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200580 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
581 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
582 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000584};
585
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000586static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500587 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
589 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
590 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000591};
592
Martin v. Löwise440e472004-06-01 15:22:42 +0000593PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 PyVarObject_HEAD_INIT(&PyType_Type, 0)
595 "generator", /* tp_name */
596 sizeof(PyGenObject), /* tp_basicsize */
597 0, /* tp_itemsize */
598 /* methods */
599 (destructor)gen_dealloc, /* tp_dealloc */
600 0, /* tp_print */
601 0, /* tp_getattr */
602 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400603 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 (reprfunc)gen_repr, /* tp_repr */
605 0, /* tp_as_number */
606 0, /* tp_as_sequence */
607 0, /* tp_as_mapping */
608 0, /* tp_hash */
609 0, /* tp_call */
610 0, /* tp_str */
611 PyObject_GenericGetAttr, /* tp_getattro */
612 0, /* tp_setattro */
613 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200614 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
615 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 0, /* tp_doc */
617 (traverseproc)gen_traverse, /* tp_traverse */
618 0, /* tp_clear */
619 0, /* tp_richcompare */
620 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov5376ba92015-06-22 12:19:30 -0400621 PyObject_SelfIter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 (iternextfunc)gen_iternext, /* tp_iternext */
623 gen_methods, /* tp_methods */
624 gen_memberlist, /* tp_members */
625 gen_getsetlist, /* tp_getset */
626 0, /* tp_base */
627 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 0, /* tp_descr_get */
630 0, /* tp_descr_set */
631 0, /* tp_dictoffset */
632 0, /* tp_init */
633 0, /* tp_alloc */
634 0, /* tp_new */
635 0, /* tp_free */
636 0, /* tp_is_gc */
637 0, /* tp_bases */
638 0, /* tp_mro */
639 0, /* tp_cache */
640 0, /* tp_subclasses */
641 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200642 0, /* tp_del */
643 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200644 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000645};
646
Yury Selivanov5376ba92015-06-22 12:19:30 -0400647static PyObject *
648gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
649 PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000650{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400651 PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 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 *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400677PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
678{
679 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
680}
681
682PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200683PyGen_New(PyFrameObject *f)
684{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400685 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
Victor Stinner40ee3012014-06-16 15:59:28 +0200686}
687
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000688int
689PyGen_NeedsFinalizing(PyGenObject *gen)
690{
Antoine Pitrou93963562013-05-14 20:37:52 +0200691 int i;
692 PyFrameObject *f = gen->gi_frame;
693
694 if (f == NULL || f->f_stacktop == NULL)
695 return 0; /* no frame or empty blockstack == no finalization */
696
697 /* Any block type besides a loop requires cleanup. */
698 for (i = 0; i < f->f_iblock; i++)
699 if (f->f_blockstack[i].b_type != SETUP_LOOP)
700 return 1;
701
702 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000704}
Yury Selivanov75445082015-05-11 22:57:16 -0400705
Yury Selivanov5376ba92015-06-22 12:19:30 -0400706/* Coroutine Object */
707
708typedef struct {
709 PyObject_HEAD
710 PyCoroObject *cw_coroutine;
711} PyCoroWrapper;
712
713static int
714gen_is_coroutine(PyObject *o)
715{
716 if (PyGen_CheckExact(o)) {
717 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
718 if (code->co_flags & CO_ITERABLE_COROUTINE) {
719 return 1;
720 }
721 }
722 return 0;
723}
724
Yury Selivanov75445082015-05-11 22:57:16 -0400725/*
726 * This helper function returns an awaitable for `o`:
727 * - `o` if `o` is a coroutine-object;
728 * - `type(o)->tp_as_async->am_await(o)`
729 *
730 * Raises a TypeError if it's not possible to return
731 * an awaitable and returns NULL.
732 */
733PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400734_PyCoro_GetAwaitableIter(PyObject *o)
Yury Selivanov75445082015-05-11 22:57:16 -0400735{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400736 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400737 PyTypeObject *ot;
738
Yury Selivanov5376ba92015-06-22 12:19:30 -0400739 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
740 /* 'o' is a coroutine. */
Yury Selivanov75445082015-05-11 22:57:16 -0400741 Py_INCREF(o);
742 return o;
743 }
744
745 ot = Py_TYPE(o);
746 if (ot->tp_as_async != NULL) {
747 getter = ot->tp_as_async->am_await;
748 }
749 if (getter != NULL) {
750 PyObject *res = (*getter)(o);
751 if (res != NULL) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400752 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
753 /* __await__ must return an *iterator*, not
754 a coroutine or another awaitable (see PEP 492) */
755 PyErr_SetString(PyExc_TypeError,
756 "__await__() returned a coroutine");
757 Py_CLEAR(res);
758 } else if (!PyIter_Check(res)) {
Yury Selivanov75445082015-05-11 22:57:16 -0400759 PyErr_Format(PyExc_TypeError,
760 "__await__() returned non-iterator "
761 "of type '%.100s'",
762 Py_TYPE(res)->tp_name);
763 Py_CLEAR(res);
764 }
Yury Selivanov75445082015-05-11 22:57:16 -0400765 }
766 return res;
767 }
768
769 PyErr_Format(PyExc_TypeError,
770 "object %.100s can't be used in 'await' expression",
771 ot->tp_name);
Yury Selivanov75445082015-05-11 22:57:16 -0400772 return NULL;
773}
Yury Selivanov5376ba92015-06-22 12:19:30 -0400774
775static PyObject *
776coro_repr(PyCoroObject *coro)
777{
778 return PyUnicode_FromFormat("<coroutine object %S at %p>",
779 coro->cr_qualname, coro);
780}
781
782static PyObject *
783coro_await(PyCoroObject *coro)
784{
785 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
786 if (cw == NULL) {
787 return NULL;
788 }
789 Py_INCREF(coro);
790 cw->cw_coroutine = coro;
791 _PyObject_GC_TRACK(cw);
792 return (PyObject *)cw;
793}
794
Yury Selivanove13f8f32015-07-03 00:23:30 -0400795static PyObject *
796coro_get_cr_await(PyCoroObject *coro)
797{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500798 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400799 if (yf == NULL)
800 Py_RETURN_NONE;
801 return yf;
802}
803
Yury Selivanov5376ba92015-06-22 12:19:30 -0400804static PyGetSetDef coro_getsetlist[] = {
805 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
806 PyDoc_STR("name of the coroutine")},
807 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
808 PyDoc_STR("qualified name of the coroutine")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400809 {"cr_await", (getter)coro_get_cr_await, NULL,
810 PyDoc_STR("object being awaited on, or None")},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400811 {NULL} /* Sentinel */
812};
813
814static PyMemberDef coro_memberlist[] = {
815 {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
816 {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
817 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
818 {NULL} /* Sentinel */
819};
820
821PyDoc_STRVAR(coro_send_doc,
822"send(arg) -> send 'arg' into 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_throw_doc,
826"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400827return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400828
829PyDoc_STRVAR(coro_close_doc,
830"close() -> raise GeneratorExit inside coroutine.");
831
832static PyMethodDef coro_methods[] = {
833 {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
834 {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
835 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
836 {NULL, NULL} /* Sentinel */
837};
838
839static PyAsyncMethods coro_as_async = {
840 (unaryfunc)coro_await, /* am_await */
841 0, /* am_aiter */
842 0 /* am_anext */
843};
844
845PyTypeObject PyCoro_Type = {
846 PyVarObject_HEAD_INIT(&PyType_Type, 0)
847 "coroutine", /* tp_name */
848 sizeof(PyCoroObject), /* tp_basicsize */
849 0, /* tp_itemsize */
850 /* methods */
851 (destructor)gen_dealloc, /* tp_dealloc */
852 0, /* tp_print */
853 0, /* tp_getattr */
854 0, /* tp_setattr */
855 &coro_as_async, /* tp_as_async */
856 (reprfunc)coro_repr, /* tp_repr */
857 0, /* tp_as_number */
858 0, /* tp_as_sequence */
859 0, /* tp_as_mapping */
860 0, /* tp_hash */
861 0, /* tp_call */
862 0, /* tp_str */
863 PyObject_GenericGetAttr, /* tp_getattro */
864 0, /* tp_setattro */
865 0, /* tp_as_buffer */
866 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
867 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
868 0, /* tp_doc */
869 (traverseproc)gen_traverse, /* tp_traverse */
870 0, /* tp_clear */
871 0, /* tp_richcompare */
872 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
873 0, /* tp_iter */
874 0, /* tp_iternext */
875 coro_methods, /* tp_methods */
876 coro_memberlist, /* tp_members */
877 coro_getsetlist, /* tp_getset */
878 0, /* tp_base */
879 0, /* tp_dict */
880 0, /* tp_descr_get */
881 0, /* tp_descr_set */
882 0, /* tp_dictoffset */
883 0, /* tp_init */
884 0, /* tp_alloc */
885 0, /* tp_new */
886 0, /* tp_free */
887 0, /* tp_is_gc */
888 0, /* tp_bases */
889 0, /* tp_mro */
890 0, /* tp_cache */
891 0, /* tp_subclasses */
892 0, /* tp_weaklist */
893 0, /* tp_del */
894 0, /* tp_version_tag */
895 _PyGen_Finalize, /* tp_finalize */
896};
897
898static void
899coro_wrapper_dealloc(PyCoroWrapper *cw)
900{
901 _PyObject_GC_UNTRACK((PyObject *)cw);
902 Py_CLEAR(cw->cw_coroutine);
903 PyObject_GC_Del(cw);
904}
905
906static PyObject *
907coro_wrapper_iternext(PyCoroWrapper *cw)
908{
Yury Selivanov77c96812016-02-13 17:59:05 -0500909 return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400910}
911
912static PyObject *
913coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
914{
Yury Selivanov77c96812016-02-13 17:59:05 -0500915 return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400916}
917
918static PyObject *
919coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
920{
921 return gen_throw((PyGenObject *)cw->cw_coroutine, args);
922}
923
924static PyObject *
925coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
926{
927 return gen_close((PyGenObject *)cw->cw_coroutine, args);
928}
929
930static int
931coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
932{
933 Py_VISIT((PyObject *)cw->cw_coroutine);
934 return 0;
935}
936
937static PyMethodDef coro_wrapper_methods[] = {
Yury Selivanov66f88282015-06-24 11:04:15 -0400938 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
939 {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
940 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400941 {NULL, NULL} /* Sentinel */
942};
943
944PyTypeObject _PyCoroWrapper_Type = {
945 PyVarObject_HEAD_INIT(&PyType_Type, 0)
946 "coroutine_wrapper",
947 sizeof(PyCoroWrapper), /* tp_basicsize */
948 0, /* tp_itemsize */
949 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
950 0, /* tp_print */
951 0, /* tp_getattr */
952 0, /* tp_setattr */
953 0, /* tp_as_async */
954 0, /* tp_repr */
955 0, /* tp_as_number */
956 0, /* tp_as_sequence */
957 0, /* tp_as_mapping */
958 0, /* tp_hash */
959 0, /* tp_call */
960 0, /* tp_str */
961 PyObject_GenericGetAttr, /* tp_getattro */
962 0, /* tp_setattro */
963 0, /* tp_as_buffer */
964 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
965 "A wrapper object implementing __await__ for coroutines.",
966 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
967 0, /* tp_clear */
968 0, /* tp_richcompare */
969 0, /* tp_weaklistoffset */
970 PyObject_SelfIter, /* tp_iter */
971 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
972 coro_wrapper_methods, /* tp_methods */
973 0, /* tp_members */
974 0, /* tp_getset */
975 0, /* tp_base */
976 0, /* tp_dict */
977 0, /* tp_descr_get */
978 0, /* tp_descr_set */
979 0, /* tp_dictoffset */
980 0, /* tp_init */
981 0, /* tp_alloc */
982 0, /* tp_new */
983 PyObject_Del, /* tp_free */
984};
985
986PyObject *
987PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
988{
989 return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
990}
Yury Selivanova6f6edb2016-06-09 15:08:31 -0400991
992
993/* __aiter__ wrapper; see http://bugs.python.org/issue27243 for details. */
994
995typedef struct {
996 PyObject_HEAD
997 PyObject *aw_aiter;
998} PyAIterWrapper;
999
1000
1001static PyObject *
1002aiter_wrapper_iternext(PyAIterWrapper *aw)
1003{
1004 PyErr_SetObject(PyExc_StopIteration, aw->aw_aiter);
1005 return NULL;
1006}
1007
1008static int
1009aiter_wrapper_traverse(PyAIterWrapper *aw, visitproc visit, void *arg)
1010{
1011 Py_VISIT((PyObject *)aw->aw_aiter);
1012 return 0;
1013}
1014
1015static void
1016aiter_wrapper_dealloc(PyAIterWrapper *aw)
1017{
1018 _PyObject_GC_UNTRACK((PyObject *)aw);
1019 Py_CLEAR(aw->aw_aiter);
1020 PyObject_GC_Del(aw);
1021}
1022
1023static PyAsyncMethods aiter_wrapper_as_async = {
1024 PyObject_SelfIter, /* am_await */
1025 0, /* am_aiter */
1026 0 /* am_anext */
1027};
1028
1029PyTypeObject _PyAIterWrapper_Type = {
1030 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1031 "aiter_wrapper",
1032 sizeof(PyAIterWrapper), /* tp_basicsize */
1033 0, /* tp_itemsize */
1034 (destructor)aiter_wrapper_dealloc, /* destructor tp_dealloc */
1035 0, /* tp_print */
1036 0, /* tp_getattr */
1037 0, /* tp_setattr */
1038 &aiter_wrapper_as_async, /* tp_as_async */
1039 0, /* tp_repr */
1040 0, /* tp_as_number */
1041 0, /* tp_as_sequence */
1042 0, /* tp_as_mapping */
1043 0, /* tp_hash */
1044 0, /* tp_call */
1045 0, /* tp_str */
1046 PyObject_GenericGetAttr, /* tp_getattro */
1047 0, /* tp_setattro */
1048 0, /* tp_as_buffer */
1049 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1050 "A wrapper object for __aiter__ bakwards compatibility.",
1051 (traverseproc)aiter_wrapper_traverse, /* tp_traverse */
1052 0, /* tp_clear */
1053 0, /* tp_richcompare */
1054 0, /* tp_weaklistoffset */
1055 PyObject_SelfIter, /* tp_iter */
1056 (iternextfunc)aiter_wrapper_iternext, /* tp_iternext */
1057 0, /* tp_methods */
1058 0, /* tp_members */
1059 0, /* tp_getset */
1060 0, /* tp_base */
1061 0, /* tp_dict */
1062 0, /* tp_descr_get */
1063 0, /* tp_descr_set */
1064 0, /* tp_dictoffset */
1065 0, /* tp_init */
1066 0, /* tp_alloc */
1067 0, /* tp_new */
1068 PyObject_Del, /* tp_free */
1069};
1070
1071
1072PyObject *
1073_PyAIterWrapper_New(PyObject *aiter)
1074{
1075 PyAIterWrapper *aw = PyObject_GC_New(PyAIterWrapper,
1076 &_PyAIterWrapper_Type);
1077 if (aw == NULL) {
1078 return NULL;
1079 }
1080 Py_INCREF(aiter);
1081 aw->aw_aiter = aiter;
1082 _PyObject_GC_TRACK(aw);
1083 return (PyObject *)aw;
1084}