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