blob: 0d5d54fdbafcd4bbc87b7615122ca6906c3e0b51 [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 {
Serhiy Storchaka24411f82016-11-06 18:44:42 +0200157 _PyGen_SetStopIterationValue(result);
Antoine Pitrou93963562013-05-14 20:37:52 +0200158 }
159 Py_CLEAR(result);
160 }
Yury Selivanov68333392015-05-22 11:16:47 -0400161 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400162 /* Check for __future__ generator_stop and conditionally turn
163 * a leaking StopIteration into RuntimeError (with its cause
164 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400165 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400166 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400167 {
168 PyObject *exc, *val, *val2, *tb;
Yury Selivanov5376ba92015-06-22 12:19:30 -0400169 char *msg = "generator raised StopIteration";
170 if (PyCoro_CheckExact(gen))
171 msg = "coroutine raised StopIteration";
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400172 PyErr_Fetch(&exc, &val, &tb);
173 PyErr_NormalizeException(&exc, &val, &tb);
174 if (tb != NULL)
175 PyException_SetTraceback(val, tb);
176 Py_DECREF(exc);
177 Py_XDECREF(tb);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400178 PyErr_SetString(PyExc_RuntimeError, msg);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400179 PyErr_Fetch(&exc, &val2, &tb);
180 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400181 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400182 PyException_SetCause(val2, val);
183 PyException_SetContext(val2, val);
184 PyErr_Restore(exc, val2, tb);
185 }
Yury Selivanov68333392015-05-22 11:16:47 -0400186 else {
187 PyObject *exc, *val, *tb;
188
189 /* Pop the exception before issuing a warning. */
190 PyErr_Fetch(&exc, &val, &tb);
191
192 if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
193 "generator '%.50S' raised StopIteration",
194 gen->gi_qualname)) {
195 /* Warning was converted to an error. */
196 Py_XDECREF(exc);
197 Py_XDECREF(val);
198 Py_XDECREF(tb);
199 }
200 else {
201 PyErr_Restore(exc, val, tb);
202 }
203 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400204 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200205
206 if (!result || f->f_stacktop == NULL) {
207 /* generator can't be rerun, so release the frame */
208 /* first clean reference cycle through stored exception traceback */
209 PyObject *t, *v, *tb;
210 t = f->f_exc_type;
211 v = f->f_exc_value;
212 tb = f->f_exc_traceback;
213 f->f_exc_type = NULL;
214 f->f_exc_value = NULL;
215 f->f_exc_traceback = NULL;
216 Py_XDECREF(t);
217 Py_XDECREF(v);
218 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200219 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200220 gen->gi_frame = NULL;
221 Py_DECREF(f);
222 }
223
224 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000225}
226
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000227PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000228"send(arg) -> send 'arg' into generator,\n\
229return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000230
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500231PyObject *
232_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000233{
Yury Selivanov77c96812016-02-13 17:59:05 -0500234 return gen_send_ex(gen, arg, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000235}
236
237PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400238"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000239
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000240/*
241 * This helper function is used by gen_close and gen_throw to
242 * close a subiterator being delegated to by yield-from.
243 */
244
Antoine Pitrou93963562013-05-14 20:37:52 +0200245static int
246gen_close_iter(PyObject *yf)
247{
248 PyObject *retval = NULL;
249 _Py_IDENTIFIER(close);
250
251 if (PyGen_CheckExact(yf)) {
252 retval = gen_close((PyGenObject *)yf, NULL);
253 if (retval == NULL)
254 return -1;
255 } else {
256 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
257 if (meth == NULL) {
258 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
259 PyErr_WriteUnraisable(yf);
260 PyErr_Clear();
261 } else {
262 retval = PyObject_CallFunction(meth, "");
263 Py_DECREF(meth);
264 if (retval == NULL)
265 return -1;
266 }
267 }
268 Py_XDECREF(retval);
269 return 0;
270}
271
Yury Selivanovc724bae2016-03-02 11:30:46 -0500272PyObject *
273_PyGen_yf(PyGenObject *gen)
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500274{
Antoine Pitrou93963562013-05-14 20:37:52 +0200275 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500276 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200277
278 if (f && f->f_stacktop) {
279 PyObject *bytecode = f->f_code->co_code;
280 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
281
282 if (code[f->f_lasti + 1] != YIELD_FROM)
283 return NULL;
284 yf = f->f_stacktop[-1];
285 Py_INCREF(yf);
286 }
287
288 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500289}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000290
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000291static PyObject *
292gen_close(PyGenObject *gen, PyObject *args)
293{
Antoine Pitrou93963562013-05-14 20:37:52 +0200294 PyObject *retval;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500295 PyObject *yf = _PyGen_yf(gen);
Antoine Pitrou93963562013-05-14 20:37:52 +0200296 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000297
Antoine Pitrou93963562013-05-14 20:37:52 +0200298 if (yf) {
299 gen->gi_running = 1;
300 err = gen_close_iter(yf);
301 gen->gi_running = 0;
302 Py_DECREF(yf);
303 }
304 if (err == 0)
305 PyErr_SetNone(PyExc_GeneratorExit);
Yury Selivanov77c96812016-02-13 17:59:05 -0500306 retval = gen_send_ex(gen, Py_None, 1, 1);
Antoine Pitrou93963562013-05-14 20:37:52 +0200307 if (retval) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400308 char *msg = "generator ignored GeneratorExit";
309 if (PyCoro_CheckExact(gen))
310 msg = "coroutine ignored GeneratorExit";
Antoine Pitrou93963562013-05-14 20:37:52 +0200311 Py_DECREF(retval);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400312 PyErr_SetString(PyExc_RuntimeError, msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 return NULL;
314 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200315 if (PyErr_ExceptionMatches(PyExc_StopIteration)
316 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
317 PyErr_Clear(); /* ignore these errors */
318 Py_INCREF(Py_None);
319 return Py_None;
320 }
321 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000322}
323
Antoine Pitrou93963562013-05-14 20:37:52 +0200324
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000325PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
327return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000328
329static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000330gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 PyObject *typ;
333 PyObject *tb = NULL;
334 PyObject *val = NULL;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500335 PyObject *yf = _PyGen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000336 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
339 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000340
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000341 if (yf) {
342 PyObject *ret;
343 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000344 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500345 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200346 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500347 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000348 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000349 if (err < 0)
Yury Selivanov77c96812016-02-13 17:59:05 -0500350 return gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000351 goto throw_here;
352 }
353 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500354 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000355 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500356 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000357 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000358 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000359 if (meth == NULL) {
360 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
361 Py_DECREF(yf);
362 return NULL;
363 }
364 PyErr_Clear();
365 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000366 goto throw_here;
367 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500368 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000369 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500370 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000371 Py_DECREF(meth);
372 }
373 Py_DECREF(yf);
374 if (!ret) {
375 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500376 /* Pop subiterator from stack */
377 ret = *(--gen->gi_frame->f_stacktop);
378 assert(ret == yf);
379 Py_DECREF(ret);
380 /* Termination repetition of YIELD_FROM */
381 gen->gi_frame->f_lasti++;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000382 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500383 ret = gen_send_ex(gen, val, 0, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000384 Py_DECREF(val);
385 } else {
Yury Selivanov77c96812016-02-13 17:59:05 -0500386 ret = gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000387 }
388 }
389 return ret;
390 }
391
392throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 /* First, check the traceback argument, replacing None with
394 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400395 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400397 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 else if (tb != NULL && !PyTraceBack_Check(tb)) {
399 PyErr_SetString(PyExc_TypeError,
400 "throw() third argument must be a traceback object");
401 return NULL;
402 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 Py_INCREF(typ);
405 Py_XINCREF(val);
406 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000407
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400408 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 else if (PyExceptionInstance_Check(typ)) {
412 /* Raising an instance. The value should be a dummy. */
413 if (val && val != Py_None) {
414 PyErr_SetString(PyExc_TypeError,
415 "instance exception may not have a separate value");
416 goto failed_throw;
417 }
418 else {
419 /* Normalize to raise <class>, <instance> */
420 Py_XDECREF(val);
421 val = typ;
422 typ = PyExceptionInstance_Class(typ);
423 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200424
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400425 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200426 /* Returns NULL if there's no traceback */
427 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 }
429 }
430 else {
431 /* Not something you can raise. throw() fails. */
432 PyErr_Format(PyExc_TypeError,
433 "exceptions must be classes or instances "
434 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000435 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 goto failed_throw;
437 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 PyErr_Restore(typ, val, tb);
Yury Selivanov77c96812016-02-13 17:59:05 -0500440 return gen_send_ex(gen, Py_None, 1, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000441
442failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 /* Didn't use our arguments, so restore their original refcounts */
444 Py_DECREF(typ);
445 Py_XDECREF(val);
446 Py_XDECREF(tb);
447 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000448}
449
450
451static PyObject *
452gen_iternext(PyGenObject *gen)
453{
Yury Selivanov77c96812016-02-13 17:59:05 -0500454 return gen_send_ex(gen, NULL, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000455}
456
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000457/*
Serhiy Storchaka24411f82016-11-06 18:44:42 +0200458 * Set StopIteration with specified value. Value can be arbitrary object
459 * or NULL.
460 *
461 * Returns 0 if StopIteration is set and -1 if any other exception is set.
462 */
463int
464_PyGen_SetStopIterationValue(PyObject *value)
465{
466 PyObject *e;
467
468 if (value == NULL ||
469 (!PyTuple_Check(value) &&
470 !PyObject_TypeCheck(value, (PyTypeObject *) PyExc_StopIteration)))
471 {
472 /* Delay exception instantiation if we can */
473 PyErr_SetObject(PyExc_StopIteration, value);
474 return 0;
475 }
476 /* Construct an exception instance manually with
477 * PyObject_CallFunctionObjArgs and pass it to PyErr_SetObject.
478 *
479 * We do this to handle a situation when "value" is a tuple, in which
480 * case PyErr_SetObject would set the value of StopIteration to
481 * the first element of the tuple.
482 *
483 * (See PyErr_SetObject/_PyErr_CreateException code for details.)
484 */
485 e = PyObject_CallFunctionObjArgs(PyExc_StopIteration, value, NULL);
486 if (e == NULL) {
487 return -1;
488 }
489 PyErr_SetObject(PyExc_StopIteration, e);
490 Py_DECREF(e);
491 return 0;
492}
493
494/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000495 * If StopIteration exception is set, fetches its 'value'
496 * attribute if any, otherwise sets pvalue to None.
497 *
498 * Returns 0 if no exception or StopIteration is set.
499 * If any other exception is set, returns -1 and leaves
500 * pvalue unchanged.
501 */
502
503int
Serhiy Storchaka24411f82016-11-06 18:44:42 +0200504_PyGen_FetchStopIterationValue(PyObject **pvalue)
505{
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000506 PyObject *et, *ev, *tb;
507 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500508
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000509 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
510 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200511 if (ev) {
512 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300513 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200514 value = ((PyStopIterationObject *)ev)->value;
515 Py_INCREF(value);
516 Py_DECREF(ev);
Serhiy Storchaka24411f82016-11-06 18:44:42 +0200517 } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) {
518 /* Avoid normalisation and take ev as value.
519 *
520 * Normalization is required if the value is a tuple, in
521 * that case the value of StopIteration would be set to
522 * the first element of the tuple.
523 *
524 * (See _PyErr_CreateException code for details.)
525 */
Antoine Pitrou7403e912015-04-26 18:46:40 +0200526 value = ev;
527 } else {
528 /* normalisation required */
529 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300530 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200531 PyErr_Restore(et, ev, tb);
532 return -1;
533 }
534 value = ((PyStopIterationObject *)ev)->value;
535 Py_INCREF(value);
536 Py_DECREF(ev);
537 }
538 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000539 Py_XDECREF(et);
540 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000541 } else if (PyErr_Occurred()) {
542 return -1;
543 }
544 if (value == NULL) {
545 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100546 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000547 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000548 *pvalue = value;
549 return 0;
550}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000551
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000552static PyObject *
553gen_repr(PyGenObject *gen)
554{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400555 return PyUnicode_FromFormat("<generator object %S at %p>",
556 gen->gi_qualname, gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000557}
558
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000559static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200560gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000561{
Victor Stinner40ee3012014-06-16 15:59:28 +0200562 Py_INCREF(op->gi_name);
563 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000564}
565
Victor Stinner40ee3012014-06-16 15:59:28 +0200566static int
567gen_set_name(PyGenObject *op, PyObject *value)
568{
569 PyObject *tmp;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000570
Victor Stinner40ee3012014-06-16 15:59:28 +0200571 /* Not legal to del gen.gi_name or to set it to anything
572 * other than a string object. */
573 if (value == NULL || !PyUnicode_Check(value)) {
574 PyErr_SetString(PyExc_TypeError,
575 "__name__ must be set to a string object");
576 return -1;
577 }
578 tmp = op->gi_name;
579 Py_INCREF(value);
580 op->gi_name = value;
581 Py_DECREF(tmp);
582 return 0;
583}
584
585static PyObject *
586gen_get_qualname(PyGenObject *op)
587{
588 Py_INCREF(op->gi_qualname);
589 return op->gi_qualname;
590}
591
592static int
593gen_set_qualname(PyGenObject *op, PyObject *value)
594{
595 PyObject *tmp;
596
597 /* Not legal to del gen.__qualname__ or to set it to anything
598 * other than a string object. */
599 if (value == NULL || !PyUnicode_Check(value)) {
600 PyErr_SetString(PyExc_TypeError,
601 "__qualname__ must be set to a string object");
602 return -1;
603 }
604 tmp = op->gi_qualname;
605 Py_INCREF(value);
606 op->gi_qualname = value;
607 Py_DECREF(tmp);
608 return 0;
609}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000610
Yury Selivanove13f8f32015-07-03 00:23:30 -0400611static PyObject *
612gen_getyieldfrom(PyGenObject *gen)
613{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500614 PyObject *yf = _PyGen_yf(gen);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400615 if (yf == NULL)
616 Py_RETURN_NONE;
617 return yf;
618}
619
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000620static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200621 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
622 PyDoc_STR("name of the generator")},
623 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
624 PyDoc_STR("qualified name of the generator")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400625 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
626 PyDoc_STR("object being iterated by yield from, or None")},
Victor Stinner40ee3012014-06-16 15:59:28 +0200627 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000628};
629
Martin v. Löwise440e472004-06-01 15:22:42 +0000630static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200631 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
632 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
633 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000635};
636
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000637static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500638 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
640 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
641 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000642};
643
Martin v. Löwise440e472004-06-01 15:22:42 +0000644PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 PyVarObject_HEAD_INIT(&PyType_Type, 0)
646 "generator", /* tp_name */
647 sizeof(PyGenObject), /* tp_basicsize */
648 0, /* tp_itemsize */
649 /* methods */
650 (destructor)gen_dealloc, /* tp_dealloc */
651 0, /* tp_print */
652 0, /* tp_getattr */
653 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400654 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 (reprfunc)gen_repr, /* tp_repr */
656 0, /* tp_as_number */
657 0, /* tp_as_sequence */
658 0, /* tp_as_mapping */
659 0, /* tp_hash */
660 0, /* tp_call */
661 0, /* tp_str */
662 PyObject_GenericGetAttr, /* tp_getattro */
663 0, /* tp_setattro */
664 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200665 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
666 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 0, /* tp_doc */
668 (traverseproc)gen_traverse, /* tp_traverse */
669 0, /* tp_clear */
670 0, /* tp_richcompare */
671 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov5376ba92015-06-22 12:19:30 -0400672 PyObject_SelfIter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 (iternextfunc)gen_iternext, /* tp_iternext */
674 gen_methods, /* tp_methods */
675 gen_memberlist, /* tp_members */
676 gen_getsetlist, /* tp_getset */
677 0, /* tp_base */
678 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 0, /* tp_descr_get */
681 0, /* tp_descr_set */
682 0, /* tp_dictoffset */
683 0, /* tp_init */
684 0, /* tp_alloc */
685 0, /* tp_new */
686 0, /* tp_free */
687 0, /* tp_is_gc */
688 0, /* tp_bases */
689 0, /* tp_mro */
690 0, /* tp_cache */
691 0, /* tp_subclasses */
692 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200693 0, /* tp_del */
694 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200695 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000696};
697
Yury Selivanov5376ba92015-06-22 12:19:30 -0400698static PyObject *
699gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
700 PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000701{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400702 PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 if (gen == NULL) {
704 Py_DECREF(f);
705 return NULL;
706 }
707 gen->gi_frame = f;
Antoine Pitrou58720d62013-08-05 23:26:40 +0200708 f->f_gen = (PyObject *) gen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 Py_INCREF(f->f_code);
710 gen->gi_code = (PyObject *)(f->f_code);
711 gen->gi_running = 0;
712 gen->gi_weakreflist = NULL;
Victor Stinner40ee3012014-06-16 15:59:28 +0200713 if (name != NULL)
714 gen->gi_name = name;
715 else
716 gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;
717 Py_INCREF(gen->gi_name);
718 if (qualname != NULL)
719 gen->gi_qualname = qualname;
720 else
721 gen->gi_qualname = gen->gi_name;
722 Py_INCREF(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 _PyObject_GC_TRACK(gen);
724 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000725}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000726
Victor Stinner40ee3012014-06-16 15:59:28 +0200727PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400728PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
729{
730 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
731}
732
733PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200734PyGen_New(PyFrameObject *f)
735{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400736 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
Victor Stinner40ee3012014-06-16 15:59:28 +0200737}
738
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000739int
740PyGen_NeedsFinalizing(PyGenObject *gen)
741{
Antoine Pitrou93963562013-05-14 20:37:52 +0200742 int i;
743 PyFrameObject *f = gen->gi_frame;
744
745 if (f == NULL || f->f_stacktop == NULL)
746 return 0; /* no frame or empty blockstack == no finalization */
747
748 /* Any block type besides a loop requires cleanup. */
749 for (i = 0; i < f->f_iblock; i++)
750 if (f->f_blockstack[i].b_type != SETUP_LOOP)
751 return 1;
752
753 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755}
Yury Selivanov75445082015-05-11 22:57:16 -0400756
Yury Selivanov5376ba92015-06-22 12:19:30 -0400757/* Coroutine Object */
758
759typedef struct {
760 PyObject_HEAD
761 PyCoroObject *cw_coroutine;
762} PyCoroWrapper;
763
764static int
765gen_is_coroutine(PyObject *o)
766{
767 if (PyGen_CheckExact(o)) {
768 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
769 if (code->co_flags & CO_ITERABLE_COROUTINE) {
770 return 1;
771 }
772 }
773 return 0;
774}
775
Yury Selivanov75445082015-05-11 22:57:16 -0400776/*
777 * This helper function returns an awaitable for `o`:
778 * - `o` if `o` is a coroutine-object;
779 * - `type(o)->tp_as_async->am_await(o)`
780 *
781 * Raises a TypeError if it's not possible to return
782 * an awaitable and returns NULL.
783 */
784PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400785_PyCoro_GetAwaitableIter(PyObject *o)
Yury Selivanov75445082015-05-11 22:57:16 -0400786{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400787 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400788 PyTypeObject *ot;
789
Yury Selivanov5376ba92015-06-22 12:19:30 -0400790 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
791 /* 'o' is a coroutine. */
Yury Selivanov75445082015-05-11 22:57:16 -0400792 Py_INCREF(o);
793 return o;
794 }
795
796 ot = Py_TYPE(o);
797 if (ot->tp_as_async != NULL) {
798 getter = ot->tp_as_async->am_await;
799 }
800 if (getter != NULL) {
801 PyObject *res = (*getter)(o);
802 if (res != NULL) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400803 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
804 /* __await__ must return an *iterator*, not
805 a coroutine or another awaitable (see PEP 492) */
806 PyErr_SetString(PyExc_TypeError,
807 "__await__() returned a coroutine");
808 Py_CLEAR(res);
809 } else if (!PyIter_Check(res)) {
Yury Selivanov75445082015-05-11 22:57:16 -0400810 PyErr_Format(PyExc_TypeError,
811 "__await__() returned non-iterator "
812 "of type '%.100s'",
813 Py_TYPE(res)->tp_name);
814 Py_CLEAR(res);
815 }
Yury Selivanov75445082015-05-11 22:57:16 -0400816 }
817 return res;
818 }
819
820 PyErr_Format(PyExc_TypeError,
821 "object %.100s can't be used in 'await' expression",
822 ot->tp_name);
Yury Selivanov75445082015-05-11 22:57:16 -0400823 return NULL;
824}
Yury Selivanov5376ba92015-06-22 12:19:30 -0400825
826static PyObject *
827coro_repr(PyCoroObject *coro)
828{
829 return PyUnicode_FromFormat("<coroutine object %S at %p>",
830 coro->cr_qualname, coro);
831}
832
833static PyObject *
834coro_await(PyCoroObject *coro)
835{
836 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
837 if (cw == NULL) {
838 return NULL;
839 }
840 Py_INCREF(coro);
841 cw->cw_coroutine = coro;
842 _PyObject_GC_TRACK(cw);
843 return (PyObject *)cw;
844}
845
Yury Selivanove13f8f32015-07-03 00:23:30 -0400846static PyObject *
847coro_get_cr_await(PyCoroObject *coro)
848{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500849 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400850 if (yf == NULL)
851 Py_RETURN_NONE;
852 return yf;
853}
854
Yury Selivanov5376ba92015-06-22 12:19:30 -0400855static PyGetSetDef coro_getsetlist[] = {
856 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
857 PyDoc_STR("name of the coroutine")},
858 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
859 PyDoc_STR("qualified name of the coroutine")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400860 {"cr_await", (getter)coro_get_cr_await, NULL,
861 PyDoc_STR("object being awaited on, or None")},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400862 {NULL} /* Sentinel */
863};
864
865static PyMemberDef coro_memberlist[] = {
866 {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
867 {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
868 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
869 {NULL} /* Sentinel */
870};
871
872PyDoc_STRVAR(coro_send_doc,
873"send(arg) -> send 'arg' into coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400874return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400875
876PyDoc_STRVAR(coro_throw_doc,
877"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400878return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400879
880PyDoc_STRVAR(coro_close_doc,
881"close() -> raise GeneratorExit inside coroutine.");
882
883static PyMethodDef coro_methods[] = {
884 {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
885 {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
886 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
887 {NULL, NULL} /* Sentinel */
888};
889
890static PyAsyncMethods coro_as_async = {
891 (unaryfunc)coro_await, /* am_await */
892 0, /* am_aiter */
893 0 /* am_anext */
894};
895
896PyTypeObject PyCoro_Type = {
897 PyVarObject_HEAD_INIT(&PyType_Type, 0)
898 "coroutine", /* tp_name */
899 sizeof(PyCoroObject), /* tp_basicsize */
900 0, /* tp_itemsize */
901 /* methods */
902 (destructor)gen_dealloc, /* tp_dealloc */
903 0, /* tp_print */
904 0, /* tp_getattr */
905 0, /* tp_setattr */
906 &coro_as_async, /* tp_as_async */
907 (reprfunc)coro_repr, /* tp_repr */
908 0, /* tp_as_number */
909 0, /* tp_as_sequence */
910 0, /* tp_as_mapping */
911 0, /* tp_hash */
912 0, /* tp_call */
913 0, /* tp_str */
914 PyObject_GenericGetAttr, /* tp_getattro */
915 0, /* tp_setattro */
916 0, /* tp_as_buffer */
917 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
918 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
919 0, /* tp_doc */
920 (traverseproc)gen_traverse, /* tp_traverse */
921 0, /* tp_clear */
922 0, /* tp_richcompare */
923 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
924 0, /* tp_iter */
925 0, /* tp_iternext */
926 coro_methods, /* tp_methods */
927 coro_memberlist, /* tp_members */
928 coro_getsetlist, /* tp_getset */
929 0, /* tp_base */
930 0, /* tp_dict */
931 0, /* tp_descr_get */
932 0, /* tp_descr_set */
933 0, /* tp_dictoffset */
934 0, /* tp_init */
935 0, /* tp_alloc */
936 0, /* tp_new */
937 0, /* tp_free */
938 0, /* tp_is_gc */
939 0, /* tp_bases */
940 0, /* tp_mro */
941 0, /* tp_cache */
942 0, /* tp_subclasses */
943 0, /* tp_weaklist */
944 0, /* tp_del */
945 0, /* tp_version_tag */
946 _PyGen_Finalize, /* tp_finalize */
947};
948
949static void
950coro_wrapper_dealloc(PyCoroWrapper *cw)
951{
952 _PyObject_GC_UNTRACK((PyObject *)cw);
953 Py_CLEAR(cw->cw_coroutine);
954 PyObject_GC_Del(cw);
955}
956
957static PyObject *
958coro_wrapper_iternext(PyCoroWrapper *cw)
959{
Yury Selivanov77c96812016-02-13 17:59:05 -0500960 return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400961}
962
963static PyObject *
964coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
965{
Yury Selivanov77c96812016-02-13 17:59:05 -0500966 return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400967}
968
969static PyObject *
970coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
971{
972 return gen_throw((PyGenObject *)cw->cw_coroutine, args);
973}
974
975static PyObject *
976coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
977{
978 return gen_close((PyGenObject *)cw->cw_coroutine, args);
979}
980
981static int
982coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
983{
984 Py_VISIT((PyObject *)cw->cw_coroutine);
985 return 0;
986}
987
988static PyMethodDef coro_wrapper_methods[] = {
Yury Selivanov66f88282015-06-24 11:04:15 -0400989 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
990 {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
991 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400992 {NULL, NULL} /* Sentinel */
993};
994
995PyTypeObject _PyCoroWrapper_Type = {
996 PyVarObject_HEAD_INIT(&PyType_Type, 0)
997 "coroutine_wrapper",
998 sizeof(PyCoroWrapper), /* tp_basicsize */
999 0, /* tp_itemsize */
1000 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
1001 0, /* tp_print */
1002 0, /* tp_getattr */
1003 0, /* tp_setattr */
1004 0, /* tp_as_async */
1005 0, /* tp_repr */
1006 0, /* tp_as_number */
1007 0, /* tp_as_sequence */
1008 0, /* tp_as_mapping */
1009 0, /* tp_hash */
1010 0, /* tp_call */
1011 0, /* tp_str */
1012 PyObject_GenericGetAttr, /* tp_getattro */
1013 0, /* tp_setattro */
1014 0, /* tp_as_buffer */
1015 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1016 "A wrapper object implementing __await__ for coroutines.",
1017 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
1018 0, /* tp_clear */
1019 0, /* tp_richcompare */
1020 0, /* tp_weaklistoffset */
1021 PyObject_SelfIter, /* tp_iter */
1022 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
1023 coro_wrapper_methods, /* tp_methods */
1024 0, /* tp_members */
1025 0, /* tp_getset */
1026 0, /* tp_base */
1027 0, /* tp_dict */
1028 0, /* tp_descr_get */
1029 0, /* tp_descr_set */
1030 0, /* tp_dictoffset */
1031 0, /* tp_init */
1032 0, /* tp_alloc */
1033 0, /* tp_new */
1034 PyObject_Del, /* tp_free */
1035};
1036
1037PyObject *
1038PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1039{
1040 return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
1041}
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001042
1043
1044/* __aiter__ wrapper; see http://bugs.python.org/issue27243 for details. */
1045
1046typedef struct {
1047 PyObject_HEAD
1048 PyObject *aw_aiter;
1049} PyAIterWrapper;
1050
1051
1052static PyObject *
1053aiter_wrapper_iternext(PyAIterWrapper *aw)
1054{
Serhiy Storchaka24411f82016-11-06 18:44:42 +02001055 _PyGen_SetStopIterationValue(aw->aw_aiter);
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001056 return NULL;
1057}
1058
1059static int
1060aiter_wrapper_traverse(PyAIterWrapper *aw, visitproc visit, void *arg)
1061{
1062 Py_VISIT((PyObject *)aw->aw_aiter);
1063 return 0;
1064}
1065
1066static void
1067aiter_wrapper_dealloc(PyAIterWrapper *aw)
1068{
1069 _PyObject_GC_UNTRACK((PyObject *)aw);
1070 Py_CLEAR(aw->aw_aiter);
1071 PyObject_GC_Del(aw);
1072}
1073
1074static PyAsyncMethods aiter_wrapper_as_async = {
1075 PyObject_SelfIter, /* am_await */
1076 0, /* am_aiter */
1077 0 /* am_anext */
1078};
1079
1080PyTypeObject _PyAIterWrapper_Type = {
1081 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1082 "aiter_wrapper",
1083 sizeof(PyAIterWrapper), /* tp_basicsize */
1084 0, /* tp_itemsize */
1085 (destructor)aiter_wrapper_dealloc, /* destructor tp_dealloc */
1086 0, /* tp_print */
1087 0, /* tp_getattr */
1088 0, /* tp_setattr */
1089 &aiter_wrapper_as_async, /* tp_as_async */
1090 0, /* tp_repr */
1091 0, /* tp_as_number */
1092 0, /* tp_as_sequence */
1093 0, /* tp_as_mapping */
1094 0, /* tp_hash */
1095 0, /* tp_call */
1096 0, /* tp_str */
1097 PyObject_GenericGetAttr, /* tp_getattro */
1098 0, /* tp_setattro */
1099 0, /* tp_as_buffer */
1100 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1101 "A wrapper object for __aiter__ bakwards compatibility.",
1102 (traverseproc)aiter_wrapper_traverse, /* tp_traverse */
1103 0, /* tp_clear */
1104 0, /* tp_richcompare */
1105 0, /* tp_weaklistoffset */
1106 PyObject_SelfIter, /* tp_iter */
1107 (iternextfunc)aiter_wrapper_iternext, /* tp_iternext */
1108 0, /* tp_methods */
1109 0, /* tp_members */
1110 0, /* tp_getset */
1111 0, /* tp_base */
1112 0, /* tp_dict */
1113 0, /* tp_descr_get */
1114 0, /* tp_descr_set */
1115 0, /* tp_dictoffset */
1116 0, /* tp_init */
1117 0, /* tp_alloc */
1118 0, /* tp_new */
1119 PyObject_Del, /* tp_free */
1120};
1121
1122
1123PyObject *
1124_PyAIterWrapper_New(PyObject *aiter)
1125{
1126 PyAIterWrapper *aw = PyObject_GC_New(PyAIterWrapper,
1127 &_PyAIterWrapper_Type);
1128 if (aw == NULL) {
1129 return NULL;
1130 }
1131 Py_INCREF(aiter);
1132 aw->aw_aiter = aiter;
1133 _PyObject_GC_TRACK(aw);
1134 return (PyObject *)aw;
1135}