blob: f74d044dcf7a96bde132a64e97de15886fe44a25 [file] [log] [blame]
Martin v. Löwise440e472004-06-01 15:22:42 +00001/* Generator object implementation */
2
3#include "Python.h"
4#include "frameobject.h"
Martin v. Löwise440e472004-06-01 15:22:42 +00005#include "structmember.h"
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006#include "opcode.h"
Martin v. Löwise440e472004-06-01 15:22:42 +00007
Nick Coghlan1f7ce622012-01-13 21:43:40 +10008static PyObject *gen_close(PyGenObject *gen, PyObject *args);
Nick Coghlan1f7ce622012-01-13 21:43:40 +10009
Martin v. Löwise440e472004-06-01 15:22:42 +000010static int
11gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
12{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 Py_VISIT((PyObject *)gen->gi_frame);
14 Py_VISIT(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020015 Py_VISIT(gen->gi_name);
16 Py_VISIT(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 return 0;
Martin v. Löwise440e472004-06-01 15:22:42 +000018}
19
Antoine Pitrou58720d62013-08-05 23:26:40 +020020void
21_PyGen_Finalize(PyObject *self)
Antoine Pitrou796564c2013-07-30 19:59:21 +020022{
23 PyGenObject *gen = (PyGenObject *)self;
24 PyObject *res;
25 PyObject *error_type, *error_value, *error_traceback;
26
Yury Selivanov75445082015-05-11 22:57:16 -040027 /* If `gen` is a coroutine, and if it was never awaited on,
28 issue a RuntimeWarning. */
29 if (gen->gi_code != NULL
Yury Selivanov5376ba92015-06-22 12:19:30 -040030 && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE
Yury Selivanov75445082015-05-11 22:57:16 -040031 && gen->gi_frame != NULL
32 && gen->gi_frame->f_lasti == -1
33 && !PyErr_Occurred()
34 && PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
35 "coroutine '%.50S' was never awaited",
36 gen->gi_qualname))
37 return;
38
Antoine Pitrou796564c2013-07-30 19:59:21 +020039 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
40 /* Generator isn't paused, so no need to close */
41 return;
42
43 /* Save the current exception, if any. */
44 PyErr_Fetch(&error_type, &error_value, &error_traceback);
45
46 res = gen_close(gen, NULL);
47
48 if (res == NULL)
49 PyErr_WriteUnraisable(self);
50 else
51 Py_DECREF(res);
52
53 /* Restore the saved exception. */
54 PyErr_Restore(error_type, error_value, error_traceback);
55}
56
57static void
Martin v. Löwise440e472004-06-01 15:22:42 +000058gen_dealloc(PyGenObject *gen)
59{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 PyObject *self = (PyObject *) gen;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 _PyObject_GC_UNTRACK(gen);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 if (gen->gi_weakreflist != NULL)
65 PyObject_ClearWeakRefs(self);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000066
Antoine Pitrou93963562013-05-14 20:37:52 +020067 _PyObject_GC_TRACK(self);
68
Antoine Pitrou796564c2013-07-30 19:59:21 +020069 if (PyObject_CallFinalizerFromDealloc(self))
70 return; /* resurrected. :( */
Antoine Pitrou93963562013-05-14 20:37:52 +020071
72 _PyObject_GC_UNTRACK(self);
73 Py_CLEAR(gen->gi_frame);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 Py_CLEAR(gen->gi_code);
Victor Stinner40ee3012014-06-16 15:59:28 +020075 Py_CLEAR(gen->gi_name);
76 Py_CLEAR(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 PyObject_GC_Del(gen);
Martin v. Löwise440e472004-06-01 15:22:42 +000078}
79
80static PyObject *
Yury Selivanov77c96812016-02-13 17:59:05 -050081gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
Martin v. Löwise440e472004-06-01 15:22:42 +000082{
Antoine Pitrou93963562013-05-14 20:37:52 +020083 PyThreadState *tstate = PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +020085 PyObject *result;
Martin v. Löwise440e472004-06-01 15:22:42 +000086
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050087 if (gen->gi_running) {
Yury Selivanov5376ba92015-06-22 12:19:30 -040088 char *msg = "generator already executing";
89 if (PyCoro_CheckExact(gen))
90 msg = "coroutine already executing";
91 PyErr_SetString(PyExc_ValueError, msg);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -050092 return NULL;
93 }
Antoine Pitrou93963562013-05-14 20:37:52 +020094 if (f == NULL || f->f_stacktop == NULL) {
Yury Selivanov77c96812016-02-13 17:59:05 -050095 if (PyCoro_CheckExact(gen) && !closing) {
96 /* `gen` is an exhausted coroutine: raise an error,
97 except when called from gen_close(), which should
98 always be a silent method. */
99 PyErr_SetString(
100 PyExc_RuntimeError,
101 "cannot reuse already awaited coroutine");
102 } else if (arg && !exc) {
103 /* `gen` is an exhausted generator:
104 only set exception if called from send(). */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 PyErr_SetNone(PyExc_StopIteration);
Yury Selivanov77c96812016-02-13 17:59:05 -0500106 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 return NULL;
108 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000109
Antoine Pitrou93963562013-05-14 20:37:52 +0200110 if (f->f_lasti == -1) {
111 if (arg && arg != Py_None) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400112 char *msg = "can't send non-None value to a "
113 "just-started generator";
114 if (PyCoro_CheckExact(gen))
115 msg = "can't send non-None value to a "
116 "just-started coroutine";
117 PyErr_SetString(PyExc_TypeError, msg);
Antoine Pitrou93963562013-05-14 20:37:52 +0200118 return NULL;
119 }
120 } else {
121 /* Push arg onto the frame's value stack */
122 result = arg ? arg : Py_None;
123 Py_INCREF(result);
124 *(f->f_stacktop++) = result;
125 }
126
127 /* Generators always return to their most recent caller, not
128 * necessarily their creator. */
129 Py_XINCREF(tstate->frame);
130 assert(f->f_back == NULL);
131 f->f_back = tstate->frame;
132
133 gen->gi_running = 1;
134 result = PyEval_EvalFrameEx(f, exc);
135 gen->gi_running = 0;
136
137 /* Don't keep the reference to f_back any longer than necessary. It
138 * may keep a chain of frames alive or it could create a reference
139 * cycle. */
140 assert(f->f_back == tstate->frame);
141 Py_CLEAR(f->f_back);
142
143 /* If the generator just returned (as opposed to yielding), signal
144 * that the generator is exhausted. */
145 if (result && f->f_stacktop == NULL) {
146 if (result == Py_None) {
147 /* Delay exception instantiation if we can */
148 PyErr_SetNone(PyExc_StopIteration);
149 } else {
150 PyObject *e = PyObject_CallFunctionObjArgs(
151 PyExc_StopIteration, result, NULL);
152 if (e != NULL) {
153 PyErr_SetObject(PyExc_StopIteration, e);
154 Py_DECREF(e);
155 }
156 }
157 Py_CLEAR(result);
158 }
Yury Selivanov68333392015-05-22 11:16:47 -0400159 else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400160 /* Check for __future__ generator_stop and conditionally turn
161 * a leaking StopIteration into RuntimeError (with its cause
162 * set appropriately). */
Yury Selivanov68333392015-05-22 11:16:47 -0400163 if (((PyCodeObject *)gen->gi_code)->co_flags &
Yury Selivanov75445082015-05-11 22:57:16 -0400164 (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400165 {
166 PyObject *exc, *val, *val2, *tb;
Yury Selivanov5376ba92015-06-22 12:19:30 -0400167 char *msg = "generator raised StopIteration";
168 if (PyCoro_CheckExact(gen))
169 msg = "coroutine raised StopIteration";
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400170 PyErr_Fetch(&exc, &val, &tb);
171 PyErr_NormalizeException(&exc, &val, &tb);
172 if (tb != NULL)
173 PyException_SetTraceback(val, tb);
174 Py_DECREF(exc);
175 Py_XDECREF(tb);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400176 PyErr_SetString(PyExc_RuntimeError, msg);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400177 PyErr_Fetch(&exc, &val2, &tb);
178 PyErr_NormalizeException(&exc, &val2, &tb);
Yury Selivanov18c30a22015-05-10 15:09:46 -0400179 Py_INCREF(val);
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400180 PyException_SetCause(val2, val);
181 PyException_SetContext(val2, val);
182 PyErr_Restore(exc, val2, tb);
183 }
Yury Selivanov68333392015-05-22 11:16:47 -0400184 else {
185 PyObject *exc, *val, *tb;
186
187 /* Pop the exception before issuing a warning. */
188 PyErr_Fetch(&exc, &val, &tb);
189
190 if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
191 "generator '%.50S' raised StopIteration",
192 gen->gi_qualname)) {
193 /* Warning was converted to an error. */
194 Py_XDECREF(exc);
195 Py_XDECREF(val);
196 Py_XDECREF(tb);
197 }
198 else {
199 PyErr_Restore(exc, val, tb);
200 }
201 }
Yury Selivanov8170e8c2015-05-09 11:44:30 -0400202 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200203
204 if (!result || f->f_stacktop == NULL) {
205 /* generator can't be rerun, so release the frame */
206 /* first clean reference cycle through stored exception traceback */
207 PyObject *t, *v, *tb;
208 t = f->f_exc_type;
209 v = f->f_exc_value;
210 tb = f->f_exc_traceback;
211 f->f_exc_type = NULL;
212 f->f_exc_value = NULL;
213 f->f_exc_traceback = NULL;
214 Py_XDECREF(t);
215 Py_XDECREF(v);
216 Py_XDECREF(tb);
Antoine Pitrou58720d62013-08-05 23:26:40 +0200217 gen->gi_frame->f_gen = NULL;
Antoine Pitrou93963562013-05-14 20:37:52 +0200218 gen->gi_frame = NULL;
219 Py_DECREF(f);
220 }
221
222 return result;
Martin v. Löwise440e472004-06-01 15:22:42 +0000223}
224
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000225PyDoc_STRVAR(send_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000226"send(arg) -> send 'arg' into generator,\n\
227return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000228
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500229PyObject *
230_PyGen_Send(PyGenObject *gen, PyObject *arg)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000231{
Yury Selivanov77c96812016-02-13 17:59:05 -0500232 return gen_send_ex(gen, arg, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000233}
234
235PyDoc_STRVAR(close_doc,
Benjamin Petersonab3da292012-05-03 18:44:09 -0400236"close() -> raise GeneratorExit inside generator.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000237
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000238/*
239 * This helper function is used by gen_close and gen_throw to
240 * close a subiterator being delegated to by yield-from.
241 */
242
Antoine Pitrou93963562013-05-14 20:37:52 +0200243static int
244gen_close_iter(PyObject *yf)
245{
246 PyObject *retval = NULL;
247 _Py_IDENTIFIER(close);
248
249 if (PyGen_CheckExact(yf)) {
250 retval = gen_close((PyGenObject *)yf, NULL);
251 if (retval == NULL)
252 return -1;
253 } else {
254 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
255 if (meth == NULL) {
256 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
257 PyErr_WriteUnraisable(yf);
258 PyErr_Clear();
259 } else {
260 retval = PyObject_CallFunction(meth, "");
261 Py_DECREF(meth);
262 if (retval == NULL)
263 return -1;
264 }
265 }
266 Py_XDECREF(retval);
267 return 0;
268}
269
Yury Selivanovc724bae2016-03-02 11:30:46 -0500270PyObject *
271_PyGen_yf(PyGenObject *gen)
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500272{
Antoine Pitrou93963562013-05-14 20:37:52 +0200273 PyObject *yf = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500274 PyFrameObject *f = gen->gi_frame;
Antoine Pitrou93963562013-05-14 20:37:52 +0200275
276 if (f && f->f_stacktop) {
277 PyObject *bytecode = f->f_code->co_code;
278 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
279
280 if (code[f->f_lasti + 1] != YIELD_FROM)
281 return NULL;
282 yf = f->f_stacktop[-1];
283 Py_INCREF(yf);
284 }
285
286 return yf;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500287}
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000288
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000289static PyObject *
290gen_close(PyGenObject *gen, PyObject *args)
291{
Antoine Pitrou93963562013-05-14 20:37:52 +0200292 PyObject *retval;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500293 PyObject *yf = _PyGen_yf(gen);
Antoine Pitrou93963562013-05-14 20:37:52 +0200294 int err = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000295
Antoine Pitrou93963562013-05-14 20:37:52 +0200296 if (yf) {
297 gen->gi_running = 1;
298 err = gen_close_iter(yf);
299 gen->gi_running = 0;
300 Py_DECREF(yf);
301 }
302 if (err == 0)
303 PyErr_SetNone(PyExc_GeneratorExit);
Yury Selivanov77c96812016-02-13 17:59:05 -0500304 retval = gen_send_ex(gen, Py_None, 1, 1);
Antoine Pitrou93963562013-05-14 20:37:52 +0200305 if (retval) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400306 char *msg = "generator ignored GeneratorExit";
307 if (PyCoro_CheckExact(gen))
308 msg = "coroutine ignored GeneratorExit";
Antoine Pitrou93963562013-05-14 20:37:52 +0200309 Py_DECREF(retval);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400310 PyErr_SetString(PyExc_RuntimeError, msg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 return NULL;
312 }
Antoine Pitrou93963562013-05-14 20:37:52 +0200313 if (PyErr_ExceptionMatches(PyExc_StopIteration)
314 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
315 PyErr_Clear(); /* ignore these errors */
316 Py_INCREF(Py_None);
317 return Py_None;
318 }
319 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000320}
321
Antoine Pitrou93963562013-05-14 20:37:52 +0200322
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000323PyDoc_STRVAR(throw_doc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
325return next yielded value or raise StopIteration.");
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000326
327static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328gen_throw(PyGenObject *gen, PyObject *args)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 PyObject *typ;
331 PyObject *tb = NULL;
332 PyObject *val = NULL;
Yury Selivanovc724bae2016-03-02 11:30:46 -0500333 PyObject *yf = _PyGen_yf(gen);
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000334 _Py_IDENTIFIER(throw);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
337 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000338
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000339 if (yf) {
340 PyObject *ret;
341 int err;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000342 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500343 gen->gi_running = 1;
Antoine Pitrou93963562013-05-14 20:37:52 +0200344 err = gen_close_iter(yf);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500345 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000346 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000347 if (err < 0)
Yury Selivanov77c96812016-02-13 17:59:05 -0500348 return gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000349 goto throw_here;
350 }
351 if (PyGen_CheckExact(yf)) {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500352 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000353 ret = gen_throw((PyGenObject *)yf, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500354 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000355 } else {
Nick Coghlan5b0dac12012-06-17 15:45:11 +1000356 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000357 if (meth == NULL) {
358 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
359 Py_DECREF(yf);
360 return NULL;
361 }
362 PyErr_Clear();
363 Py_DECREF(yf);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000364 goto throw_here;
365 }
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500366 gen->gi_running = 1;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000367 ret = PyObject_CallObject(meth, args);
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500368 gen->gi_running = 0;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000369 Py_DECREF(meth);
370 }
371 Py_DECREF(yf);
372 if (!ret) {
373 PyObject *val;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500374 /* Pop subiterator from stack */
375 ret = *(--gen->gi_frame->f_stacktop);
376 assert(ret == yf);
377 Py_DECREF(ret);
378 /* Termination repetition of YIELD_FROM */
379 gen->gi_frame->f_lasti++;
Nick Coghlanc40bc092012-06-17 15:15:49 +1000380 if (_PyGen_FetchStopIterationValue(&val) == 0) {
Yury Selivanov77c96812016-02-13 17:59:05 -0500381 ret = gen_send_ex(gen, val, 0, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000382 Py_DECREF(val);
383 } else {
Yury Selivanov77c96812016-02-13 17:59:05 -0500384 ret = gen_send_ex(gen, Py_None, 1, 0);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000385 }
386 }
387 return ret;
388 }
389
390throw_here:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 /* First, check the traceback argument, replacing None with
392 NULL. */
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400393 if (tb == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 tb = NULL;
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400395 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 else if (tb != NULL && !PyTraceBack_Check(tb)) {
397 PyErr_SetString(PyExc_TypeError,
398 "throw() third argument must be a traceback object");
399 return NULL;
400 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 Py_INCREF(typ);
403 Py_XINCREF(val);
404 Py_XINCREF(tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000405
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400406 if (PyExceptionClass_Check(typ))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 PyErr_NormalizeException(&typ, &val, &tb);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 else if (PyExceptionInstance_Check(typ)) {
410 /* Raising an instance. The value should be a dummy. */
411 if (val && val != Py_None) {
412 PyErr_SetString(PyExc_TypeError,
413 "instance exception may not have a separate value");
414 goto failed_throw;
415 }
416 else {
417 /* Normalize to raise <class>, <instance> */
418 Py_XDECREF(val);
419 val = typ;
420 typ = PyExceptionInstance_Class(typ);
421 Py_INCREF(typ);
Antoine Pitrou551ba202011-10-18 16:40:50 +0200422
Benjamin Peterson9d9141f2011-10-19 16:57:40 -0400423 if (tb == NULL)
Antoine Pitrou551ba202011-10-18 16:40:50 +0200424 /* Returns NULL if there's no traceback */
425 tb = PyException_GetTraceback(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 }
427 }
428 else {
429 /* Not something you can raise. throw() fails. */
430 PyErr_Format(PyExc_TypeError,
431 "exceptions must be classes or instances "
432 "deriving from BaseException, not %s",
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000433 Py_TYPE(typ)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 goto failed_throw;
435 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 PyErr_Restore(typ, val, tb);
Yury Selivanov77c96812016-02-13 17:59:05 -0500438 return gen_send_ex(gen, Py_None, 1, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000439
440failed_throw:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 /* Didn't use our arguments, so restore their original refcounts */
442 Py_DECREF(typ);
443 Py_XDECREF(val);
444 Py_XDECREF(tb);
445 return NULL;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000446}
447
448
449static PyObject *
450gen_iternext(PyGenObject *gen)
451{
Yury Selivanov77c96812016-02-13 17:59:05 -0500452 return gen_send_ex(gen, NULL, 0, 0);
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000453}
454
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000455/*
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000456 * If StopIteration exception is set, fetches its 'value'
457 * attribute if any, otherwise sets pvalue to None.
458 *
459 * Returns 0 if no exception or StopIteration is set.
460 * If any other exception is set, returns -1 and leaves
461 * pvalue unchanged.
462 */
463
464int
Nick Coghlanc40bc092012-06-17 15:15:49 +1000465_PyGen_FetchStopIterationValue(PyObject **pvalue) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000466 PyObject *et, *ev, *tb;
467 PyObject *value = NULL;
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500468
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000469 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
470 PyErr_Fetch(&et, &ev, &tb);
Antoine Pitrou7403e912015-04-26 18:46:40 +0200471 if (ev) {
472 /* exception will usually be normalised already */
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300473 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200474 value = ((PyStopIterationObject *)ev)->value;
475 Py_INCREF(value);
476 Py_DECREF(ev);
477 } else if (et == PyExc_StopIteration) {
478 /* avoid normalisation and take ev as value */
479 value = ev;
480 } else {
481 /* normalisation required */
482 PyErr_NormalizeException(&et, &ev, &tb);
Serhiy Storchaka08d230a2015-05-22 11:02:49 +0300483 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
Antoine Pitrou7403e912015-04-26 18:46:40 +0200484 PyErr_Restore(et, ev, tb);
485 return -1;
486 }
487 value = ((PyStopIterationObject *)ev)->value;
488 Py_INCREF(value);
489 Py_DECREF(ev);
490 }
491 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000492 Py_XDECREF(et);
493 Py_XDECREF(tb);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000494 } else if (PyErr_Occurred()) {
495 return -1;
496 }
497 if (value == NULL) {
498 value = Py_None;
Amaury Forgeot d'Arce557da82012-01-13 21:06:12 +0100499 Py_INCREF(value);
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000500 }
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000501 *pvalue = value;
502 return 0;
503}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000504
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000505static PyObject *
506gen_repr(PyGenObject *gen)
507{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400508 return PyUnicode_FromFormat("<generator object %S at %p>",
509 gen->gi_qualname, gen);
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000510}
511
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000512static PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200513gen_get_name(PyGenObject *op)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000514{
Victor Stinner40ee3012014-06-16 15:59:28 +0200515 Py_INCREF(op->gi_name);
516 return op->gi_name;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000517}
518
Victor Stinner40ee3012014-06-16 15:59:28 +0200519static int
520gen_set_name(PyGenObject *op, PyObject *value)
521{
522 PyObject *tmp;
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000523
Victor Stinner40ee3012014-06-16 15:59:28 +0200524 /* Not legal to del gen.gi_name or to set it to anything
525 * other than a string object. */
526 if (value == NULL || !PyUnicode_Check(value)) {
527 PyErr_SetString(PyExc_TypeError,
528 "__name__ must be set to a string object");
529 return -1;
530 }
531 tmp = op->gi_name;
532 Py_INCREF(value);
533 op->gi_name = value;
534 Py_DECREF(tmp);
535 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{
548 PyObject *tmp;
549
550 /* Not legal to del gen.__qualname__ or to set it to anything
551 * other than a string object. */
552 if (value == NULL || !PyUnicode_Check(value)) {
553 PyErr_SetString(PyExc_TypeError,
554 "__qualname__ must be set to a string object");
555 return -1;
556 }
557 tmp = op->gi_qualname;
558 Py_INCREF(value);
559 op->gi_qualname = value;
560 Py_DECREF(tmp);
561 return 0;
562}
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000563
Yury Selivanove13f8f32015-07-03 00:23:30 -0400564static PyObject *
565gen_getyieldfrom(PyGenObject *gen)
566{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500567 PyObject *yf = _PyGen_yf(gen);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400568 if (yf == NULL)
569 Py_RETURN_NONE;
570 return yf;
571}
572
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000573static PyGetSetDef gen_getsetlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200574 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
575 PyDoc_STR("name of the generator")},
576 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
577 PyDoc_STR("qualified name of the generator")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400578 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
579 PyDoc_STR("object being iterated by yield from, or None")},
Victor Stinner40ee3012014-06-16 15:59:28 +0200580 {NULL} /* Sentinel */
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000581};
582
Martin v. Löwise440e472004-06-01 15:22:42 +0000583static PyMemberDef gen_memberlist[] = {
Victor Stinner40ee3012014-06-16 15:59:28 +0200584 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
585 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
586 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 {NULL} /* Sentinel */
Martin v. Löwise440e472004-06-01 15:22:42 +0000588};
589
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000590static PyMethodDef gen_methods[] = {
Benjamin Peterson2afe6ae2012-03-15 15:37:39 -0500591 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
593 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
594 {NULL, NULL} /* Sentinel */
Phillip J. Eby0d6615f2005-08-02 00:46:46 +0000595};
596
Martin v. Löwise440e472004-06-01 15:22:42 +0000597PyTypeObject PyGen_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 PyVarObject_HEAD_INIT(&PyType_Type, 0)
599 "generator", /* tp_name */
600 sizeof(PyGenObject), /* tp_basicsize */
601 0, /* tp_itemsize */
602 /* methods */
603 (destructor)gen_dealloc, /* tp_dealloc */
604 0, /* tp_print */
605 0, /* tp_getattr */
606 0, /* tp_setattr */
Yury Selivanov75445082015-05-11 22:57:16 -0400607 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 (reprfunc)gen_repr, /* tp_repr */
609 0, /* tp_as_number */
610 0, /* tp_as_sequence */
611 0, /* tp_as_mapping */
612 0, /* tp_hash */
613 0, /* tp_call */
614 0, /* tp_str */
615 PyObject_GenericGetAttr, /* tp_getattro */
616 0, /* tp_setattro */
617 0, /* tp_as_buffer */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200618 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
619 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 0, /* tp_doc */
621 (traverseproc)gen_traverse, /* tp_traverse */
622 0, /* tp_clear */
623 0, /* tp_richcompare */
624 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
Yury Selivanov5376ba92015-06-22 12:19:30 -0400625 PyObject_SelfIter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 (iternextfunc)gen_iternext, /* tp_iternext */
627 gen_methods, /* tp_methods */
628 gen_memberlist, /* tp_members */
629 gen_getsetlist, /* tp_getset */
630 0, /* tp_base */
631 0, /* tp_dict */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 0, /* tp_descr_get */
634 0, /* tp_descr_set */
635 0, /* tp_dictoffset */
636 0, /* tp_init */
637 0, /* tp_alloc */
638 0, /* tp_new */
639 0, /* tp_free */
640 0, /* tp_is_gc */
641 0, /* tp_bases */
642 0, /* tp_mro */
643 0, /* tp_cache */
644 0, /* tp_subclasses */
645 0, /* tp_weaklist */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200646 0, /* tp_del */
647 0, /* tp_version_tag */
Antoine Pitrou58720d62013-08-05 23:26:40 +0200648 _PyGen_Finalize, /* tp_finalize */
Martin v. Löwise440e472004-06-01 15:22:42 +0000649};
650
Yury Selivanov5376ba92015-06-22 12:19:30 -0400651static PyObject *
652gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
653 PyObject *name, PyObject *qualname)
Martin v. Löwise440e472004-06-01 15:22:42 +0000654{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400655 PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (gen == NULL) {
657 Py_DECREF(f);
658 return NULL;
659 }
660 gen->gi_frame = f;
Antoine Pitrou58720d62013-08-05 23:26:40 +0200661 f->f_gen = (PyObject *) gen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 Py_INCREF(f->f_code);
663 gen->gi_code = (PyObject *)(f->f_code);
664 gen->gi_running = 0;
665 gen->gi_weakreflist = NULL;
Victor Stinner40ee3012014-06-16 15:59:28 +0200666 if (name != NULL)
667 gen->gi_name = name;
668 else
669 gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;
670 Py_INCREF(gen->gi_name);
671 if (qualname != NULL)
672 gen->gi_qualname = qualname;
673 else
674 gen->gi_qualname = gen->gi_name;
675 Py_INCREF(gen->gi_qualname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 _PyObject_GC_TRACK(gen);
677 return (PyObject *)gen;
Martin v. Löwise440e472004-06-01 15:22:42 +0000678}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000679
Victor Stinner40ee3012014-06-16 15:59:28 +0200680PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400681PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
682{
683 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
684}
685
686PyObject *
Victor Stinner40ee3012014-06-16 15:59:28 +0200687PyGen_New(PyFrameObject *f)
688{
Yury Selivanov5376ba92015-06-22 12:19:30 -0400689 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
Victor Stinner40ee3012014-06-16 15:59:28 +0200690}
691
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000692int
693PyGen_NeedsFinalizing(PyGenObject *gen)
694{
Antoine Pitrou93963562013-05-14 20:37:52 +0200695 int i;
696 PyFrameObject *f = gen->gi_frame;
697
698 if (f == NULL || f->f_stacktop == NULL)
699 return 0; /* no frame or empty blockstack == no finalization */
700
701 /* Any block type besides a loop requires cleanup. */
702 for (i = 0; i < f->f_iblock; i++)
703 if (f->f_blockstack[i].b_type != SETUP_LOOP)
704 return 1;
705
706 /* No blocks except loops, it's safe to skip finalization. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000708}
Yury Selivanov75445082015-05-11 22:57:16 -0400709
Yury Selivanov5376ba92015-06-22 12:19:30 -0400710/* Coroutine Object */
711
712typedef struct {
713 PyObject_HEAD
714 PyCoroObject *cw_coroutine;
715} PyCoroWrapper;
716
717static int
718gen_is_coroutine(PyObject *o)
719{
720 if (PyGen_CheckExact(o)) {
721 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
722 if (code->co_flags & CO_ITERABLE_COROUTINE) {
723 return 1;
724 }
725 }
726 return 0;
727}
728
Yury Selivanov75445082015-05-11 22:57:16 -0400729/*
730 * This helper function returns an awaitable for `o`:
731 * - `o` if `o` is a coroutine-object;
732 * - `type(o)->tp_as_async->am_await(o)`
733 *
734 * Raises a TypeError if it's not possible to return
735 * an awaitable and returns NULL.
736 */
737PyObject *
Yury Selivanov5376ba92015-06-22 12:19:30 -0400738_PyCoro_GetAwaitableIter(PyObject *o)
Yury Selivanov75445082015-05-11 22:57:16 -0400739{
Yury Selivanov6ef05902015-05-28 11:21:31 -0400740 unaryfunc getter = NULL;
Yury Selivanov75445082015-05-11 22:57:16 -0400741 PyTypeObject *ot;
742
Yury Selivanov5376ba92015-06-22 12:19:30 -0400743 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
744 /* 'o' is a coroutine. */
Yury Selivanov75445082015-05-11 22:57:16 -0400745 Py_INCREF(o);
746 return o;
747 }
748
749 ot = Py_TYPE(o);
750 if (ot->tp_as_async != NULL) {
751 getter = ot->tp_as_async->am_await;
752 }
753 if (getter != NULL) {
754 PyObject *res = (*getter)(o);
755 if (res != NULL) {
Yury Selivanov5376ba92015-06-22 12:19:30 -0400756 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
757 /* __await__ must return an *iterator*, not
758 a coroutine or another awaitable (see PEP 492) */
759 PyErr_SetString(PyExc_TypeError,
760 "__await__() returned a coroutine");
761 Py_CLEAR(res);
762 } else if (!PyIter_Check(res)) {
Yury Selivanov75445082015-05-11 22:57:16 -0400763 PyErr_Format(PyExc_TypeError,
764 "__await__() returned non-iterator "
765 "of type '%.100s'",
766 Py_TYPE(res)->tp_name);
767 Py_CLEAR(res);
768 }
Yury Selivanov75445082015-05-11 22:57:16 -0400769 }
770 return res;
771 }
772
773 PyErr_Format(PyExc_TypeError,
774 "object %.100s can't be used in 'await' expression",
775 ot->tp_name);
Yury Selivanov75445082015-05-11 22:57:16 -0400776 return NULL;
777}
Yury Selivanov5376ba92015-06-22 12:19:30 -0400778
779static PyObject *
780coro_repr(PyCoroObject *coro)
781{
782 return PyUnicode_FromFormat("<coroutine object %S at %p>",
783 coro->cr_qualname, coro);
784}
785
786static PyObject *
787coro_await(PyCoroObject *coro)
788{
789 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
790 if (cw == NULL) {
791 return NULL;
792 }
793 Py_INCREF(coro);
794 cw->cw_coroutine = coro;
795 _PyObject_GC_TRACK(cw);
796 return (PyObject *)cw;
797}
798
Yury Selivanove13f8f32015-07-03 00:23:30 -0400799static PyObject *
800coro_get_cr_await(PyCoroObject *coro)
801{
Yury Selivanovc724bae2016-03-02 11:30:46 -0500802 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
Yury Selivanove13f8f32015-07-03 00:23:30 -0400803 if (yf == NULL)
804 Py_RETURN_NONE;
805 return yf;
806}
807
Yury Selivanov5376ba92015-06-22 12:19:30 -0400808static PyGetSetDef coro_getsetlist[] = {
809 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
810 PyDoc_STR("name of the coroutine")},
811 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
812 PyDoc_STR("qualified name of the coroutine")},
Yury Selivanove13f8f32015-07-03 00:23:30 -0400813 {"cr_await", (getter)coro_get_cr_await, NULL,
814 PyDoc_STR("object being awaited on, or None")},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400815 {NULL} /* Sentinel */
816};
817
818static PyMemberDef coro_memberlist[] = {
819 {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
820 {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
821 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
822 {NULL} /* Sentinel */
823};
824
825PyDoc_STRVAR(coro_send_doc,
826"send(arg) -> send 'arg' into 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_throw_doc,
830"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
Yury Selivanov66f88282015-06-24 11:04:15 -0400831return next iterated value or raise StopIteration.");
Yury Selivanov5376ba92015-06-22 12:19:30 -0400832
833PyDoc_STRVAR(coro_close_doc,
834"close() -> raise GeneratorExit inside coroutine.");
835
836static PyMethodDef coro_methods[] = {
837 {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
838 {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
839 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
840 {NULL, NULL} /* Sentinel */
841};
842
843static PyAsyncMethods coro_as_async = {
844 (unaryfunc)coro_await, /* am_await */
845 0, /* am_aiter */
846 0 /* am_anext */
847};
848
849PyTypeObject PyCoro_Type = {
850 PyVarObject_HEAD_INIT(&PyType_Type, 0)
851 "coroutine", /* tp_name */
852 sizeof(PyCoroObject), /* tp_basicsize */
853 0, /* tp_itemsize */
854 /* methods */
855 (destructor)gen_dealloc, /* tp_dealloc */
856 0, /* tp_print */
857 0, /* tp_getattr */
858 0, /* tp_setattr */
859 &coro_as_async, /* tp_as_async */
860 (reprfunc)coro_repr, /* tp_repr */
861 0, /* tp_as_number */
862 0, /* tp_as_sequence */
863 0, /* tp_as_mapping */
864 0, /* tp_hash */
865 0, /* tp_call */
866 0, /* tp_str */
867 PyObject_GenericGetAttr, /* tp_getattro */
868 0, /* tp_setattro */
869 0, /* tp_as_buffer */
870 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
871 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
872 0, /* tp_doc */
873 (traverseproc)gen_traverse, /* tp_traverse */
874 0, /* tp_clear */
875 0, /* tp_richcompare */
876 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
877 0, /* tp_iter */
878 0, /* tp_iternext */
879 coro_methods, /* tp_methods */
880 coro_memberlist, /* tp_members */
881 coro_getsetlist, /* tp_getset */
882 0, /* tp_base */
883 0, /* tp_dict */
884 0, /* tp_descr_get */
885 0, /* tp_descr_set */
886 0, /* tp_dictoffset */
887 0, /* tp_init */
888 0, /* tp_alloc */
889 0, /* tp_new */
890 0, /* tp_free */
891 0, /* tp_is_gc */
892 0, /* tp_bases */
893 0, /* tp_mro */
894 0, /* tp_cache */
895 0, /* tp_subclasses */
896 0, /* tp_weaklist */
897 0, /* tp_del */
898 0, /* tp_version_tag */
899 _PyGen_Finalize, /* tp_finalize */
900};
901
902static void
903coro_wrapper_dealloc(PyCoroWrapper *cw)
904{
905 _PyObject_GC_UNTRACK((PyObject *)cw);
906 Py_CLEAR(cw->cw_coroutine);
907 PyObject_GC_Del(cw);
908}
909
910static PyObject *
911coro_wrapper_iternext(PyCoroWrapper *cw)
912{
Yury Selivanov77c96812016-02-13 17:59:05 -0500913 return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400914}
915
916static PyObject *
917coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
918{
Yury Selivanov77c96812016-02-13 17:59:05 -0500919 return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);
Yury Selivanov5376ba92015-06-22 12:19:30 -0400920}
921
922static PyObject *
923coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
924{
925 return gen_throw((PyGenObject *)cw->cw_coroutine, args);
926}
927
928static PyObject *
929coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
930{
931 return gen_close((PyGenObject *)cw->cw_coroutine, args);
932}
933
934static int
935coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
936{
937 Py_VISIT((PyObject *)cw->cw_coroutine);
938 return 0;
939}
940
941static PyMethodDef coro_wrapper_methods[] = {
Yury Selivanov66f88282015-06-24 11:04:15 -0400942 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
943 {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
944 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
Yury Selivanov5376ba92015-06-22 12:19:30 -0400945 {NULL, NULL} /* Sentinel */
946};
947
948PyTypeObject _PyCoroWrapper_Type = {
949 PyVarObject_HEAD_INIT(&PyType_Type, 0)
950 "coroutine_wrapper",
951 sizeof(PyCoroWrapper), /* tp_basicsize */
952 0, /* tp_itemsize */
953 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
954 0, /* tp_print */
955 0, /* tp_getattr */
956 0, /* tp_setattr */
957 0, /* tp_as_async */
958 0, /* tp_repr */
959 0, /* tp_as_number */
960 0, /* tp_as_sequence */
961 0, /* tp_as_mapping */
962 0, /* tp_hash */
963 0, /* tp_call */
964 0, /* tp_str */
965 PyObject_GenericGetAttr, /* tp_getattro */
966 0, /* tp_setattro */
967 0, /* tp_as_buffer */
968 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
969 "A wrapper object implementing __await__ for coroutines.",
970 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
971 0, /* tp_clear */
972 0, /* tp_richcompare */
973 0, /* tp_weaklistoffset */
974 PyObject_SelfIter, /* tp_iter */
975 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
976 coro_wrapper_methods, /* tp_methods */
977 0, /* tp_members */
978 0, /* tp_getset */
979 0, /* tp_base */
980 0, /* tp_dict */
981 0, /* tp_descr_get */
982 0, /* tp_descr_set */
983 0, /* tp_dictoffset */
984 0, /* tp_init */
985 0, /* tp_alloc */
986 0, /* tp_new */
987 PyObject_Del, /* tp_free */
988};
989
990PyObject *
991PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
992{
993 return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
994}