blob: 9172e6a01025948977c14626b89820eadf2ff83a [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;
Benjamin Petersonb88db872016-09-07 08:46:59 -070024 PyObject *res = NULL;
Antoine Pitrou796564c2013-07-30 19:59:21 +020025 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. */
Benjamin Petersonb88db872016-09-07 08:46:59 -070036 if (gen->gi_code != NULL &&
37 ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE &&
38 gen->gi_frame->f_lasti == -1) {
39 if (!error_value) {
40 PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
41 "coroutine '%.50S' was never awaited",
42 gen->gi_qualname);
43 }
Benjamin Peterson2f40ed42016-09-05 10:14:54 -070044 }
45 else {
46 res = gen_close(gen, NULL);
47 }
Antoine Pitrou796564c2013-07-30 19:59:21 +020048
Benjamin Petersonb88db872016-09-07 08:46:59 -070049 if (res == NULL) {
50 if (PyErr_Occurred())
51 PyErr_WriteUnraisable(self);
52 }
53 else {
Antoine Pitrou796564c2013-07-30 19:59:21 +020054 Py_DECREF(res);
Benjamin Petersonb88db872016-09-07 08:46:59 -070055 }
Antoine Pitrou796564c2013-07-30 19:59:21 +020056
57 /* Restore the saved exception. */
58 PyErr_Restore(error_type, error_value, error_traceback);
59}
60
61static void
Martin v. Löwise440e472004-06-01 15:22:42 +000062gen_dealloc(PyGenObject *gen)
63{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 PyObject *self = (PyObject *) gen;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 if (gen->gi_weakreflist != NULL)
69 PyObject_ClearWeakRefs(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000070
Antoine Pitrou93963562013-05-14 20:37:52 +020071 _PyObject_GC_TRACK(self);
72
Antoine Pitrou796564c2013-07-30 19:59:21 +020073 if (PyObject_CallFinalizerFromDealloc(self))
74 return; /* resurrected. :( */
Antoine Pitrou93963562013-05-14 20:37:52 +020075
76 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbdddb112016-09-05 10:39:57 -070077 if (gen->gi_frame != NULL) {
78 gen->gi_frame->f_gen = NULL;
79 Py_CLEAR(gen->gi_frame);
80 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 Py_CLEAR(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020082 Py_CLEAR(gen->gi_name);
83 Py_CLEAR(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000085}
86
87static PyObject *
Yury Selivanov77c96812016-02-13 17:59:05 -050088gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
Martin v. Löwise440e472004-06-01 15:22:42 +000089{
Antoine Pitrou93963562013-05-14 20:37:52 +020090 PyThreadState *tstate = PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +020092 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000093
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050094 if (gen->gi_running) {
Yury Selivanov5376ba92015-06-22 12:19:30 -040095 char *msg = "generator already executing";
96 if (PyCoro_CheckExact(gen))
97 msg = "coroutine already executing";
98 PyErr_SetString(PyExc_ValueError, msg);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050099 return NULL;
100 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200101 if (f == NULL || f->f_stacktop == NULL) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500102 if (PyCoro_CheckExact(gen) && !closing) {
103 /* `gen` is an exhausted coroutine: raise an error,
104 except when called from gen_close(), which should
105 always be a silent method. */
106 PyErr_SetString(
107 PyExc_RuntimeError,
108 "cannot reuse already awaited coroutine");
109 } else if (arg && !exc) {
110 /* `gen` is an exhausted generator:
111 only set exception if called from send(). */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 PyErr_SetNone(PyExc_StopIteration);
Yury Selivanov77c96812016-02-13 17:59:05 -0500113 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 return NULL;
115 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000116
Antoine Pitrou93963562013-05-14 20:37:52 +0200117 if (f->f_lasti == -1) {
118 if (arg && arg != Py_None) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400119 char *msg = "can't send non-None value to a "
120 "just-started generator";
121 if (PyCoro_CheckExact(gen))
122 msg = "can't send non-None value to a "
123 "just-started coroutine";
124 PyErr_SetString(PyExc_TypeError, msg);
Antoine Pitrou93963562013-05-14 20:37:52 +0200125 return NULL;
126 }
127 } else {
128 /* Push arg onto the frame's value stack */
129 result = arg ? arg : Py_None;
130 Py_INCREF(result);
131 *(f->f_stacktop++) = result;
132 }
133
134 /* Generators always return to their most recent caller, not
135 * necessarily their creator. */
136 Py_XINCREF(tstate->frame);
137 assert(f->f_back == NULL);
138 f->f_back = tstate->frame;
139
140 gen->gi_running = 1;
141 result = PyEval_EvalFrameEx(f, exc);
142 gen->gi_running = 0;
143
144 /* Don't keep the reference to f_back any longer than necessary. It
145 * may keep a chain of frames alive or it could create a reference
146 * cycle. */
147 assert(f->f_back == tstate->frame);
148 Py_CLEAR(f->f_back);
149
150 /* If the generator just returned (as opposed to yielding), signal
151 * that the generator is exhausted. */
152 if (result && f->f_stacktop == NULL) {
153 if (result == Py_None) {
154 /* Delay exception instantiation if we can */
155 PyErr_SetNone(PyExc_StopIteration);
156 } else {
157 PyObject *e = PyObject_CallFunctionObjArgs(
158 PyExc_StopIteration, result, NULL);
159 if (e != NULL) {
160 PyErr_SetObject(PyExc_StopIteration, e);
161 Py_DECREF(e);
162 }
163 }
164 Py_CLEAR(result);
165 }
Yury Selivanov68333392015-05-22 11:16:47 -0400166 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400167 /* Check for __future__ generator_stop and conditionally turn
168 * a leaking StopIteration into RuntimeError (with its cause
169 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400170 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400171 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400172 {
173 PyObject *exc, *val, *val2, *tb;
Yury Selivanov5376ba92015-06-22 12:19:30 -0400174 char *msg = "generator raised StopIteration";
175 if (PyCoro_CheckExact(gen))
176 msg = "coroutine raised StopIteration";
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400177 PyErr_Fetch(&exc, &val, &tb);
178 PyErr_NormalizeException(&exc, &val, &tb);
179 if (tb != NULL)
180 PyException_SetTraceback(val, tb);
181 Py_DECREF(exc);
182 Py_XDECREF(tb);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400183 PyErr_SetString(PyExc_RuntimeError, msg);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400184 PyErr_Fetch(&exc, &val2, &tb);
185 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400186 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400187 PyException_SetCause(val2, val);
188 PyException_SetContext(val2, val);
189 PyErr_Restore(exc, val2, tb);
190 }
Yury Selivanov68333392015-05-22 11:16:47 -0400191 else {
192 PyObject *exc, *val, *tb;
193
194 /* Pop the exception before issuing a warning. */
195 PyErr_Fetch(&exc, &val, &tb);
196
197 if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
198 "generator '%.50S' raised StopIteration",
199 gen->gi_qualname)) {
200 /* Warning was converted to an error. */
201 Py_XDECREF(exc);
202 Py_XDECREF(val);
203 Py_XDECREF(tb);
204 }
205 else {
206 PyErr_Restore(exc, val, tb);
207 }
208 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400209 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200210
211 if (!result || f->f_stacktop == NULL) {
212 /* generator can't be rerun, so release the frame */
213 /* first clean reference cycle through stored exception traceback */
214 PyObject *t, *v, *tb;
215 t = f->f_exc_type;
216 v = f->f_exc_value;
217 tb = f->f_exc_traceback;
218 f->f_exc_type = NULL;
219 f->f_exc_value = NULL;
220 f->f_exc_traceback = NULL;
221 Py_XDECREF(t);
222 Py_XDECREF(v);
223 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200224 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200225 gen->gi_frame = NULL;
226 Py_DECREF(f);
227 }
228
229 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000230}
231
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000232PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000233"send(arg) -> send 'arg' into generator,\n\
234return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000235
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500236PyObject *
237_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000238{
Yury Selivanov77c96812016-02-13 17:59:05 -0500239 return gen_send_ex(gen, arg, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000240}
241
242PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400243"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000244
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000245/*
246 * This helper function is used by gen_close and gen_throw to
247 * close a subiterator being delegated to by yield-from.
248 */
249
Antoine Pitrou93963562013-05-14 20:37:52 +0200250static int
251gen_close_iter(PyObject *yf)
252{
253 PyObject *retval = NULL;
254 _Py_IDENTIFIER(close);
255
256 if (PyGen_CheckExact(yf)) {
257 retval = gen_close((PyGenObject *)yf, NULL);
258 if (retval == NULL)
259 return -1;
260 } else {
261 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
262 if (meth == NULL) {
263 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
264 PyErr_WriteUnraisable(yf);
265 PyErr_Clear();
266 } else {
267 retval = PyObject_CallFunction(meth, "");
268 Py_DECREF(meth);
269 if (retval == NULL)
270 return -1;
271 }
272 }
273 Py_XDECREF(retval);
274 return 0;
275}
276
Yury Selivanovc724bae2016-03-02 11:30:46 -0500277PyObject *
278_PyGen_yf(PyGenObject *gen)
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500279{
Antoine Pitrou93963562013-05-14 20:37:52 +0200280 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500281 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200282
283 if (f && f->f_stacktop) {
284 PyObject *bytecode = f->f_code->co_code;
285 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
286
287 if (code[f->f_lasti + 1] != YIELD_FROM)
288 return NULL;
289 yf = f->f_stacktop[-1];
290 Py_INCREF(yf);
291 }
292
293 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500294}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000295
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000296static PyObject *
297gen_close(PyGenObject *gen, PyObject *args)
298{
Antoine Pitrou93963562013-05-14 20:37:52 +0200299 PyObject *retval;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500300 PyObject *yf = _PyGen_yf(gen);
Antoine Pitrou93963562013-05-14 20:37:52 +0200301 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000302
Antoine Pitrou93963562013-05-14 20:37:52 +0200303 if (yf) {
304 gen->gi_running = 1;
305 err = gen_close_iter(yf);
306 gen->gi_running = 0;
307 Py_DECREF(yf);
308 }
309 if (err == 0)
310 PyErr_SetNone(PyExc_GeneratorExit);
Yury Selivanov77c96812016-02-13 17:59:05 -0500311 retval = gen_send_ex(gen, Py_None, 1, 1);
Antoine Pitrou93963562013-05-14 20:37:52 +0200312 if (retval) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400313 char *msg = "generator ignored GeneratorExit";
314 if (PyCoro_CheckExact(gen))
315 msg = "coroutine ignored GeneratorExit";
Antoine Pitrou93963562013-05-14 20:37:52 +0200316 Py_DECREF(retval);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400317 PyErr_SetString(PyExc_RuntimeError, msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 return NULL;
319 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200320 if (PyErr_ExceptionMatches(PyExc_StopIteration)
321 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
322 PyErr_Clear(); /* ignore these errors */
323 Py_INCREF(Py_None);
324 return Py_None;
325 }
326 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000327}
328
Antoine Pitrou93963562013-05-14 20:37:52 +0200329
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000330PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
332return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000333
334static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 PyObject *typ;
338 PyObject *tb = NULL;
339 PyObject *val = NULL;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500340 PyObject *yf = _PyGen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000341 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
344 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000345
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000346 if (yf) {
347 PyObject *ret;
348 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000349 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500350 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200351 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500352 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000353 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000354 if (err < 0)
Yury Selivanov77c96812016-02-13 17:59:05 -0500355 return gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000356 goto throw_here;
357 }
358 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500359 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000360 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500361 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000362 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000363 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000364 if (meth == NULL) {
365 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
366 Py_DECREF(yf);
367 return NULL;
368 }
369 PyErr_Clear();
370 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000371 goto throw_here;
372 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500373 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000374 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500375 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000376 Py_DECREF(meth);
377 }
378 Py_DECREF(yf);
379 if (!ret) {
380 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500381 /* Pop subiterator from stack */
382 ret = *(--gen->gi_frame->f_stacktop);
383 assert(ret == yf);
384 Py_DECREF(ret);
385 /* Termination repetition of YIELD_FROM */
386 gen->gi_frame->f_lasti++;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000387 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500388 ret = gen_send_ex(gen, val, 0, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000389 Py_DECREF(val);
390 } else {
Yury Selivanov77c96812016-02-13 17:59:05 -0500391 ret = gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000392 }
393 }
394 return ret;
395 }
396
397throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 /* First, check the traceback argument, replacing None with
399 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400400 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400402 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 else if (tb != NULL && !PyTraceBack_Check(tb)) {
404 PyErr_SetString(PyExc_TypeError,
405 "throw() third argument must be a traceback object");
406 return NULL;
407 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 Py_INCREF(typ);
410 Py_XINCREF(val);
411 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000412
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400413 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 else if (PyExceptionInstance_Check(typ)) {
417 /* Raising an instance. The value should be a dummy. */
418 if (val && val != Py_None) {
419 PyErr_SetString(PyExc_TypeError,
420 "instance exception may not have a separate value");
421 goto failed_throw;
422 }
423 else {
424 /* Normalize to raise <class>, <instance> */
425 Py_XDECREF(val);
426 val = typ;
427 typ = PyExceptionInstance_Class(typ);
428 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200429
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400430 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200431 /* Returns NULL if there's no traceback */
432 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 }
434 }
435 else {
436 /* Not something you can raise. throw() fails. */
437 PyErr_Format(PyExc_TypeError,
438 "exceptions must be classes or instances "
439 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000440 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 goto failed_throw;
442 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 PyErr_Restore(typ, val, tb);
Yury Selivanov77c96812016-02-13 17:59:05 -0500445 return gen_send_ex(gen, Py_None, 1, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000446
447failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 /* Didn't use our arguments, so restore their original refcounts */
449 Py_DECREF(typ);
450 Py_XDECREF(val);
451 Py_XDECREF(tb);
452 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000453}
454
455
456static PyObject *
457gen_iternext(PyGenObject *gen)
458{
Yury Selivanov77c96812016-02-13 17:59:05 -0500459 return gen_send_ex(gen, NULL, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000460}
461
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000462/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000463 * If StopIteration exception is set, fetches its 'value'
464 * attribute if any, otherwise sets pvalue to None.
465 *
466 * Returns 0 if no exception or StopIteration is set.
467 * If any other exception is set, returns -1 and leaves
468 * pvalue unchanged.
469 */
470
471int
Nick Coghlanc40bc092012-06-17 15:15:49 +1000472_PyGen_FetchStopIterationValue(PyObject **pvalue) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000473 PyObject *et, *ev, *tb;
474 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500475
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000476 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
477 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200478 if (ev) {
479 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300480 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200481 value = ((PyStopIterationObject *)ev)->value;
482 Py_INCREF(value);
483 Py_DECREF(ev);
484 } else if (et == PyExc_StopIteration) {
485 /* avoid normalisation and take ev as value */
486 value = ev;
487 } else {
488 /* normalisation required */
489 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300490 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200491 PyErr_Restore(et, ev, tb);
492 return -1;
493 }
494 value = ((PyStopIterationObject *)ev)->value;
495 Py_INCREF(value);
496 Py_DECREF(ev);
497 }
498 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000499 Py_XDECREF(et);
500 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000501 } else if (PyErr_Occurred()) {
502 return -1;
503 }
504 if (value == NULL) {
505 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100506 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000507 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000508 *pvalue = value;
509 return 0;
510}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000511
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000512static PyObject *
513gen_repr(PyGenObject *gen)
514{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400515 return PyUnicode_FromFormat("<generator object %S at %p>",
516 gen->gi_qualname, gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000517}
518
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000519static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200520gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000521{
Victor Stinner40ee3012014-06-16 15:59:28 +0200522 Py_INCREF(op->gi_name);
523 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000524}
525
Victor Stinner40ee3012014-06-16 15:59:28 +0200526static int
527gen_set_name(PyGenObject *op, PyObject *value)
528{
529 PyObject *tmp;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000530
Victor Stinner40ee3012014-06-16 15:59:28 +0200531 /* Not legal to del gen.gi_name or to set it to anything
532 * other than a string object. */
533 if (value == NULL || !PyUnicode_Check(value)) {
534 PyErr_SetString(PyExc_TypeError,
535 "__name__ must be set to a string object");
536 return -1;
537 }
538 tmp = op->gi_name;
539 Py_INCREF(value);
540 op->gi_name = value;
541 Py_DECREF(tmp);
542 return 0;
543}
544
545static PyObject *
546gen_get_qualname(PyGenObject *op)
547{
548 Py_INCREF(op->gi_qualname);
549 return op->gi_qualname;
550}
551
552static int
553gen_set_qualname(PyGenObject *op, PyObject *value)
554{
555 PyObject *tmp;
556
557 /* Not legal to del gen.__qualname__ or to set it to anything
558 * other than a string object. */
559 if (value == NULL || !PyUnicode_Check(value)) {
560 PyErr_SetString(PyExc_TypeError,
561 "__qualname__ must be set to a string object");
562 return -1;
563 }
564 tmp = op->gi_qualname;
565 Py_INCREF(value);
566 op->gi_qualname = value;
567 Py_DECREF(tmp);
568 return 0;
569}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000570
Yury Selivanove13f8f32015-07-03 00:23:30 -0400571static PyObject *
572gen_getyieldfrom(PyGenObject *gen)
573{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500574 PyObject *yf = _PyGen_yf(gen);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400575 if (yf == NULL)
576 Py_RETURN_NONE;
577 return yf;
578}
579
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000580static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200581 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
582 PyDoc_STR("name of the generator")},
583 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
584 PyDoc_STR("qualified name of the generator")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400585 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
586 PyDoc_STR("object being iterated by yield from, or None")},
Victor Stinner40ee3012014-06-16 15:59:28 +0200587 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000588};
589
Martin v. Löwise440e472004-06-01 15:22:42 +0000590static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200591 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
592 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
593 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000595};
596
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000597static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500598 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
600 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
601 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000602};
603
Martin v. Löwise440e472004-06-01 15:22:42 +0000604PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 PyVarObject_HEAD_INIT(&PyType_Type, 0)
606 "generator", /* tp_name */
607 sizeof(PyGenObject), /* tp_basicsize */
608 0, /* tp_itemsize */
609 /* methods */
610 (destructor)gen_dealloc, /* tp_dealloc */
611 0, /* tp_print */
612 0, /* tp_getattr */
613 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400614 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 (reprfunc)gen_repr, /* tp_repr */
616 0, /* tp_as_number */
617 0, /* tp_as_sequence */
618 0, /* tp_as_mapping */
619 0, /* tp_hash */
620 0, /* tp_call */
621 0, /* tp_str */
622 PyObject_GenericGetAttr, /* tp_getattro */
623 0, /* tp_setattro */
624 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200625 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
626 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 0, /* tp_doc */
628 (traverseproc)gen_traverse, /* tp_traverse */
629 0, /* tp_clear */
630 0, /* tp_richcompare */
631 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov5376ba92015-06-22 12:19:30 -0400632 PyObject_SelfIter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 (iternextfunc)gen_iternext, /* tp_iternext */
634 gen_methods, /* tp_methods */
635 gen_memberlist, /* tp_members */
636 gen_getsetlist, /* tp_getset */
637 0, /* tp_base */
638 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 0, /* tp_descr_get */
641 0, /* tp_descr_set */
642 0, /* tp_dictoffset */
643 0, /* tp_init */
644 0, /* tp_alloc */
645 0, /* tp_new */
646 0, /* tp_free */
647 0, /* tp_is_gc */
648 0, /* tp_bases */
649 0, /* tp_mro */
650 0, /* tp_cache */
651 0, /* tp_subclasses */
652 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200653 0, /* tp_del */
654 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200655 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000656};
657
Yury Selivanov5376ba92015-06-22 12:19:30 -0400658static PyObject *
659gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
660 PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000661{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400662 PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 if (gen == NULL) {
664 Py_DECREF(f);
665 return NULL;
666 }
667 gen->gi_frame = f;
Antoine Pitrou58720d62013-08-05 23:26:40 +0200668 f->f_gen = (PyObject *) gen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 Py_INCREF(f->f_code);
670 gen->gi_code = (PyObject *)(f->f_code);
671 gen->gi_running = 0;
672 gen->gi_weakreflist = NULL;
Victor Stinner40ee3012014-06-16 15:59:28 +0200673 if (name != NULL)
674 gen->gi_name = name;
675 else
676 gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;
677 Py_INCREF(gen->gi_name);
678 if (qualname != NULL)
679 gen->gi_qualname = qualname;
680 else
681 gen->gi_qualname = gen->gi_name;
682 Py_INCREF(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 _PyObject_GC_TRACK(gen);
684 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000685}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000686
Victor Stinner40ee3012014-06-16 15:59:28 +0200687PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400688PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
689{
690 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
691}
692
693PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200694PyGen_New(PyFrameObject *f)
695{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400696 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
Victor Stinner40ee3012014-06-16 15:59:28 +0200697}
698
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000699int
700PyGen_NeedsFinalizing(PyGenObject *gen)
701{
Antoine Pitrou93963562013-05-14 20:37:52 +0200702 int i;
703 PyFrameObject *f = gen->gi_frame;
704
705 if (f == NULL || f->f_stacktop == NULL)
706 return 0; /* no frame or empty blockstack == no finalization */
707
708 /* Any block type besides a loop requires cleanup. */
709 for (i = 0; i < f->f_iblock; i++)
710 if (f->f_blockstack[i].b_type != SETUP_LOOP)
711 return 1;
712
713 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000715}
Yury Selivanov75445082015-05-11 22:57:16 -0400716
Yury Selivanov5376ba92015-06-22 12:19:30 -0400717/* Coroutine Object */
718
719typedef struct {
720 PyObject_HEAD
721 PyCoroObject *cw_coroutine;
722} PyCoroWrapper;
723
724static int
725gen_is_coroutine(PyObject *o)
726{
727 if (PyGen_CheckExact(o)) {
728 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
729 if (code->co_flags & CO_ITERABLE_COROUTINE) {
730 return 1;
731 }
732 }
733 return 0;
734}
735
Yury Selivanov75445082015-05-11 22:57:16 -0400736/*
737 * This helper function returns an awaitable for `o`:
738 * - `o` if `o` is a coroutine-object;
739 * - `type(o)->tp_as_async->am_await(o)`
740 *
741 * Raises a TypeError if it's not possible to return
742 * an awaitable and returns NULL.
743 */
744PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400745_PyCoro_GetAwaitableIter(PyObject *o)
Yury Selivanov75445082015-05-11 22:57:16 -0400746{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400747 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400748 PyTypeObject *ot;
749
Yury Selivanov5376ba92015-06-22 12:19:30 -0400750 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
751 /* 'o' is a coroutine. */
Yury Selivanov75445082015-05-11 22:57:16 -0400752 Py_INCREF(o);
753 return o;
754 }
755
756 ot = Py_TYPE(o);
757 if (ot->tp_as_async != NULL) {
758 getter = ot->tp_as_async->am_await;
759 }
760 if (getter != NULL) {
761 PyObject *res = (*getter)(o);
762 if (res != NULL) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400763 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
764 /* __await__ must return an *iterator*, not
765 a coroutine or another awaitable (see PEP 492) */
766 PyErr_SetString(PyExc_TypeError,
767 "__await__() returned a coroutine");
768 Py_CLEAR(res);
769 } else if (!PyIter_Check(res)) {
Yury Selivanov75445082015-05-11 22:57:16 -0400770 PyErr_Format(PyExc_TypeError,
771 "__await__() returned non-iterator "
772 "of type '%.100s'",
773 Py_TYPE(res)->tp_name);
774 Py_CLEAR(res);
775 }
Yury Selivanov75445082015-05-11 22:57:16 -0400776 }
777 return res;
778 }
779
780 PyErr_Format(PyExc_TypeError,
781 "object %.100s can't be used in 'await' expression",
782 ot->tp_name);
Yury Selivanov75445082015-05-11 22:57:16 -0400783 return NULL;
784}
Yury Selivanov5376ba92015-06-22 12:19:30 -0400785
786static PyObject *
787coro_repr(PyCoroObject *coro)
788{
789 return PyUnicode_FromFormat("<coroutine object %S at %p>",
790 coro->cr_qualname, coro);
791}
792
793static PyObject *
794coro_await(PyCoroObject *coro)
795{
796 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
797 if (cw == NULL) {
798 return NULL;
799 }
800 Py_INCREF(coro);
801 cw->cw_coroutine = coro;
802 _PyObject_GC_TRACK(cw);
803 return (PyObject *)cw;
804}
805
Yury Selivanove13f8f32015-07-03 00:23:30 -0400806static PyObject *
807coro_get_cr_await(PyCoroObject *coro)
808{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500809 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400810 if (yf == NULL)
811 Py_RETURN_NONE;
812 return yf;
813}
814
Yury Selivanov5376ba92015-06-22 12:19:30 -0400815static PyGetSetDef coro_getsetlist[] = {
816 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
817 PyDoc_STR("name of the coroutine")},
818 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
819 PyDoc_STR("qualified name of the coroutine")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400820 {"cr_await", (getter)coro_get_cr_await, NULL,
821 PyDoc_STR("object being awaited on, or None")},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400822 {NULL} /* Sentinel */
823};
824
825static PyMemberDef coro_memberlist[] = {
826 {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
827 {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
828 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
829 {NULL} /* Sentinel */
830};
831
832PyDoc_STRVAR(coro_send_doc,
833"send(arg) -> send 'arg' into coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400834return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400835
836PyDoc_STRVAR(coro_throw_doc,
837"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400838return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400839
840PyDoc_STRVAR(coro_close_doc,
841"close() -> raise GeneratorExit inside coroutine.");
842
843static PyMethodDef coro_methods[] = {
844 {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
845 {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
846 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
847 {NULL, NULL} /* Sentinel */
848};
849
850static PyAsyncMethods coro_as_async = {
851 (unaryfunc)coro_await, /* am_await */
852 0, /* am_aiter */
853 0 /* am_anext */
854};
855
856PyTypeObject PyCoro_Type = {
857 PyVarObject_HEAD_INIT(&PyType_Type, 0)
858 "coroutine", /* tp_name */
859 sizeof(PyCoroObject), /* tp_basicsize */
860 0, /* tp_itemsize */
861 /* methods */
862 (destructor)gen_dealloc, /* tp_dealloc */
863 0, /* tp_print */
864 0, /* tp_getattr */
865 0, /* tp_setattr */
866 &coro_as_async, /* tp_as_async */
867 (reprfunc)coro_repr, /* tp_repr */
868 0, /* tp_as_number */
869 0, /* tp_as_sequence */
870 0, /* tp_as_mapping */
871 0, /* tp_hash */
872 0, /* tp_call */
873 0, /* tp_str */
874 PyObject_GenericGetAttr, /* tp_getattro */
875 0, /* tp_setattro */
876 0, /* tp_as_buffer */
877 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
878 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
879 0, /* tp_doc */
880 (traverseproc)gen_traverse, /* tp_traverse */
881 0, /* tp_clear */
882 0, /* tp_richcompare */
883 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
884 0, /* tp_iter */
885 0, /* tp_iternext */
886 coro_methods, /* tp_methods */
887 coro_memberlist, /* tp_members */
888 coro_getsetlist, /* tp_getset */
889 0, /* tp_base */
890 0, /* tp_dict */
891 0, /* tp_descr_get */
892 0, /* tp_descr_set */
893 0, /* tp_dictoffset */
894 0, /* tp_init */
895 0, /* tp_alloc */
896 0, /* tp_new */
897 0, /* tp_free */
898 0, /* tp_is_gc */
899 0, /* tp_bases */
900 0, /* tp_mro */
901 0, /* tp_cache */
902 0, /* tp_subclasses */
903 0, /* tp_weaklist */
904 0, /* tp_del */
905 0, /* tp_version_tag */
906 _PyGen_Finalize, /* tp_finalize */
907};
908
909static void
910coro_wrapper_dealloc(PyCoroWrapper *cw)
911{
912 _PyObject_GC_UNTRACK((PyObject *)cw);
913 Py_CLEAR(cw->cw_coroutine);
914 PyObject_GC_Del(cw);
915}
916
917static PyObject *
918coro_wrapper_iternext(PyCoroWrapper *cw)
919{
Yury Selivanov77c96812016-02-13 17:59:05 -0500920 return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400921}
922
923static PyObject *
924coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
925{
Yury Selivanov77c96812016-02-13 17:59:05 -0500926 return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400927}
928
929static PyObject *
930coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
931{
932 return gen_throw((PyGenObject *)cw->cw_coroutine, args);
933}
934
935static PyObject *
936coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
937{
938 return gen_close((PyGenObject *)cw->cw_coroutine, args);
939}
940
941static int
942coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
943{
944 Py_VISIT((PyObject *)cw->cw_coroutine);
945 return 0;
946}
947
948static PyMethodDef coro_wrapper_methods[] = {
Yury Selivanov66f88282015-06-24 11:04:15 -0400949 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
950 {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
951 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400952 {NULL, NULL} /* Sentinel */
953};
954
955PyTypeObject _PyCoroWrapper_Type = {
956 PyVarObject_HEAD_INIT(&PyType_Type, 0)
957 "coroutine_wrapper",
958 sizeof(PyCoroWrapper), /* tp_basicsize */
959 0, /* tp_itemsize */
960 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
961 0, /* tp_print */
962 0, /* tp_getattr */
963 0, /* tp_setattr */
964 0, /* tp_as_async */
965 0, /* tp_repr */
966 0, /* tp_as_number */
967 0, /* tp_as_sequence */
968 0, /* tp_as_mapping */
969 0, /* tp_hash */
970 0, /* tp_call */
971 0, /* tp_str */
972 PyObject_GenericGetAttr, /* tp_getattro */
973 0, /* tp_setattro */
974 0, /* tp_as_buffer */
975 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
976 "A wrapper object implementing __await__ for coroutines.",
977 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
978 0, /* tp_clear */
979 0, /* tp_richcompare */
980 0, /* tp_weaklistoffset */
981 PyObject_SelfIter, /* tp_iter */
982 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
983 coro_wrapper_methods, /* tp_methods */
984 0, /* tp_members */
985 0, /* tp_getset */
986 0, /* tp_base */
987 0, /* tp_dict */
988 0, /* tp_descr_get */
989 0, /* tp_descr_set */
990 0, /* tp_dictoffset */
991 0, /* tp_init */
992 0, /* tp_alloc */
993 0, /* tp_new */
994 PyObject_Del, /* tp_free */
995};
996
997PyObject *
998PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
999{
1000 return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
1001}
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001002
1003
1004/* __aiter__ wrapper; see http://bugs.python.org/issue27243 for details. */
1005
1006typedef struct {
1007 PyObject_HEAD
1008 PyObject *aw_aiter;
1009} PyAIterWrapper;
1010
1011
1012static PyObject *
1013aiter_wrapper_iternext(PyAIterWrapper *aw)
1014{
1015 PyErr_SetObject(PyExc_StopIteration, aw->aw_aiter);
1016 return NULL;
1017}
1018
1019static int
1020aiter_wrapper_traverse(PyAIterWrapper *aw, visitproc visit, void *arg)
1021{
1022 Py_VISIT((PyObject *)aw->aw_aiter);
1023 return 0;
1024}
1025
1026static void
1027aiter_wrapper_dealloc(PyAIterWrapper *aw)
1028{
1029 _PyObject_GC_UNTRACK((PyObject *)aw);
1030 Py_CLEAR(aw->aw_aiter);
1031 PyObject_GC_Del(aw);
1032}
1033
1034static PyAsyncMethods aiter_wrapper_as_async = {
1035 PyObject_SelfIter, /* am_await */
1036 0, /* am_aiter */
1037 0 /* am_anext */
1038};
1039
1040PyTypeObject _PyAIterWrapper_Type = {
1041 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1042 "aiter_wrapper",
1043 sizeof(PyAIterWrapper), /* tp_basicsize */
1044 0, /* tp_itemsize */
1045 (destructor)aiter_wrapper_dealloc, /* destructor tp_dealloc */
1046 0, /* tp_print */
1047 0, /* tp_getattr */
1048 0, /* tp_setattr */
1049 &aiter_wrapper_as_async, /* tp_as_async */
1050 0, /* tp_repr */
1051 0, /* tp_as_number */
1052 0, /* tp_as_sequence */
1053 0, /* tp_as_mapping */
1054 0, /* tp_hash */
1055 0, /* tp_call */
1056 0, /* tp_str */
1057 PyObject_GenericGetAttr, /* tp_getattro */
1058 0, /* tp_setattro */
1059 0, /* tp_as_buffer */
1060 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1061 "A wrapper object for __aiter__ bakwards compatibility.",
1062 (traverseproc)aiter_wrapper_traverse, /* tp_traverse */
1063 0, /* tp_clear */
1064 0, /* tp_richcompare */
1065 0, /* tp_weaklistoffset */
1066 PyObject_SelfIter, /* tp_iter */
1067 (iternextfunc)aiter_wrapper_iternext, /* tp_iternext */
1068 0, /* tp_methods */
1069 0, /* tp_members */
1070 0, /* tp_getset */
1071 0, /* tp_base */
1072 0, /* tp_dict */
1073 0, /* tp_descr_get */
1074 0, /* tp_descr_set */
1075 0, /* tp_dictoffset */
1076 0, /* tp_init */
1077 0, /* tp_alloc */
1078 0, /* tp_new */
1079 PyObject_Del, /* tp_free */
1080};
1081
1082
1083PyObject *
1084_PyAIterWrapper_New(PyObject *aiter)
1085{
1086 PyAIterWrapper *aw = PyObject_GC_New(PyAIterWrapper,
1087 &_PyAIterWrapper_Type);
1088 if (aw == NULL) {
1089 return NULL;
1090 }
1091 Py_INCREF(aiter);
1092 aw->aw_aiter = aiter;
1093 _PyObject_GC_TRACK(aw);
1094 return (PyObject *)aw;
1095}