1 /* Generator object implementation */
2
3 #include "Python.h"
4 #include "pycore_call.h" // _PyObject_CallNoArgs()
5 #include "pycore_ceval.h" // _PyEval_EvalFrame()
6 #include "pycore_frame.h" // _PyInterpreterFrame
7 #include "pycore_genobject.h" // struct _Py_async_gen_state
8 #include "pycore_object.h" // _PyObject_GC_UNTRACK()
9 #include "pycore_opcode.h" // _PyOpcode_Deopt
10 #include "pycore_pyerrors.h" // _PyErr_ClearExcState()
11 #include "pycore_pystate.h" // _PyThreadState_GET()
12 #include "structmember.h" // PyMemberDef
13 #include "opcode.h" // SEND
14
15 static PyObject *gen_close(PyGenObject *, PyObject *);
16 static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);
17 static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *);
18
19 static const char *NON_INIT_CORO_MSG = "can't send non-None value to a "
20 "just-started coroutine";
21
22 static const char *ASYNC_GEN_IGNORED_EXIT_MSG =
23 "async generator ignored GeneratorExit";
24
25 static inline int
exc_state_traverse(_PyErr_StackItem * exc_state,visitproc visit,void * arg)26 exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg)
27 {
28 Py_VISIT(exc_state->exc_value);
29 return 0;
30 }
31
32 static int
gen_traverse(PyGenObject * gen,visitproc visit,void * arg)33 gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
34 {
35 Py_VISIT(gen->gi_code);
36 Py_VISIT(gen->gi_name);
37 Py_VISIT(gen->gi_qualname);
38 if (gen->gi_frame_state < FRAME_CLEARED) {
39 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
40 assert(frame->frame_obj == NULL ||
41 frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR);
42 int err = _PyFrame_Traverse(frame, visit, arg);
43 if (err) {
44 return err;
45 }
46 }
47 /* No need to visit cr_origin, because it's just tuples/str/int, so can't
48 participate in a reference cycle. */
49 return exc_state_traverse(&gen->gi_exc_state, visit, arg);
50 }
51
52 void
_PyGen_Finalize(PyObject * self)53 _PyGen_Finalize(PyObject *self)
54 {
55 PyGenObject *gen = (PyGenObject *)self;
56 PyObject *res = NULL;
57 PyObject *error_type, *error_value, *error_traceback;
58
59 if (gen->gi_frame_state >= FRAME_COMPLETED) {
60 /* Generator isn't paused, so no need to close */
61 return;
62 }
63
64 if (PyAsyncGen_CheckExact(self)) {
65 PyAsyncGenObject *agen = (PyAsyncGenObject*)self;
66 PyObject *finalizer = agen->ag_origin_or_finalizer;
67 if (finalizer && !agen->ag_closed) {
68 /* Save the current exception, if any. */
69 PyErr_Fetch(&error_type, &error_value, &error_traceback);
70
71 res = PyObject_CallOneArg(finalizer, self);
72
73 if (res == NULL) {
74 PyErr_WriteUnraisable(self);
75 } else {
76 Py_DECREF(res);
77 }
78 /* Restore the saved exception. */
79 PyErr_Restore(error_type, error_value, error_traceback);
80 return;
81 }
82 }
83
84 /* Save the current exception, if any. */
85 PyErr_Fetch(&error_type, &error_value, &error_traceback);
86
87 /* If `gen` is a coroutine, and if it was never awaited on,
88 issue a RuntimeWarning. */
89 if (gen->gi_code != NULL &&
90 ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE &&
91 gen->gi_frame_state == FRAME_CREATED)
92 {
93 _PyErr_WarnUnawaitedCoroutine((PyObject *)gen);
94 }
95 else {
96 res = gen_close(gen, NULL);
97 }
98
99 if (res == NULL) {
100 if (PyErr_Occurred()) {
101 PyErr_WriteUnraisable(self);
102 }
103 }
104 else {
105 Py_DECREF(res);
106 }
107
108 /* Restore the saved exception. */
109 PyErr_Restore(error_type, error_value, error_traceback);
110 }
111
112 static void
gen_dealloc(PyGenObject * gen)113 gen_dealloc(PyGenObject *gen)
114 {
115 PyObject *self = (PyObject *) gen;
116
117 _PyObject_GC_UNTRACK(gen);
118
119 if (gen->gi_weakreflist != NULL)
120 PyObject_ClearWeakRefs(self);
121
122 _PyObject_GC_TRACK(self);
123
124 if (PyObject_CallFinalizerFromDealloc(self))
125 return; /* resurrected. :( */
126
127 _PyObject_GC_UNTRACK(self);
128 if (PyAsyncGen_CheckExact(gen)) {
129 /* We have to handle this case for asynchronous generators
130 right here, because this code has to be between UNTRACK
131 and GC_Del. */
132 Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
133 }
134 if (gen->gi_frame_state < FRAME_CLEARED) {
135 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
136 gen->gi_frame_state = FRAME_CLEARED;
137 frame->previous = NULL;
138 _PyFrame_Clear(frame);
139 }
140 if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) {
141 Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
142 }
143 Py_CLEAR(gen->gi_code);
144 Py_CLEAR(gen->gi_name);
145 Py_CLEAR(gen->gi_qualname);
146 _PyErr_ClearExcState(&gen->gi_exc_state);
147 PyObject_GC_Del(gen);
148 }
149
150 static PySendResult
gen_send_ex2(PyGenObject * gen,PyObject * arg,PyObject ** presult,int exc,int closing)151 gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
152 int exc, int closing)
153 {
154 PyThreadState *tstate = _PyThreadState_GET();
155 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
156 PyObject *result;
157
158 *presult = NULL;
159 if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) {
160 const char *msg = "can't send non-None value to a "
161 "just-started generator";
162 if (PyCoro_CheckExact(gen)) {
163 msg = NON_INIT_CORO_MSG;
164 }
165 else if (PyAsyncGen_CheckExact(gen)) {
166 msg = "can't send non-None value to a "
167 "just-started async generator";
168 }
169 PyErr_SetString(PyExc_TypeError, msg);
170 return PYGEN_ERROR;
171 }
172 if (gen->gi_frame_state == FRAME_EXECUTING) {
173 const char *msg = "generator already executing";
174 if (PyCoro_CheckExact(gen)) {
175 msg = "coroutine already executing";
176 }
177 else if (PyAsyncGen_CheckExact(gen)) {
178 msg = "async generator already executing";
179 }
180 PyErr_SetString(PyExc_ValueError, msg);
181 return PYGEN_ERROR;
182 }
183 if (gen->gi_frame_state >= FRAME_COMPLETED) {
184 if (PyCoro_CheckExact(gen) && !closing) {
185 /* `gen` is an exhausted coroutine: raise an error,
186 except when called from gen_close(), which should
187 always be a silent method. */
188 PyErr_SetString(
189 PyExc_RuntimeError,
190 "cannot reuse already awaited coroutine");
191 }
192 else if (arg && !exc) {
193 /* `gen` is an exhausted generator:
194 only return value if called from send(). */
195 *presult = Py_None;
196 Py_INCREF(*presult);
197 return PYGEN_RETURN;
198 }
199 return PYGEN_ERROR;
200 }
201
202 assert(gen->gi_frame_state < FRAME_EXECUTING);
203 /* Push arg onto the frame's value stack */
204 result = arg ? arg : Py_None;
205 Py_INCREF(result);
206 _PyFrame_StackPush(frame, result);
207
208 frame->previous = tstate->cframe->current_frame;
209
210 gen->gi_exc_state.previous_item = tstate->exc_info;
211 tstate->exc_info = &gen->gi_exc_state;
212
213 if (exc) {
214 assert(_PyErr_Occurred(tstate));
215 _PyErr_ChainStackItem(NULL);
216 }
217
218 gen->gi_frame_state = FRAME_EXECUTING;
219 result = _PyEval_EvalFrame(tstate, frame, exc);
220 if (gen->gi_frame_state == FRAME_EXECUTING) {
221 gen->gi_frame_state = FRAME_COMPLETED;
222 }
223 tstate->exc_info = gen->gi_exc_state.previous_item;
224 gen->gi_exc_state.previous_item = NULL;
225
226 assert(tstate->cframe->current_frame == frame->previous);
227 /* Don't keep the reference to previous any longer than necessary. It
228 * may keep a chain of frames alive or it could create a reference
229 * cycle. */
230 frame->previous = NULL;
231
232 /* If the generator just returned (as opposed to yielding), signal
233 * that the generator is exhausted. */
234 if (result) {
235 if (gen->gi_frame_state == FRAME_SUSPENDED) {
236 *presult = result;
237 return PYGEN_NEXT;
238 }
239 assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
240 if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) {
241 /* Return NULL if called by gen_iternext() */
242 Py_CLEAR(result);
243 }
244 }
245 else {
246 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
247 const char *msg = "generator raised StopIteration";
248 if (PyCoro_CheckExact(gen)) {
249 msg = "coroutine raised StopIteration";
250 }
251 else if (PyAsyncGen_CheckExact(gen)) {
252 msg = "async generator raised StopIteration";
253 }
254 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
255 }
256 else if (PyAsyncGen_CheckExact(gen) &&
257 PyErr_ExceptionMatches(PyExc_StopAsyncIteration))
258 {
259 /* code in `gen` raised a StopAsyncIteration error:
260 raise a RuntimeError.
261 */
262 const char *msg = "async generator raised StopAsyncIteration";
263 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
264 }
265 }
266
267 /* generator can't be rerun, so release the frame */
268 /* first clean reference cycle through stored exception traceback */
269 _PyErr_ClearExcState(&gen->gi_exc_state);
270
271 gen->gi_frame_state = FRAME_CLEARED;
272 _PyFrame_Clear(frame);
273 *presult = result;
274 return result ? PYGEN_RETURN : PYGEN_ERROR;
275 }
276
277 static PySendResult
PyGen_am_send(PyGenObject * gen,PyObject * arg,PyObject ** result)278 PyGen_am_send(PyGenObject *gen, PyObject *arg, PyObject **result)
279 {
280 return gen_send_ex2(gen, arg, result, 0, 0);
281 }
282
283 static PyObject *
gen_send_ex(PyGenObject * gen,PyObject * arg,int exc,int closing)284 gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
285 {
286 PyObject *result;
287 if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) {
288 if (PyAsyncGen_CheckExact(gen)) {
289 assert(result == Py_None);
290 PyErr_SetNone(PyExc_StopAsyncIteration);
291 }
292 else if (result == Py_None) {
293 PyErr_SetNone(PyExc_StopIteration);
294 }
295 else {
296 _PyGen_SetStopIterationValue(result);
297 }
298 Py_CLEAR(result);
299 }
300 return result;
301 }
302
303 PyDoc_STRVAR(send_doc,
304 "send(arg) -> send 'arg' into generator,\n\
305 return next yielded value or raise StopIteration.");
306
307 static PyObject *
gen_send(PyGenObject * gen,PyObject * arg)308 gen_send(PyGenObject *gen, PyObject *arg)
309 {
310 return gen_send_ex(gen, arg, 0, 0);
311 }
312
313 PyDoc_STRVAR(close_doc,
314 "close() -> raise GeneratorExit inside generator.");
315
316 /*
317 * This helper function is used by gen_close and gen_throw to
318 * close a subiterator being delegated to by yield-from.
319 */
320
321 static int
gen_close_iter(PyObject * yf)322 gen_close_iter(PyObject *yf)
323 {
324 PyObject *retval = NULL;
325
326 if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
327 retval = gen_close((PyGenObject *)yf, NULL);
328 if (retval == NULL)
329 return -1;
330 }
331 else {
332 PyObject *meth;
333 if (_PyObject_LookupAttr(yf, &_Py_ID(close), &meth) < 0) {
334 PyErr_WriteUnraisable(yf);
335 }
336 if (meth) {
337 retval = _PyObject_CallNoArgs(meth);
338 Py_DECREF(meth);
339 if (retval == NULL)
340 return -1;
341 }
342 }
343 Py_XDECREF(retval);
344 return 0;
345 }
346
347 PyObject *
_PyGen_yf(PyGenObject * gen)348 _PyGen_yf(PyGenObject *gen)
349 {
350 PyObject *yf = NULL;
351
352 if (gen->gi_frame_state < FRAME_CLEARED) {
353 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
354
355 if (gen->gi_frame_state == FRAME_CREATED) {
356 /* Return immediately if the frame didn't start yet. SEND
357 always come after LOAD_CONST: a code object should not start
358 with SEND */
359 assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND);
360 return NULL;
361 }
362 _Py_CODEUNIT next = frame->prev_instr[1];
363 if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2)
364 {
365 /* Not in a yield from */
366 return NULL;
367 }
368 yf = _PyFrame_StackPeek(frame);
369 Py_INCREF(yf);
370 }
371
372 return yf;
373 }
374
375 static PyObject *
gen_close(PyGenObject * gen,PyObject * args)376 gen_close(PyGenObject *gen, PyObject *args)
377 {
378 PyObject *retval;
379 PyObject *yf = _PyGen_yf(gen);
380 int err = 0;
381
382 if (yf) {
383 PyFrameState state = gen->gi_frame_state;
384 gen->gi_frame_state = FRAME_EXECUTING;
385 err = gen_close_iter(yf);
386 gen->gi_frame_state = state;
387 Py_DECREF(yf);
388 }
389 if (err == 0)
390 PyErr_SetNone(PyExc_GeneratorExit);
391 retval = gen_send_ex(gen, Py_None, 1, 1);
392 if (retval) {
393 const char *msg = "generator ignored GeneratorExit";
394 if (PyCoro_CheckExact(gen)) {
395 msg = "coroutine ignored GeneratorExit";
396 } else if (PyAsyncGen_CheckExact(gen)) {
397 msg = ASYNC_GEN_IGNORED_EXIT_MSG;
398 }
399 Py_DECREF(retval);
400 PyErr_SetString(PyExc_RuntimeError, msg);
401 return NULL;
402 }
403 if (PyErr_ExceptionMatches(PyExc_StopIteration)
404 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
405 PyErr_Clear(); /* ignore these errors */
406 Py_RETURN_NONE;
407 }
408 return NULL;
409 }
410
411
412 PyDoc_STRVAR(throw_doc,
413 "throw(value)\n\
414 throw(type[,value[,tb]])\n\
415 \n\
416 Raise exception in generator, return next yielded value or raise\n\
417 StopIteration.");
418
419 static PyObject *
_gen_throw(PyGenObject * gen,int close_on_genexit,PyObject * typ,PyObject * val,PyObject * tb)420 _gen_throw(PyGenObject *gen, int close_on_genexit,
421 PyObject *typ, PyObject *val, PyObject *tb)
422 {
423 PyObject *yf = _PyGen_yf(gen);
424
425 if (yf) {
426 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
427 PyObject *ret;
428 int err;
429 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&
430 close_on_genexit
431 ) {
432 /* Asynchronous generators *should not* be closed right away.
433 We have to allow some awaits to work it through, hence the
434 `close_on_genexit` parameter here.
435 */
436 PyFrameState state = gen->gi_frame_state;
437 gen->gi_frame_state = FRAME_EXECUTING;
438 err = gen_close_iter(yf);
439 gen->gi_frame_state = state;
440 Py_DECREF(yf);
441 if (err < 0)
442 return gen_send_ex(gen, Py_None, 1, 0);
443 goto throw_here;
444 }
445 if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
446 /* `yf` is a generator or a coroutine. */
447 PyThreadState *tstate = _PyThreadState_GET();
448 /* Since we are fast-tracking things by skipping the eval loop,
449 we need to update the current frame so the stack trace
450 will be reported correctly to the user. */
451 /* XXX We should probably be updating the current frame
452 somewhere in ceval.c. */
453 _PyInterpreterFrame *prev = tstate->cframe->current_frame;
454 frame->previous = prev;
455 tstate->cframe->current_frame = frame;
456 /* Close the generator that we are currently iterating with
457 'yield from' or awaiting on with 'await'. */
458 PyFrameState state = gen->gi_frame_state;
459 gen->gi_frame_state = FRAME_EXECUTING;
460 ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
461 typ, val, tb);
462 gen->gi_frame_state = state;
463 tstate->cframe->current_frame = prev;
464 frame->previous = NULL;
465 } else {
466 /* `yf` is an iterator or a coroutine-like object. */
467 PyObject *meth;
468 if (_PyObject_LookupAttr(yf, &_Py_ID(throw), &meth) < 0) {
469 Py_DECREF(yf);
470 return NULL;
471 }
472 if (meth == NULL) {
473 Py_DECREF(yf);
474 goto throw_here;
475 }
476 PyFrameState state = gen->gi_frame_state;
477 gen->gi_frame_state = FRAME_EXECUTING;
478 ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
479 gen->gi_frame_state = state;
480 Py_DECREF(meth);
481 }
482 Py_DECREF(yf);
483 if (!ret) {
484 PyObject *val;
485 /* Pop subiterator from stack */
486 assert(gen->gi_frame_state < FRAME_CLEARED);
487 ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe);
488 assert(ret == yf);
489 Py_DECREF(ret);
490 // XXX: Performing this jump ourselves is awkward and problematic.
491 // See https://github.com/python/cpython/pull/31968.
492 /* Termination repetition of SEND loop */
493 assert(_PyInterpreterFrame_LASTI(frame) >= 0);
494 /* Backup to SEND */
495 assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND);
496 int jump = _Py_OPARG(frame->prev_instr[-1]);
497 frame->prev_instr += jump - 1;
498 if (_PyGen_FetchStopIterationValue(&val) == 0) {
499 ret = gen_send(gen, val);
500 Py_DECREF(val);
501 } else {
502 ret = gen_send_ex(gen, Py_None, 1, 0);
503 }
504 }
505 return ret;
506 }
507
508 throw_here:
509 /* First, check the traceback argument, replacing None with
510 NULL. */
511 if (tb == Py_None) {
512 tb = NULL;
513 }
514 else if (tb != NULL && !PyTraceBack_Check(tb)) {
515 PyErr_SetString(PyExc_TypeError,
516 "throw() third argument must be a traceback object");
517 return NULL;
518 }
519
520 Py_INCREF(typ);
521 Py_XINCREF(val);
522 Py_XINCREF(tb);
523
524 if (PyExceptionClass_Check(typ))
525 PyErr_NormalizeException(&typ, &val, &tb);
526
527 else if (PyExceptionInstance_Check(typ)) {
528 /* Raising an instance. The value should be a dummy. */
529 if (val && val != Py_None) {
530 PyErr_SetString(PyExc_TypeError,
531 "instance exception may not have a separate value");
532 goto failed_throw;
533 }
534 else {
535 /* Normalize to raise <class>, <instance> */
536 Py_XDECREF(val);
537 val = typ;
538 typ = PyExceptionInstance_Class(typ);
539 Py_INCREF(typ);
540
541 if (tb == NULL)
542 /* Returns NULL if there's no traceback */
543 tb = PyException_GetTraceback(val);
544 }
545 }
546 else {
547 /* Not something you can raise. throw() fails. */
548 PyErr_Format(PyExc_TypeError,
549 "exceptions must be classes or instances "
550 "deriving from BaseException, not %s",
551 Py_TYPE(typ)->tp_name);
552 goto failed_throw;
553 }
554
555 PyErr_Restore(typ, val, tb);
556 return gen_send_ex(gen, Py_None, 1, 0);
557
558 failed_throw:
559 /* Didn't use our arguments, so restore their original refcounts */
560 Py_DECREF(typ);
561 Py_XDECREF(val);
562 Py_XDECREF(tb);
563 return NULL;
564 }
565
566
567 static PyObject *
gen_throw(PyGenObject * gen,PyObject * const * args,Py_ssize_t nargs)568 gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs)
569 {
570 PyObject *typ;
571 PyObject *tb = NULL;
572 PyObject *val = NULL;
573
574 if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) {
575 return NULL;
576 }
577 typ = args[0];
578 if (nargs == 3) {
579 val = args[1];
580 tb = args[2];
581 }
582 else if (nargs == 2) {
583 val = args[1];
584 }
585 return _gen_throw(gen, 1, typ, val, tb);
586 }
587
588
589 static PyObject *
gen_iternext(PyGenObject * gen)590 gen_iternext(PyGenObject *gen)
591 {
592 PyObject *result;
593 assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen));
594 if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) {
595 if (result != Py_None) {
596 _PyGen_SetStopIterationValue(result);
597 }
598 Py_CLEAR(result);
599 }
600 return result;
601 }
602
603 /*
604 * Set StopIteration with specified value. Value can be arbitrary object
605 * or NULL.
606 *
607 * Returns 0 if StopIteration is set and -1 if any other exception is set.
608 */
609 int
_PyGen_SetStopIterationValue(PyObject * value)610 _PyGen_SetStopIterationValue(PyObject *value)
611 {
612 PyObject *e;
613
614 if (value == NULL ||
615 (!PyTuple_Check(value) && !PyExceptionInstance_Check(value)))
616 {
617 /* Delay exception instantiation if we can */
618 PyErr_SetObject(PyExc_StopIteration, value);
619 return 0;
620 }
621 /* Construct an exception instance manually with
622 * PyObject_CallOneArg and pass it to PyErr_SetObject.
623 *
624 * We do this to handle a situation when "value" is a tuple, in which
625 * case PyErr_SetObject would set the value of StopIteration to
626 * the first element of the tuple.
627 *
628 * (See PyErr_SetObject/_PyErr_CreateException code for details.)
629 */
630 e = PyObject_CallOneArg(PyExc_StopIteration, value);
631 if (e == NULL) {
632 return -1;
633 }
634 PyErr_SetObject(PyExc_StopIteration, e);
635 Py_DECREF(e);
636 return 0;
637 }
638
639 /*
640 * If StopIteration exception is set, fetches its 'value'
641 * attribute if any, otherwise sets pvalue to None.
642 *
643 * Returns 0 if no exception or StopIteration is set.
644 * If any other exception is set, returns -1 and leaves
645 * pvalue unchanged.
646 */
647
648 int
_PyGen_FetchStopIterationValue(PyObject ** pvalue)649 _PyGen_FetchStopIterationValue(PyObject **pvalue)
650 {
651 PyObject *et, *ev, *tb;
652 PyObject *value = NULL;
653
654 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
655 PyErr_Fetch(&et, &ev, &tb);
656 if (ev) {
657 /* exception will usually be normalised already */
658 if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
659 value = ((PyStopIterationObject *)ev)->value;
660 Py_INCREF(value);
661 Py_DECREF(ev);
662 } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) {
663 /* Avoid normalisation and take ev as value.
664 *
665 * Normalization is required if the value is a tuple, in
666 * that case the value of StopIteration would be set to
667 * the first element of the tuple.
668 *
669 * (See _PyErr_CreateException code for details.)
670 */
671 value = ev;
672 } else {
673 /* normalisation required */
674 PyErr_NormalizeException(&et, &ev, &tb);
675 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
676 PyErr_Restore(et, ev, tb);
677 return -1;
678 }
679 value = ((PyStopIterationObject *)ev)->value;
680 Py_INCREF(value);
681 Py_DECREF(ev);
682 }
683 }
684 Py_XDECREF(et);
685 Py_XDECREF(tb);
686 } else if (PyErr_Occurred()) {
687 return -1;
688 }
689 if (value == NULL) {
690 value = Py_None;
691 Py_INCREF(value);
692 }
693 *pvalue = value;
694 return 0;
695 }
696
697 static PyObject *
gen_repr(PyGenObject * gen)698 gen_repr(PyGenObject *gen)
699 {
700 return PyUnicode_FromFormat("<generator object %S at %p>",
701 gen->gi_qualname, gen);
702 }
703
704 static PyObject *
gen_get_name(PyGenObject * op,void * Py_UNUSED (ignored))705 gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored))
706 {
707 Py_INCREF(op->gi_name);
708 return op->gi_name;
709 }
710
711 static int
gen_set_name(PyGenObject * op,PyObject * value,void * Py_UNUSED (ignored))712 gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))
713 {
714 /* Not legal to del gen.gi_name or to set it to anything
715 * other than a string object. */
716 if (value == NULL || !PyUnicode_Check(value)) {
717 PyErr_SetString(PyExc_TypeError,
718 "__name__ must be set to a string object");
719 return -1;
720 }
721 Py_INCREF(value);
722 Py_XSETREF(op->gi_name, value);
723 return 0;
724 }
725
726 static PyObject *
gen_get_qualname(PyGenObject * op,void * Py_UNUSED (ignored))727 gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored))
728 {
729 Py_INCREF(op->gi_qualname);
730 return op->gi_qualname;
731 }
732
733 static int
gen_set_qualname(PyGenObject * op,PyObject * value,void * Py_UNUSED (ignored))734 gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))
735 {
736 /* Not legal to del gen.__qualname__ or to set it to anything
737 * other than a string object. */
738 if (value == NULL || !PyUnicode_Check(value)) {
739 PyErr_SetString(PyExc_TypeError,
740 "__qualname__ must be set to a string object");
741 return -1;
742 }
743 Py_INCREF(value);
744 Py_XSETREF(op->gi_qualname, value);
745 return 0;
746 }
747
748 static PyObject *
gen_getyieldfrom(PyGenObject * gen,void * Py_UNUSED (ignored))749 gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored))
750 {
751 PyObject *yf = _PyGen_yf(gen);
752 if (yf == NULL)
753 Py_RETURN_NONE;
754 return yf;
755 }
756
757
758 static PyObject *
gen_getrunning(PyGenObject * gen,void * Py_UNUSED (ignored))759 gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored))
760 {
761 if (gen->gi_frame_state == FRAME_EXECUTING) {
762 Py_RETURN_TRUE;
763 }
764 Py_RETURN_FALSE;
765 }
766
767 static PyObject *
gen_getsuspended(PyGenObject * gen,void * Py_UNUSED (ignored))768 gen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored))
769 {
770 return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED);
771 }
772
773 static PyObject *
_gen_getframe(PyGenObject * gen,const char * const name)774 _gen_getframe(PyGenObject *gen, const char *const name)
775 {
776 if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) {
777 return NULL;
778 }
779 if (gen->gi_frame_state == FRAME_CLEARED) {
780 Py_RETURN_NONE;
781 }
782 return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));
783 }
784
785 static PyObject *
gen_getframe(PyGenObject * gen,void * Py_UNUSED (ignored))786 gen_getframe(PyGenObject *gen, void *Py_UNUSED(ignored))
787 {
788 return _gen_getframe(gen, "gi_frame");
789 }
790
791 static PyGetSetDef gen_getsetlist[] = {
792 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
793 PyDoc_STR("name of the generator")},
794 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
795 PyDoc_STR("qualified name of the generator")},
796 {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL,
797 PyDoc_STR("object being iterated by yield from, or None")},
798 {"gi_running", (getter)gen_getrunning, NULL, NULL},
799 {"gi_frame", (getter)gen_getframe, NULL, NULL},
800 {"gi_suspended", (getter)gen_getsuspended, NULL, NULL},
801 {NULL} /* Sentinel */
802 };
803
804 static PyMemberDef gen_memberlist[] = {
805 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|PY_AUDIT_READ},
806 {NULL} /* Sentinel */
807 };
808
809 static PyObject *
gen_sizeof(PyGenObject * gen,PyObject * Py_UNUSED (ignored))810 gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored))
811 {
812 Py_ssize_t res;
813 res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
814 PyCodeObject *code = gen->gi_code;
815 res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
816 return PyLong_FromSsize_t(res);
817 }
818
819 PyDoc_STRVAR(sizeof__doc__,
820 "gen.__sizeof__() -> size of gen in memory, in bytes");
821
822 static PyMethodDef gen_methods[] = {
823 {"send",(PyCFunction)gen_send, METH_O, send_doc},
824 {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, throw_doc},
825 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
826 {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
827 {NULL, NULL} /* Sentinel */
828 };
829
830 static PyAsyncMethods gen_as_async = {
831 0, /* am_await */
832 0, /* am_aiter */
833 0, /* am_anext */
834 (sendfunc)PyGen_am_send, /* am_send */
835 };
836
837
838 PyTypeObject PyGen_Type = {
839 PyVarObject_HEAD_INIT(&PyType_Type, 0)
840 "generator", /* tp_name */
841 offsetof(PyGenObject, gi_iframe) +
842 offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
843 sizeof(PyObject *), /* tp_itemsize */
844 /* methods */
845 (destructor)gen_dealloc, /* tp_dealloc */
846 0, /* tp_vectorcall_offset */
847 0, /* tp_getattr */
848 0, /* tp_setattr */
849 &gen_as_async, /* tp_as_async */
850 (reprfunc)gen_repr, /* tp_repr */
851 0, /* tp_as_number */
852 0, /* tp_as_sequence */
853 0, /* tp_as_mapping */
854 0, /* tp_hash */
855 0, /* tp_call */
856 0, /* tp_str */
857 PyObject_GenericGetAttr, /* tp_getattro */
858 0, /* tp_setattro */
859 0, /* tp_as_buffer */
860 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
861 0, /* tp_doc */
862 (traverseproc)gen_traverse, /* tp_traverse */
863 0, /* tp_clear */
864 0, /* tp_richcompare */
865 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
866 PyObject_SelfIter, /* tp_iter */
867 (iternextfunc)gen_iternext, /* tp_iternext */
868 gen_methods, /* tp_methods */
869 gen_memberlist, /* tp_members */
870 gen_getsetlist, /* tp_getset */
871 0, /* tp_base */
872 0, /* tp_dict */
873
874 0, /* tp_descr_get */
875 0, /* tp_descr_set */
876 0, /* tp_dictoffset */
877 0, /* tp_init */
878 0, /* tp_alloc */
879 0, /* tp_new */
880 0, /* tp_free */
881 0, /* tp_is_gc */
882 0, /* tp_bases */
883 0, /* tp_mro */
884 0, /* tp_cache */
885 0, /* tp_subclasses */
886 0, /* tp_weaklist */
887 0, /* tp_del */
888 0, /* tp_version_tag */
889 _PyGen_Finalize, /* tp_finalize */
890 };
891
892 static PyObject *
make_gen(PyTypeObject * type,PyFunctionObject * func)893 make_gen(PyTypeObject *type, PyFunctionObject *func)
894 {
895 PyCodeObject *code = (PyCodeObject *)func->func_code;
896 int slots = code->co_nlocalsplus + code->co_stacksize;
897 PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots);
898 if (gen == NULL) {
899 return NULL;
900 }
901 gen->gi_frame_state = FRAME_CLEARED;
902 gen->gi_code = (PyCodeObject *)func->func_code;
903 Py_INCREF(gen->gi_code);
904 gen->gi_weakreflist = NULL;
905 gen->gi_exc_state.exc_value = NULL;
906 gen->gi_exc_state.previous_item = NULL;
907 assert(func->func_name != NULL);
908 gen->gi_name = Py_NewRef(func->func_name);
909 assert(func->func_qualname != NULL);
910 gen->gi_qualname = Py_NewRef(func->func_qualname);
911 _PyObject_GC_TRACK(gen);
912 return (PyObject *)gen;
913 }
914
915 static PyObject *
916 compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame);
917
918 PyObject *
_Py_MakeCoro(PyFunctionObject * func)919 _Py_MakeCoro(PyFunctionObject *func)
920 {
921 int coro_flags = ((PyCodeObject *)func->func_code)->co_flags &
922 (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
923 assert(coro_flags);
924 if (coro_flags == CO_GENERATOR) {
925 return make_gen(&PyGen_Type, func);
926 }
927 if (coro_flags == CO_ASYNC_GENERATOR) {
928 PyAsyncGenObject *o;
929 o = (PyAsyncGenObject *)make_gen(&PyAsyncGen_Type, func);
930 if (o == NULL) {
931 return NULL;
932 }
933 o->ag_origin_or_finalizer = NULL;
934 o->ag_closed = 0;
935 o->ag_hooks_inited = 0;
936 o->ag_running_async = 0;
937 return (PyObject*)o;
938 }
939 assert (coro_flags == CO_COROUTINE);
940 PyObject *coro = make_gen(&PyCoro_Type, func);
941 if (!coro) {
942 return NULL;
943 }
944 PyThreadState *tstate = _PyThreadState_GET();
945 int origin_depth = tstate->coroutine_origin_tracking_depth;
946
947 if (origin_depth == 0) {
948 ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
949 } else {
950 assert(_PyEval_GetFrame());
951 PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()->previous);
952 ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
953 if (!cr_origin) {
954 Py_DECREF(coro);
955 return NULL;
956 }
957 }
958 return coro;
959 }
960
961 static PyObject *
gen_new_with_qualname(PyTypeObject * type,PyFrameObject * f,PyObject * name,PyObject * qualname)962 gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
963 PyObject *name, PyObject *qualname)
964 {
965 PyCodeObject *code = f->f_frame->f_code;
966 int size = code->co_nlocalsplus + code->co_stacksize;
967 PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, size);
968 if (gen == NULL) {
969 Py_DECREF(f);
970 return NULL;
971 }
972 /* Copy the frame */
973 assert(f->f_frame->frame_obj == NULL);
974 assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
975 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
976 _PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame);
977 gen->gi_frame_state = FRAME_CREATED;
978 assert(frame->frame_obj == f);
979 f->f_frame = frame;
980 frame->owner = FRAME_OWNED_BY_GENERATOR;
981 assert(PyObject_GC_IsTracked((PyObject *)f));
982 gen->gi_code = PyFrame_GetCode(f);
983 Py_INCREF(gen->gi_code);
984 Py_DECREF(f);
985 gen->gi_weakreflist = NULL;
986 gen->gi_exc_state.exc_value = NULL;
987 gen->gi_exc_state.previous_item = NULL;
988 if (name != NULL)
989 gen->gi_name = name;
990 else
991 gen->gi_name = gen->gi_code->co_name;
992 Py_INCREF(gen->gi_name);
993 if (qualname != NULL)
994 gen->gi_qualname = qualname;
995 else
996 gen->gi_qualname = gen->gi_code->co_qualname;
997 Py_INCREF(gen->gi_qualname);
998 _PyObject_GC_TRACK(gen);
999 return (PyObject *)gen;
1000 }
1001
1002 PyObject *
PyGen_NewWithQualName(PyFrameObject * f,PyObject * name,PyObject * qualname)1003 PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
1004 {
1005 return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
1006 }
1007
1008 PyObject *
PyGen_New(PyFrameObject * f)1009 PyGen_New(PyFrameObject *f)
1010 {
1011 return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
1012 }
1013
1014 /* Coroutine Object */
1015
1016 typedef struct {
1017 PyObject_HEAD
1018 PyCoroObject *cw_coroutine;
1019 } PyCoroWrapper;
1020
1021 static int
gen_is_coroutine(PyObject * o)1022 gen_is_coroutine(PyObject *o)
1023 {
1024 if (PyGen_CheckExact(o)) {
1025 PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
1026 if (code->co_flags & CO_ITERABLE_COROUTINE) {
1027 return 1;
1028 }
1029 }
1030 return 0;
1031 }
1032
1033 /*
1034 * This helper function returns an awaitable for `o`:
1035 * - `o` if `o` is a coroutine-object;
1036 * - `type(o)->tp_as_async->am_await(o)`
1037 *
1038 * Raises a TypeError if it's not possible to return
1039 * an awaitable and returns NULL.
1040 */
1041 PyObject *
_PyCoro_GetAwaitableIter(PyObject * o)1042 _PyCoro_GetAwaitableIter(PyObject *o)
1043 {
1044 unaryfunc getter = NULL;
1045 PyTypeObject *ot;
1046
1047 if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
1048 /* 'o' is a coroutine. */
1049 Py_INCREF(o);
1050 return o;
1051 }
1052
1053 ot = Py_TYPE(o);
1054 if (ot->tp_as_async != NULL) {
1055 getter = ot->tp_as_async->am_await;
1056 }
1057 if (getter != NULL) {
1058 PyObject *res = (*getter)(o);
1059 if (res != NULL) {
1060 if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
1061 /* __await__ must return an *iterator*, not
1062 a coroutine or another awaitable (see PEP 492) */
1063 PyErr_SetString(PyExc_TypeError,
1064 "__await__() returned a coroutine");
1065 Py_CLEAR(res);
1066 } else if (!PyIter_Check(res)) {
1067 PyErr_Format(PyExc_TypeError,
1068 "__await__() returned non-iterator "
1069 "of type '%.100s'",
1070 Py_TYPE(res)->tp_name);
1071 Py_CLEAR(res);
1072 }
1073 }
1074 return res;
1075 }
1076
1077 PyErr_Format(PyExc_TypeError,
1078 "object %.100s can't be used in 'await' expression",
1079 ot->tp_name);
1080 return NULL;
1081 }
1082
1083 static PyObject *
coro_repr(PyCoroObject * coro)1084 coro_repr(PyCoroObject *coro)
1085 {
1086 return PyUnicode_FromFormat("<coroutine object %S at %p>",
1087 coro->cr_qualname, coro);
1088 }
1089
1090 static PyObject *
coro_await(PyCoroObject * coro)1091 coro_await(PyCoroObject *coro)
1092 {
1093 PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
1094 if (cw == NULL) {
1095 return NULL;
1096 }
1097 Py_INCREF(coro);
1098 cw->cw_coroutine = coro;
1099 _PyObject_GC_TRACK(cw);
1100 return (PyObject *)cw;
1101 }
1102
1103 static PyObject *
coro_get_cr_await(PyCoroObject * coro,void * Py_UNUSED (ignored))1104 coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored))
1105 {
1106 PyObject *yf = _PyGen_yf((PyGenObject *) coro);
1107 if (yf == NULL)
1108 Py_RETURN_NONE;
1109 return yf;
1110 }
1111
1112 static PyObject *
cr_getsuspended(PyCoroObject * coro,void * Py_UNUSED (ignored))1113 cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored))
1114 {
1115 if (coro->cr_frame_state == FRAME_SUSPENDED) {
1116 Py_RETURN_TRUE;
1117 }
1118 Py_RETURN_FALSE;
1119 }
1120
1121 static PyObject *
cr_getrunning(PyCoroObject * coro,void * Py_UNUSED (ignored))1122 cr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored))
1123 {
1124 if (coro->cr_frame_state == FRAME_EXECUTING) {
1125 Py_RETURN_TRUE;
1126 }
1127 Py_RETURN_FALSE;
1128 }
1129
1130 static PyObject *
cr_getframe(PyCoroObject * coro,void * Py_UNUSED (ignored))1131 cr_getframe(PyCoroObject *coro, void *Py_UNUSED(ignored))
1132 {
1133 return _gen_getframe((PyGenObject *)coro, "cr_frame");
1134 }
1135
1136
1137 static PyGetSetDef coro_getsetlist[] = {
1138 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
1139 PyDoc_STR("name of the coroutine")},
1140 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
1141 PyDoc_STR("qualified name of the coroutine")},
1142 {"cr_await", (getter)coro_get_cr_await, NULL,
1143 PyDoc_STR("object being awaited on, or None")},
1144 {"cr_running", (getter)cr_getrunning, NULL, NULL},
1145 {"cr_frame", (getter)cr_getframe, NULL, NULL},
1146 {"cr_suspended", (getter)cr_getsuspended, NULL, NULL},
1147 {NULL} /* Sentinel */
1148 };
1149
1150 static PyMemberDef coro_memberlist[] = {
1151 {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|PY_AUDIT_READ},
1152 {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), READONLY},
1153 {NULL} /* Sentinel */
1154 };
1155
1156 PyDoc_STRVAR(coro_send_doc,
1157 "send(arg) -> send 'arg' into coroutine,\n\
1158 return next iterated value or raise StopIteration.");
1159
1160 PyDoc_STRVAR(coro_throw_doc,
1161 "throw(value)\n\
1162 throw(type[,value[,traceback]])\n\
1163 \n\
1164 Raise exception in coroutine, return next iterated value or raise\n\
1165 StopIteration.");
1166
1167 PyDoc_STRVAR(coro_close_doc,
1168 "close() -> raise GeneratorExit inside coroutine.");
1169
1170 static PyMethodDef coro_methods[] = {
1171 {"send",(PyCFunction)gen_send, METH_O, coro_send_doc},
1172 {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, coro_throw_doc},
1173 {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
1174 {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
1175 {NULL, NULL} /* Sentinel */
1176 };
1177
1178 static PyAsyncMethods coro_as_async = {
1179 (unaryfunc)coro_await, /* am_await */
1180 0, /* am_aiter */
1181 0, /* am_anext */
1182 (sendfunc)PyGen_am_send, /* am_send */
1183 };
1184
1185 PyTypeObject PyCoro_Type = {
1186 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1187 "coroutine", /* tp_name */
1188 offsetof(PyCoroObject, cr_iframe) +
1189 offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
1190 sizeof(PyObject *), /* tp_itemsize */
1191 /* methods */
1192 (destructor)gen_dealloc, /* tp_dealloc */
1193 0, /* tp_vectorcall_offset */
1194 0, /* tp_getattr */
1195 0, /* tp_setattr */
1196 &coro_as_async, /* tp_as_async */
1197 (reprfunc)coro_repr, /* tp_repr */
1198 0, /* tp_as_number */
1199 0, /* tp_as_sequence */
1200 0, /* tp_as_mapping */
1201 0, /* tp_hash */
1202 0, /* tp_call */
1203 0, /* tp_str */
1204 PyObject_GenericGetAttr, /* tp_getattro */
1205 0, /* tp_setattro */
1206 0, /* tp_as_buffer */
1207 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1208 0, /* tp_doc */
1209 (traverseproc)gen_traverse, /* tp_traverse */
1210 0, /* tp_clear */
1211 0, /* tp_richcompare */
1212 offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
1213 0, /* tp_iter */
1214 0, /* tp_iternext */
1215 coro_methods, /* tp_methods */
1216 coro_memberlist, /* tp_members */
1217 coro_getsetlist, /* tp_getset */
1218 0, /* tp_base */
1219 0, /* tp_dict */
1220 0, /* tp_descr_get */
1221 0, /* tp_descr_set */
1222 0, /* tp_dictoffset */
1223 0, /* tp_init */
1224 0, /* tp_alloc */
1225 0, /* tp_new */
1226 0, /* tp_free */
1227 0, /* tp_is_gc */
1228 0, /* tp_bases */
1229 0, /* tp_mro */
1230 0, /* tp_cache */
1231 0, /* tp_subclasses */
1232 0, /* tp_weaklist */
1233 0, /* tp_del */
1234 0, /* tp_version_tag */
1235 _PyGen_Finalize, /* tp_finalize */
1236 };
1237
1238 static void
coro_wrapper_dealloc(PyCoroWrapper * cw)1239 coro_wrapper_dealloc(PyCoroWrapper *cw)
1240 {
1241 _PyObject_GC_UNTRACK((PyObject *)cw);
1242 Py_CLEAR(cw->cw_coroutine);
1243 PyObject_GC_Del(cw);
1244 }
1245
1246 static PyObject *
coro_wrapper_iternext(PyCoroWrapper * cw)1247 coro_wrapper_iternext(PyCoroWrapper *cw)
1248 {
1249 return gen_iternext((PyGenObject *)cw->cw_coroutine);
1250 }
1251
1252 static PyObject *
coro_wrapper_send(PyCoroWrapper * cw,PyObject * arg)1253 coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
1254 {
1255 return gen_send((PyGenObject *)cw->cw_coroutine, arg);
1256 }
1257
1258 static PyObject *
coro_wrapper_throw(PyCoroWrapper * cw,PyObject * const * args,Py_ssize_t nargs)1259 coro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs)
1260 {
1261 return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs);
1262 }
1263
1264 static PyObject *
coro_wrapper_close(PyCoroWrapper * cw,PyObject * args)1265 coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
1266 {
1267 return gen_close((PyGenObject *)cw->cw_coroutine, args);
1268 }
1269
1270 static int
coro_wrapper_traverse(PyCoroWrapper * cw,visitproc visit,void * arg)1271 coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
1272 {
1273 Py_VISIT((PyObject *)cw->cw_coroutine);
1274 return 0;
1275 }
1276
1277 static PyMethodDef coro_wrapper_methods[] = {
1278 {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
1279 {"throw",_PyCFunction_CAST(coro_wrapper_throw),
1280 METH_FASTCALL, coro_throw_doc},
1281 {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
1282 {NULL, NULL} /* Sentinel */
1283 };
1284
1285 PyTypeObject _PyCoroWrapper_Type = {
1286 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1287 "coroutine_wrapper",
1288 sizeof(PyCoroWrapper), /* tp_basicsize */
1289 0, /* tp_itemsize */
1290 (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
1291 0, /* tp_vectorcall_offset */
1292 0, /* tp_getattr */
1293 0, /* tp_setattr */
1294 0, /* tp_as_async */
1295 0, /* tp_repr */
1296 0, /* tp_as_number */
1297 0, /* tp_as_sequence */
1298 0, /* tp_as_mapping */
1299 0, /* tp_hash */
1300 0, /* tp_call */
1301 0, /* tp_str */
1302 PyObject_GenericGetAttr, /* tp_getattro */
1303 0, /* tp_setattro */
1304 0, /* tp_as_buffer */
1305 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1306 "A wrapper object implementing __await__ for coroutines.",
1307 (traverseproc)coro_wrapper_traverse, /* tp_traverse */
1308 0, /* tp_clear */
1309 0, /* tp_richcompare */
1310 0, /* tp_weaklistoffset */
1311 PyObject_SelfIter, /* tp_iter */
1312 (iternextfunc)coro_wrapper_iternext, /* tp_iternext */
1313 coro_wrapper_methods, /* tp_methods */
1314 0, /* tp_members */
1315 0, /* tp_getset */
1316 0, /* tp_base */
1317 0, /* tp_dict */
1318 0, /* tp_descr_get */
1319 0, /* tp_descr_set */
1320 0, /* tp_dictoffset */
1321 0, /* tp_init */
1322 0, /* tp_alloc */
1323 0, /* tp_new */
1324 0, /* tp_free */
1325 };
1326
1327 static PyObject *
compute_cr_origin(int origin_depth,_PyInterpreterFrame * current_frame)1328 compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame)
1329 {
1330 _PyInterpreterFrame *frame = current_frame;
1331 /* First count how many frames we have */
1332 int frame_count = 0;
1333 for (; frame && frame_count < origin_depth; ++frame_count) {
1334 frame = frame->previous;
1335 }
1336
1337 /* Now collect them */
1338 PyObject *cr_origin = PyTuple_New(frame_count);
1339 if (cr_origin == NULL) {
1340 return NULL;
1341 }
1342 frame = current_frame;
1343 for (int i = 0; i < frame_count; ++i) {
1344 PyCodeObject *code = frame->f_code;
1345 int line = _PyInterpreterFrame_GetLine(frame);
1346 PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line,
1347 code->co_name);
1348 if (!frameinfo) {
1349 Py_DECREF(cr_origin);
1350 return NULL;
1351 }
1352 PyTuple_SET_ITEM(cr_origin, i, frameinfo);
1353 frame = frame->previous;
1354 }
1355
1356 return cr_origin;
1357 }
1358
1359 PyObject *
PyCoro_New(PyFrameObject * f,PyObject * name,PyObject * qualname)1360 PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1361 {
1362 PyObject *coro = gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
1363 if (!coro) {
1364 return NULL;
1365 }
1366
1367 PyThreadState *tstate = _PyThreadState_GET();
1368 int origin_depth = tstate->coroutine_origin_tracking_depth;
1369
1370 if (origin_depth == 0) {
1371 ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
1372 } else {
1373 PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame());
1374 ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
1375 if (!cr_origin) {
1376 Py_DECREF(coro);
1377 return NULL;
1378 }
1379 }
1380
1381 return coro;
1382 }
1383
1384
1385 /* ========= Asynchronous Generators ========= */
1386
1387
1388 typedef enum {
1389 AWAITABLE_STATE_INIT, /* new awaitable, has not yet been iterated */
1390 AWAITABLE_STATE_ITER, /* being iterated */
1391 AWAITABLE_STATE_CLOSED, /* closed */
1392 } AwaitableState;
1393
1394
1395 typedef struct PyAsyncGenASend {
1396 PyObject_HEAD
1397 PyAsyncGenObject *ags_gen;
1398
1399 /* Can be NULL, when in the __anext__() mode
1400 (equivalent of "asend(None)") */
1401 PyObject *ags_sendval;
1402
1403 AwaitableState ags_state;
1404 } PyAsyncGenASend;
1405
1406
1407 typedef struct PyAsyncGenAThrow {
1408 PyObject_HEAD
1409 PyAsyncGenObject *agt_gen;
1410
1411 /* Can be NULL, when in the "aclose()" mode
1412 (equivalent of "athrow(GeneratorExit)") */
1413 PyObject *agt_args;
1414
1415 AwaitableState agt_state;
1416 } PyAsyncGenAThrow;
1417
1418
1419 typedef struct _PyAsyncGenWrappedValue {
1420 PyObject_HEAD
1421 PyObject *agw_val;
1422 } _PyAsyncGenWrappedValue;
1423
1424
1425 #define _PyAsyncGenWrappedValue_CheckExact(o) \
1426 Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type)
1427
1428 #define PyAsyncGenASend_CheckExact(o) \
1429 Py_IS_TYPE(o, &_PyAsyncGenASend_Type)
1430
1431
1432 static int
async_gen_traverse(PyAsyncGenObject * gen,visitproc visit,void * arg)1433 async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg)
1434 {
1435 Py_VISIT(gen->ag_origin_or_finalizer);
1436 return gen_traverse((PyGenObject*)gen, visit, arg);
1437 }
1438
1439
1440 static PyObject *
async_gen_repr(PyAsyncGenObject * o)1441 async_gen_repr(PyAsyncGenObject *o)
1442 {
1443 return PyUnicode_FromFormat("<async_generator object %S at %p>",
1444 o->ag_qualname, o);
1445 }
1446
1447
1448 static int
async_gen_init_hooks(PyAsyncGenObject * o)1449 async_gen_init_hooks(PyAsyncGenObject *o)
1450 {
1451 PyThreadState *tstate;
1452 PyObject *finalizer;
1453 PyObject *firstiter;
1454
1455 if (o->ag_hooks_inited) {
1456 return 0;
1457 }
1458
1459 o->ag_hooks_inited = 1;
1460
1461 tstate = _PyThreadState_GET();
1462
1463 finalizer = tstate->async_gen_finalizer;
1464 if (finalizer) {
1465 Py_INCREF(finalizer);
1466 o->ag_origin_or_finalizer = finalizer;
1467 }
1468
1469 firstiter = tstate->async_gen_firstiter;
1470 if (firstiter) {
1471 PyObject *res;
1472
1473 Py_INCREF(firstiter);
1474 res = PyObject_CallOneArg(firstiter, (PyObject *)o);
1475 Py_DECREF(firstiter);
1476 if (res == NULL) {
1477 return 1;
1478 }
1479 Py_DECREF(res);
1480 }
1481
1482 return 0;
1483 }
1484
1485
1486 static PyObject *
async_gen_anext(PyAsyncGenObject * o)1487 async_gen_anext(PyAsyncGenObject *o)
1488 {
1489 if (async_gen_init_hooks(o)) {
1490 return NULL;
1491 }
1492 return async_gen_asend_new(o, NULL);
1493 }
1494
1495
1496 static PyObject *
async_gen_asend(PyAsyncGenObject * o,PyObject * arg)1497 async_gen_asend(PyAsyncGenObject *o, PyObject *arg)
1498 {
1499 if (async_gen_init_hooks(o)) {
1500 return NULL;
1501 }
1502 return async_gen_asend_new(o, arg);
1503 }
1504
1505
1506 static PyObject *
async_gen_aclose(PyAsyncGenObject * o,PyObject * arg)1507 async_gen_aclose(PyAsyncGenObject *o, PyObject *arg)
1508 {
1509 if (async_gen_init_hooks(o)) {
1510 return NULL;
1511 }
1512 return async_gen_athrow_new(o, NULL);
1513 }
1514
1515 static PyObject *
async_gen_athrow(PyAsyncGenObject * o,PyObject * args)1516 async_gen_athrow(PyAsyncGenObject *o, PyObject *args)
1517 {
1518 if (async_gen_init_hooks(o)) {
1519 return NULL;
1520 }
1521 return async_gen_athrow_new(o, args);
1522 }
1523
1524 static PyObject *
ag_getframe(PyAsyncGenObject * ag,void * Py_UNUSED (ignored))1525 ag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored))
1526 {
1527 return _gen_getframe((PyGenObject *)ag, "ag_frame");
1528 }
1529
1530 static PyGetSetDef async_gen_getsetlist[] = {
1531 {"__name__", (getter)gen_get_name, (setter)gen_set_name,
1532 PyDoc_STR("name of the async generator")},
1533 {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
1534 PyDoc_STR("qualified name of the async generator")},
1535 {"ag_await", (getter)coro_get_cr_await, NULL,
1536 PyDoc_STR("object being awaited on, or None")},
1537 {"ag_frame", (getter)ag_getframe, NULL, NULL},
1538 {NULL} /* Sentinel */
1539 };
1540
1541 static PyMemberDef async_gen_memberlist[] = {
1542 {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async),
1543 READONLY},
1544 {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|PY_AUDIT_READ},
1545 {NULL} /* Sentinel */
1546 };
1547
1548 PyDoc_STRVAR(async_aclose_doc,
1549 "aclose() -> raise GeneratorExit inside generator.");
1550
1551 PyDoc_STRVAR(async_asend_doc,
1552 "asend(v) -> send 'v' in generator.");
1553
1554 PyDoc_STRVAR(async_athrow_doc,
1555 "athrow(typ[,val[,tb]]) -> raise exception in generator.");
1556
1557 static PyMethodDef async_gen_methods[] = {
1558 {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc},
1559 {"athrow",(PyCFunction)async_gen_athrow, METH_VARARGS, async_athrow_doc},
1560 {"aclose", (PyCFunction)async_gen_aclose, METH_NOARGS, async_aclose_doc},
1561 {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
1562 {"__class_getitem__", Py_GenericAlias,
1563 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
1564 {NULL, NULL} /* Sentinel */
1565 };
1566
1567
1568 static PyAsyncMethods async_gen_as_async = {
1569 0, /* am_await */
1570 PyObject_SelfIter, /* am_aiter */
1571 (unaryfunc)async_gen_anext, /* am_anext */
1572 (sendfunc)PyGen_am_send, /* am_send */
1573 };
1574
1575
1576 PyTypeObject PyAsyncGen_Type = {
1577 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1578 "async_generator", /* tp_name */
1579 offsetof(PyAsyncGenObject, ag_iframe) +
1580 offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
1581 sizeof(PyObject *), /* tp_itemsize */
1582 /* methods */
1583 (destructor)gen_dealloc, /* tp_dealloc */
1584 0, /* tp_vectorcall_offset */
1585 0, /* tp_getattr */
1586 0, /* tp_setattr */
1587 &async_gen_as_async, /* tp_as_async */
1588 (reprfunc)async_gen_repr, /* tp_repr */
1589 0, /* tp_as_number */
1590 0, /* tp_as_sequence */
1591 0, /* tp_as_mapping */
1592 0, /* tp_hash */
1593 0, /* tp_call */
1594 0, /* tp_str */
1595 PyObject_GenericGetAttr, /* tp_getattro */
1596 0, /* tp_setattro */
1597 0, /* tp_as_buffer */
1598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1599 0, /* tp_doc */
1600 (traverseproc)async_gen_traverse, /* tp_traverse */
1601 0, /* tp_clear */
1602 0, /* tp_richcompare */
1603 offsetof(PyAsyncGenObject, ag_weakreflist), /* tp_weaklistoffset */
1604 0, /* tp_iter */
1605 0, /* tp_iternext */
1606 async_gen_methods, /* tp_methods */
1607 async_gen_memberlist, /* tp_members */
1608 async_gen_getsetlist, /* tp_getset */
1609 0, /* tp_base */
1610 0, /* tp_dict */
1611 0, /* tp_descr_get */
1612 0, /* tp_descr_set */
1613 0, /* tp_dictoffset */
1614 0, /* tp_init */
1615 0, /* tp_alloc */
1616 0, /* tp_new */
1617 0, /* tp_free */
1618 0, /* tp_is_gc */
1619 0, /* tp_bases */
1620 0, /* tp_mro */
1621 0, /* tp_cache */
1622 0, /* tp_subclasses */
1623 0, /* tp_weaklist */
1624 0, /* tp_del */
1625 0, /* tp_version_tag */
1626 _PyGen_Finalize, /* tp_finalize */
1627 };
1628
1629
1630 #if _PyAsyncGen_MAXFREELIST > 0
1631 static struct _Py_async_gen_state *
get_async_gen_state(void)1632 get_async_gen_state(void)
1633 {
1634 PyInterpreterState *interp = _PyInterpreterState_GET();
1635 return &interp->async_gen;
1636 }
1637 #endif
1638
1639
1640 PyObject *
PyAsyncGen_New(PyFrameObject * f,PyObject * name,PyObject * qualname)1641 PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1642 {
1643 PyAsyncGenObject *o;
1644 o = (PyAsyncGenObject *)gen_new_with_qualname(
1645 &PyAsyncGen_Type, f, name, qualname);
1646 if (o == NULL) {
1647 return NULL;
1648 }
1649 o->ag_origin_or_finalizer = NULL;
1650 o->ag_closed = 0;
1651 o->ag_hooks_inited = 0;
1652 o->ag_running_async = 0;
1653 return (PyObject*)o;
1654 }
1655
1656
1657 void
_PyAsyncGen_ClearFreeLists(PyInterpreterState * interp)1658 _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp)
1659 {
1660 #if _PyAsyncGen_MAXFREELIST > 0
1661 struct _Py_async_gen_state *state = &interp->async_gen;
1662
1663 while (state->value_numfree) {
1664 _PyAsyncGenWrappedValue *o;
1665 o = state->value_freelist[--state->value_numfree];
1666 assert(_PyAsyncGenWrappedValue_CheckExact(o));
1667 PyObject_GC_Del(o);
1668 }
1669
1670 while (state->asend_numfree) {
1671 PyAsyncGenASend *o;
1672 o = state->asend_freelist[--state->asend_numfree];
1673 assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type));
1674 PyObject_GC_Del(o);
1675 }
1676 #endif
1677 }
1678
1679 void
_PyAsyncGen_Fini(PyInterpreterState * interp)1680 _PyAsyncGen_Fini(PyInterpreterState *interp)
1681 {
1682 _PyAsyncGen_ClearFreeLists(interp);
1683 #if defined(Py_DEBUG) && _PyAsyncGen_MAXFREELIST > 0
1684 struct _Py_async_gen_state *state = &interp->async_gen;
1685 state->value_numfree = -1;
1686 state->asend_numfree = -1;
1687 #endif
1688 }
1689
1690
1691 static PyObject *
async_gen_unwrap_value(PyAsyncGenObject * gen,PyObject * result)1692 async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)
1693 {
1694 if (result == NULL) {
1695 if (!PyErr_Occurred()) {
1696 PyErr_SetNone(PyExc_StopAsyncIteration);
1697 }
1698
1699 if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)
1700 || PyErr_ExceptionMatches(PyExc_GeneratorExit)
1701 ) {
1702 gen->ag_closed = 1;
1703 }
1704
1705 gen->ag_running_async = 0;
1706 return NULL;
1707 }
1708
1709 if (_PyAsyncGenWrappedValue_CheckExact(result)) {
1710 /* async yield */
1711 _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val);
1712 Py_DECREF(result);
1713 gen->ag_running_async = 0;
1714 return NULL;
1715 }
1716
1717 return result;
1718 }
1719
1720
1721 /* ---------- Async Generator ASend Awaitable ------------ */
1722
1723
1724 static void
async_gen_asend_dealloc(PyAsyncGenASend * o)1725 async_gen_asend_dealloc(PyAsyncGenASend *o)
1726 {
1727 _PyObject_GC_UNTRACK((PyObject *)o);
1728 Py_CLEAR(o->ags_gen);
1729 Py_CLEAR(o->ags_sendval);
1730 #if _PyAsyncGen_MAXFREELIST > 0
1731 struct _Py_async_gen_state *state = get_async_gen_state();
1732 #ifdef Py_DEBUG
1733 // async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini()
1734 assert(state->asend_numfree != -1);
1735 #endif
1736 if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
1737 assert(PyAsyncGenASend_CheckExact(o));
1738 state->asend_freelist[state->asend_numfree++] = o;
1739 }
1740 else
1741 #endif
1742 {
1743 PyObject_GC_Del(o);
1744 }
1745 }
1746
1747 static int
async_gen_asend_traverse(PyAsyncGenASend * o,visitproc visit,void * arg)1748 async_gen_asend_traverse(PyAsyncGenASend *o, visitproc visit, void *arg)
1749 {
1750 Py_VISIT(o->ags_gen);
1751 Py_VISIT(o->ags_sendval);
1752 return 0;
1753 }
1754
1755
1756 static PyObject *
async_gen_asend_send(PyAsyncGenASend * o,PyObject * arg)1757 async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
1758 {
1759 PyObject *result;
1760
1761 if (o->ags_state == AWAITABLE_STATE_CLOSED) {
1762 PyErr_SetString(
1763 PyExc_RuntimeError,
1764 "cannot reuse already awaited __anext__()/asend()");
1765 return NULL;
1766 }
1767
1768 if (o->ags_state == AWAITABLE_STATE_INIT) {
1769 if (o->ags_gen->ag_running_async) {
1770 PyErr_SetString(
1771 PyExc_RuntimeError,
1772 "anext(): asynchronous generator is already running");
1773 return NULL;
1774 }
1775
1776 if (arg == NULL || arg == Py_None) {
1777 arg = o->ags_sendval;
1778 }
1779 o->ags_state = AWAITABLE_STATE_ITER;
1780 }
1781
1782 o->ags_gen->ag_running_async = 1;
1783 result = gen_send((PyGenObject*)o->ags_gen, arg);
1784 result = async_gen_unwrap_value(o->ags_gen, result);
1785
1786 if (result == NULL) {
1787 o->ags_state = AWAITABLE_STATE_CLOSED;
1788 }
1789
1790 return result;
1791 }
1792
1793
1794 static PyObject *
async_gen_asend_iternext(PyAsyncGenASend * o)1795 async_gen_asend_iternext(PyAsyncGenASend *o)
1796 {
1797 return async_gen_asend_send(o, NULL);
1798 }
1799
1800
1801 static PyObject *
async_gen_asend_throw(PyAsyncGenASend * o,PyObject * const * args,Py_ssize_t nargs)1802 async_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs)
1803 {
1804 PyObject *result;
1805
1806 if (o->ags_state == AWAITABLE_STATE_CLOSED) {
1807 PyErr_SetString(
1808 PyExc_RuntimeError,
1809 "cannot reuse already awaited __anext__()/asend()");
1810 return NULL;
1811 }
1812
1813 result = gen_throw((PyGenObject*)o->ags_gen, args, nargs);
1814 result = async_gen_unwrap_value(o->ags_gen, result);
1815
1816 if (result == NULL) {
1817 o->ags_state = AWAITABLE_STATE_CLOSED;
1818 }
1819
1820 return result;
1821 }
1822
1823
1824 static PyObject *
async_gen_asend_close(PyAsyncGenASend * o,PyObject * args)1825 async_gen_asend_close(PyAsyncGenASend *o, PyObject *args)
1826 {
1827 o->ags_state = AWAITABLE_STATE_CLOSED;
1828 Py_RETURN_NONE;
1829 }
1830
1831
1832 static PyMethodDef async_gen_asend_methods[] = {
1833 {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc},
1834 {"throw", _PyCFunction_CAST(async_gen_asend_throw), METH_FASTCALL, throw_doc},
1835 {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc},
1836 {NULL, NULL} /* Sentinel */
1837 };
1838
1839
1840 static PyAsyncMethods async_gen_asend_as_async = {
1841 PyObject_SelfIter, /* am_await */
1842 0, /* am_aiter */
1843 0, /* am_anext */
1844 0, /* am_send */
1845 };
1846
1847
1848 PyTypeObject _PyAsyncGenASend_Type = {
1849 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1850 "async_generator_asend", /* tp_name */
1851 sizeof(PyAsyncGenASend), /* tp_basicsize */
1852 0, /* tp_itemsize */
1853 /* methods */
1854 (destructor)async_gen_asend_dealloc, /* tp_dealloc */
1855 0, /* tp_vectorcall_offset */
1856 0, /* tp_getattr */
1857 0, /* tp_setattr */
1858 &async_gen_asend_as_async, /* tp_as_async */
1859 0, /* tp_repr */
1860 0, /* tp_as_number */
1861 0, /* tp_as_sequence */
1862 0, /* tp_as_mapping */
1863 0, /* tp_hash */
1864 0, /* tp_call */
1865 0, /* tp_str */
1866 PyObject_GenericGetAttr, /* tp_getattro */
1867 0, /* tp_setattro */
1868 0, /* tp_as_buffer */
1869 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1870 0, /* tp_doc */
1871 (traverseproc)async_gen_asend_traverse, /* tp_traverse */
1872 0, /* tp_clear */
1873 0, /* tp_richcompare */
1874 0, /* tp_weaklistoffset */
1875 PyObject_SelfIter, /* tp_iter */
1876 (iternextfunc)async_gen_asend_iternext, /* tp_iternext */
1877 async_gen_asend_methods, /* tp_methods */
1878 0, /* tp_members */
1879 0, /* tp_getset */
1880 0, /* tp_base */
1881 0, /* tp_dict */
1882 0, /* tp_descr_get */
1883 0, /* tp_descr_set */
1884 0, /* tp_dictoffset */
1885 0, /* tp_init */
1886 0, /* tp_alloc */
1887 0, /* tp_new */
1888 };
1889
1890
1891 static PyObject *
async_gen_asend_new(PyAsyncGenObject * gen,PyObject * sendval)1892 async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)
1893 {
1894 PyAsyncGenASend *o;
1895 #if _PyAsyncGen_MAXFREELIST > 0
1896 struct _Py_async_gen_state *state = get_async_gen_state();
1897 #ifdef Py_DEBUG
1898 // async_gen_asend_new() must not be called after _PyAsyncGen_Fini()
1899 assert(state->asend_numfree != -1);
1900 #endif
1901 if (state->asend_numfree) {
1902 state->asend_numfree--;
1903 o = state->asend_freelist[state->asend_numfree];
1904 _Py_NewReference((PyObject *)o);
1905 }
1906 else
1907 #endif
1908 {
1909 o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type);
1910 if (o == NULL) {
1911 return NULL;
1912 }
1913 }
1914
1915 Py_INCREF(gen);
1916 o->ags_gen = gen;
1917
1918 Py_XINCREF(sendval);
1919 o->ags_sendval = sendval;
1920
1921 o->ags_state = AWAITABLE_STATE_INIT;
1922
1923 _PyObject_GC_TRACK((PyObject*)o);
1924 return (PyObject*)o;
1925 }
1926
1927
1928 /* ---------- Async Generator Value Wrapper ------------ */
1929
1930
1931 static void
async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue * o)1932 async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
1933 {
1934 _PyObject_GC_UNTRACK((PyObject *)o);
1935 Py_CLEAR(o->agw_val);
1936 #if _PyAsyncGen_MAXFREELIST > 0
1937 struct _Py_async_gen_state *state = get_async_gen_state();
1938 #ifdef Py_DEBUG
1939 // async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini()
1940 assert(state->value_numfree != -1);
1941 #endif
1942 if (state->value_numfree < _PyAsyncGen_MAXFREELIST) {
1943 assert(_PyAsyncGenWrappedValue_CheckExact(o));
1944 state->value_freelist[state->value_numfree++] = o;
1945 OBJECT_STAT_INC(to_freelist);
1946 }
1947 else
1948 #endif
1949 {
1950 PyObject_GC_Del(o);
1951 }
1952 }
1953
1954
1955 static int
async_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue * o,visitproc visit,void * arg)1956 async_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue *o,
1957 visitproc visit, void *arg)
1958 {
1959 Py_VISIT(o->agw_val);
1960 return 0;
1961 }
1962
1963
1964 PyTypeObject _PyAsyncGenWrappedValue_Type = {
1965 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1966 "async_generator_wrapped_value", /* tp_name */
1967 sizeof(_PyAsyncGenWrappedValue), /* tp_basicsize */
1968 0, /* tp_itemsize */
1969 /* methods */
1970 (destructor)async_gen_wrapped_val_dealloc, /* tp_dealloc */
1971 0, /* tp_vectorcall_offset */
1972 0, /* tp_getattr */
1973 0, /* tp_setattr */
1974 0, /* tp_as_async */
1975 0, /* tp_repr */
1976 0, /* tp_as_number */
1977 0, /* tp_as_sequence */
1978 0, /* tp_as_mapping */
1979 0, /* tp_hash */
1980 0, /* tp_call */
1981 0, /* tp_str */
1982 PyObject_GenericGetAttr, /* tp_getattro */
1983 0, /* tp_setattro */
1984 0, /* tp_as_buffer */
1985 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1986 0, /* tp_doc */
1987 (traverseproc)async_gen_wrapped_val_traverse, /* tp_traverse */
1988 0, /* tp_clear */
1989 0, /* tp_richcompare */
1990 0, /* tp_weaklistoffset */
1991 0, /* tp_iter */
1992 0, /* tp_iternext */
1993 0, /* tp_methods */
1994 0, /* tp_members */
1995 0, /* tp_getset */
1996 0, /* tp_base */
1997 0, /* tp_dict */
1998 0, /* tp_descr_get */
1999 0, /* tp_descr_set */
2000 0, /* tp_dictoffset */
2001 0, /* tp_init */
2002 0, /* tp_alloc */
2003 0, /* tp_new */
2004 };
2005
2006
2007 PyObject *
_PyAsyncGenValueWrapperNew(PyObject * val)2008 _PyAsyncGenValueWrapperNew(PyObject *val)
2009 {
2010 _PyAsyncGenWrappedValue *o;
2011 assert(val);
2012
2013 #if _PyAsyncGen_MAXFREELIST > 0
2014 struct _Py_async_gen_state *state = get_async_gen_state();
2015 #ifdef Py_DEBUG
2016 // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini()
2017 assert(state->value_numfree != -1);
2018 #endif
2019 if (state->value_numfree) {
2020 state->value_numfree--;
2021 o = state->value_freelist[state->value_numfree];
2022 OBJECT_STAT_INC(from_freelist);
2023 assert(_PyAsyncGenWrappedValue_CheckExact(o));
2024 _Py_NewReference((PyObject*)o);
2025 }
2026 else
2027 #endif
2028 {
2029 o = PyObject_GC_New(_PyAsyncGenWrappedValue,
2030 &_PyAsyncGenWrappedValue_Type);
2031 if (o == NULL) {
2032 return NULL;
2033 }
2034 }
2035 o->agw_val = val;
2036 Py_INCREF(val);
2037 _PyObject_GC_TRACK((PyObject*)o);
2038 return (PyObject*)o;
2039 }
2040
2041
2042 /* ---------- Async Generator AThrow awaitable ------------ */
2043
2044
2045 static void
async_gen_athrow_dealloc(PyAsyncGenAThrow * o)2046 async_gen_athrow_dealloc(PyAsyncGenAThrow *o)
2047 {
2048 _PyObject_GC_UNTRACK((PyObject *)o);
2049 Py_CLEAR(o->agt_gen);
2050 Py_CLEAR(o->agt_args);
2051 PyObject_GC_Del(o);
2052 }
2053
2054
2055 static int
async_gen_athrow_traverse(PyAsyncGenAThrow * o,visitproc visit,void * arg)2056 async_gen_athrow_traverse(PyAsyncGenAThrow *o, visitproc visit, void *arg)
2057 {
2058 Py_VISIT(o->agt_gen);
2059 Py_VISIT(o->agt_args);
2060 return 0;
2061 }
2062
2063
2064 static PyObject *
async_gen_athrow_send(PyAsyncGenAThrow * o,PyObject * arg)2065 async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
2066 {
2067 PyGenObject *gen = (PyGenObject*)o->agt_gen;
2068 PyObject *retval;
2069
2070 if (o->agt_state == AWAITABLE_STATE_CLOSED) {
2071 PyErr_SetString(
2072 PyExc_RuntimeError,
2073 "cannot reuse already awaited aclose()/athrow()");
2074 return NULL;
2075 }
2076
2077 if (gen->gi_frame_state >= FRAME_COMPLETED) {
2078 o->agt_state = AWAITABLE_STATE_CLOSED;
2079 PyErr_SetNone(PyExc_StopIteration);
2080 return NULL;
2081 }
2082
2083 if (o->agt_state == AWAITABLE_STATE_INIT) {
2084 if (o->agt_gen->ag_running_async) {
2085 o->agt_state = AWAITABLE_STATE_CLOSED;
2086 if (o->agt_args == NULL) {
2087 PyErr_SetString(
2088 PyExc_RuntimeError,
2089 "aclose(): asynchronous generator is already running");
2090 }
2091 else {
2092 PyErr_SetString(
2093 PyExc_RuntimeError,
2094 "athrow(): asynchronous generator is already running");
2095 }
2096 return NULL;
2097 }
2098
2099 if (o->agt_gen->ag_closed) {
2100 o->agt_state = AWAITABLE_STATE_CLOSED;
2101 PyErr_SetNone(PyExc_StopAsyncIteration);
2102 return NULL;
2103 }
2104
2105 if (arg != Py_None) {
2106 PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG);
2107 return NULL;
2108 }
2109
2110 o->agt_state = AWAITABLE_STATE_ITER;
2111 o->agt_gen->ag_running_async = 1;
2112
2113 if (o->agt_args == NULL) {
2114 /* aclose() mode */
2115 o->agt_gen->ag_closed = 1;
2116
2117 retval = _gen_throw((PyGenObject *)gen,
2118 0, /* Do not close generator when
2119 PyExc_GeneratorExit is passed */
2120 PyExc_GeneratorExit, NULL, NULL);
2121
2122 if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) {
2123 Py_DECREF(retval);
2124 goto yield_close;
2125 }
2126 } else {
2127 PyObject *typ;
2128 PyObject *tb = NULL;
2129 PyObject *val = NULL;
2130
2131 if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,
2132 &typ, &val, &tb)) {
2133 return NULL;
2134 }
2135
2136 retval = _gen_throw((PyGenObject *)gen,
2137 0, /* Do not close generator when
2138 PyExc_GeneratorExit is passed */
2139 typ, val, tb);
2140 retval = async_gen_unwrap_value(o->agt_gen, retval);
2141 }
2142 if (retval == NULL) {
2143 goto check_error;
2144 }
2145 return retval;
2146 }
2147
2148 assert(o->agt_state == AWAITABLE_STATE_ITER);
2149
2150 retval = gen_send((PyGenObject *)gen, arg);
2151 if (o->agt_args) {
2152 return async_gen_unwrap_value(o->agt_gen, retval);
2153 } else {
2154 /* aclose() mode */
2155 if (retval) {
2156 if (_PyAsyncGenWrappedValue_CheckExact(retval)) {
2157 Py_DECREF(retval);
2158 goto yield_close;
2159 }
2160 else {
2161 return retval;
2162 }
2163 }
2164 else {
2165 goto check_error;
2166 }
2167 }
2168
2169 yield_close:
2170 o->agt_gen->ag_running_async = 0;
2171 o->agt_state = AWAITABLE_STATE_CLOSED;
2172 PyErr_SetString(
2173 PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
2174 return NULL;
2175
2176 check_error:
2177 o->agt_gen->ag_running_async = 0;
2178 o->agt_state = AWAITABLE_STATE_CLOSED;
2179 if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
2180 PyErr_ExceptionMatches(PyExc_GeneratorExit))
2181 {
2182 if (o->agt_args == NULL) {
2183 /* when aclose() is called we don't want to propagate
2184 StopAsyncIteration or GeneratorExit; just raise
2185 StopIteration, signalling that this 'aclose()' await
2186 is done.
2187 */
2188 PyErr_Clear();
2189 PyErr_SetNone(PyExc_StopIteration);
2190 }
2191 }
2192 return NULL;
2193 }
2194
2195
2196 static PyObject *
async_gen_athrow_throw(PyAsyncGenAThrow * o,PyObject * const * args,Py_ssize_t nargs)2197 async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs)
2198 {
2199 PyObject *retval;
2200
2201 if (o->agt_state == AWAITABLE_STATE_CLOSED) {
2202 PyErr_SetString(
2203 PyExc_RuntimeError,
2204 "cannot reuse already awaited aclose()/athrow()");
2205 return NULL;
2206 }
2207
2208 retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs);
2209 if (o->agt_args) {
2210 return async_gen_unwrap_value(o->agt_gen, retval);
2211 } else {
2212 /* aclose() mode */
2213 if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) {
2214 o->agt_gen->ag_running_async = 0;
2215 o->agt_state = AWAITABLE_STATE_CLOSED;
2216 Py_DECREF(retval);
2217 PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
2218 return NULL;
2219 }
2220 if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
2221 PyErr_ExceptionMatches(PyExc_GeneratorExit))
2222 {
2223 /* when aclose() is called we don't want to propagate
2224 StopAsyncIteration or GeneratorExit; just raise
2225 StopIteration, signalling that this 'aclose()' await
2226 is done.
2227 */
2228 PyErr_Clear();
2229 PyErr_SetNone(PyExc_StopIteration);
2230 }
2231 return retval;
2232 }
2233 }
2234
2235
2236 static PyObject *
async_gen_athrow_iternext(PyAsyncGenAThrow * o)2237 async_gen_athrow_iternext(PyAsyncGenAThrow *o)
2238 {
2239 return async_gen_athrow_send(o, Py_None);
2240 }
2241
2242
2243 static PyObject *
async_gen_athrow_close(PyAsyncGenAThrow * o,PyObject * args)2244 async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)
2245 {
2246 o->agt_state = AWAITABLE_STATE_CLOSED;
2247 Py_RETURN_NONE;
2248 }
2249
2250
2251 static PyMethodDef async_gen_athrow_methods[] = {
2252 {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc},
2253 {"throw", _PyCFunction_CAST(async_gen_athrow_throw),
2254 METH_FASTCALL, throw_doc},
2255 {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc},
2256 {NULL, NULL} /* Sentinel */
2257 };
2258
2259
2260 static PyAsyncMethods async_gen_athrow_as_async = {
2261 PyObject_SelfIter, /* am_await */
2262 0, /* am_aiter */
2263 0, /* am_anext */
2264 0, /* am_send */
2265 };
2266
2267
2268 PyTypeObject _PyAsyncGenAThrow_Type = {
2269 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2270 "async_generator_athrow", /* tp_name */
2271 sizeof(PyAsyncGenAThrow), /* tp_basicsize */
2272 0, /* tp_itemsize */
2273 /* methods */
2274 (destructor)async_gen_athrow_dealloc, /* tp_dealloc */
2275 0, /* tp_vectorcall_offset */
2276 0, /* tp_getattr */
2277 0, /* tp_setattr */
2278 &async_gen_athrow_as_async, /* tp_as_async */
2279 0, /* tp_repr */
2280 0, /* tp_as_number */
2281 0, /* tp_as_sequence */
2282 0, /* tp_as_mapping */
2283 0, /* tp_hash */
2284 0, /* tp_call */
2285 0, /* tp_str */
2286 PyObject_GenericGetAttr, /* tp_getattro */
2287 0, /* tp_setattro */
2288 0, /* tp_as_buffer */
2289 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2290 0, /* tp_doc */
2291 (traverseproc)async_gen_athrow_traverse, /* tp_traverse */
2292 0, /* tp_clear */
2293 0, /* tp_richcompare */
2294 0, /* tp_weaklistoffset */
2295 PyObject_SelfIter, /* tp_iter */
2296 (iternextfunc)async_gen_athrow_iternext, /* tp_iternext */
2297 async_gen_athrow_methods, /* tp_methods */
2298 0, /* tp_members */
2299 0, /* tp_getset */
2300 0, /* tp_base */
2301 0, /* tp_dict */
2302 0, /* tp_descr_get */
2303 0, /* tp_descr_set */
2304 0, /* tp_dictoffset */
2305 0, /* tp_init */
2306 0, /* tp_alloc */
2307 0, /* tp_new */
2308 };
2309
2310
2311 static PyObject *
async_gen_athrow_new(PyAsyncGenObject * gen,PyObject * args)2312 async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args)
2313 {
2314 PyAsyncGenAThrow *o;
2315 o = PyObject_GC_New(PyAsyncGenAThrow, &_PyAsyncGenAThrow_Type);
2316 if (o == NULL) {
2317 return NULL;
2318 }
2319 o->agt_gen = gen;
2320 o->agt_args = args;
2321 o->agt_state = AWAITABLE_STATE_INIT;
2322 Py_INCREF(gen);
2323 Py_XINCREF(args);
2324 _PyObject_GC_TRACK((PyObject*)o);
2325 return (PyObject*)o;
2326 }
2327