Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Objects/genobject.c
Line
Count
Source (jump to first uncovered line)
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
exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg)
30
{
31
    Py_VISIT(exc_state->exc_value);
32
    return 0;
33
}
34
35
static int
36
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
37
{
38
    Py_VISIT(gen->gi_code);
39
    Py_VISIT(gen->gi_name);
40
    Py_VISIT(gen->gi_qualname);
41
    if (gen->gi_frame_state < FRAME_CLEARED) {
  Branch (41:9): [True: 411k, False: 3.33k]
42
        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
43
        assert(frame->frame_obj == NULL ||
44
               frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR);
45
        int err = _PyFrame_Traverse(frame, visit, arg);
46
        if (err) {
  Branch (46:13): [True: 0, False: 411k]
47
            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
    return exc_state_traverse(&gen->gi_exc_state, visit, arg);
53
}
54
55
void
56
_PyGen_Finalize(PyObject *self)
57
{
58
    PyGenObject *gen = (PyGenObject *)self;
59
    PyObject *res = NULL;
60
    PyObject *error_type, *error_value, *error_traceback;
61
62
    if (gen->gi_frame_state >= FRAME_COMPLETED) {
  Branch (62:9): [True: 2.97M, False: 594k]
63
        /* Generator isn't paused, so no need to close */
64
        return;
65
    }
66
67
    if (PyAsyncGen_CheckExact(self)) {
68
        PyAsyncGenObject *agen = (PyAsyncGenObject*)self;
69
        PyObject *finalizer = agen->ag_origin_or_finalizer;
70
        if (finalizer && 
!agen->ag_closed12
) {
  Branch (70:13): [True: 12, False: 405]
  Branch (70:26): [True: 10, False: 2]
71
            /* Save the current exception, if any. */
72
            PyErr_Fetch(&error_type, &error_value, &error_traceback);
73
74
            res = PyObject_CallOneArg(finalizer, self);
75
76
            if (res == NULL) {
  Branch (76:17): [True: 0, False: 10]
77
                PyErr_WriteUnraisable(self);
78
            } else {
79
                Py_DECREF(res);
80
            }
81
            /* Restore the saved exception. */
82
            PyErr_Restore(error_type, error_value, error_traceback);
83
            return;
84
        }
85
    }
86
87
    /* Save the current exception, if any. */
88
    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
    if (gen->gi_code != NULL &&
  Branch (92:9): [True: 594k, False: 0]
93
        ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE &&
  Branch (93:9): [True: 57, False: 594k]
94
        
gen->gi_frame_state == FRAME_CREATED57
)
  Branch (94:9): [True: 37, False: 20]
95
    {
96
        _PyErr_WarnUnawaitedCoroutine((PyObject *)gen);
97
    }
98
    else {
99
        res = gen_close(gen, NULL);
100
    }
101
102
    if (res == NULL) {
  Branch (102:9): [True: 38, False: 594k]
103
        if (PyErr_Occurred()) {
  Branch (103:13): [True: 1, False: 37]
104
            PyErr_WriteUnraisable(self);
105
        }
106
    }
107
    else {
108
        Py_DECREF(res);
109
    }
110
111
    /* Restore the saved exception. */
112
    PyErr_Restore(error_type, error_value, error_traceback);
113
}
114
115
static void
116
gen_dealloc(PyGenObject *gen)
117
{
118
    PyObject *self = (PyObject *) gen;
119
120
    _PyObject_GC_UNTRACK(gen);
121
122
    if (gen->gi_weakreflist != NULL)
  Branch (122:9): [True: 138, False: 3.56M]
123
        PyObject_ClearWeakRefs(self);
124
125
    _PyObject_GC_TRACK(self);
126
127
    if (PyObject_CallFinalizerFromDealloc(self))
  Branch (127:9): [True: 43, False: 3.56M]
128
        return;                     /* resurrected.  :( */
129
130
    _PyObject_GC_UNTRACK(self);
131
    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
        Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
136
    }
137
    if (gen->gi_frame_state < FRAME_CLEARED) {
  Branch (137:9): [True: 37, False: 3.56M]
138
        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
139
        gen->gi_frame_state = FRAME_CLEARED;
140
        frame->previous = NULL;
141
        _PyFrame_Clear(frame);
142
    }
143
    if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) {
  Branch (143:9): [True: 28.9k, False: 3.53M]
144
        Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
145
    }
146
    Py_CLEAR(gen->gi_code);
147
    Py_CLEAR(gen->gi_name);
148
    Py_CLEAR(gen->gi_qualname);
149
    _PyErr_ClearExcState(&gen->gi_exc_state);
150
    PyObject_GC_Del(gen);
151
}
152
153
static PySendResult
154
gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
155
             int exc, int closing)
156
{
157
    PyThreadState *tstate = _PyThreadState_GET();
158
    _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
159
    PyObject *result;
160
161
    *presult = NULL;
162
    if (gen->gi_frame_state == FRAME_CREATED && 
arg3.56M
&&
arg != 658k
Py_None658k
) {
  Branch (162:9): [True: 3.56M, False: 26.4M]
  Branch (162:49): [True: 658k, False: 2.91M]
  Branch (162:56): [True: 4, False: 658k]
163
        const char *msg = "can't send non-None value to a "
164
                            "just-started generator";
165
        if (PyCoro_CheckExact(gen)) {
166
            msg = NON_INIT_CORO_MSG;
167
        }
168
        else if (PyAsyncGen_CheckExact(gen)) {
169
            msg = "can't send non-None value to a "
170
                    "just-started async generator";
171
        }
172
        PyErr_SetString(PyExc_TypeError, msg);
173
        return PYGEN_ERROR;
174
    }
175
    if (gen->gi_frame_state == FRAME_EXECUTING) {
  Branch (175:9): [True: 9, False: 30.0M]
176
        const char *msg = "generator already executing";
177
        if (PyCoro_CheckExact(gen)) {
178
            msg = "coroutine already executing";
179
        }
180
        else if (PyAsyncGen_CheckExact(gen)) {
181
            msg = "async generator already executing";
182
        }
183
        PyErr_SetString(PyExc_ValueError, msg);
184
        return PYGEN_ERROR;
185
    }
186
    if (gen->gi_frame_state >= FRAME_COMPLETED) {
  Branch (186:9): [True: 9.66k, False: 30.0M]
187
        if (PyCoro_CheckExact(gen) && 
!closing825
) {
  Branch (187:39): [True: 11, False: 814]
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
            PyErr_SetString(
192
                PyExc_RuntimeError,
193
                "cannot reuse already awaited coroutine");
194
        }
195
        else if (arg && 
!exc9.41k
) {
  Branch (195:18): [True: 9.41k, False: 244]
  Branch (195:25): [True: 1, False: 9.40k]
196
            /* `gen` is an exhausted generator:
197
               only return value if called from send(). */
198
            *presult = Py_None;
199
            Py_INCREF(*presult);
200
            return PYGEN_RETURN;
201
        }
202
        return PYGEN_ERROR;
203
    }
204
205
    assert(gen->gi_frame_state < FRAME_EXECUTING);
206
    /* Push arg onto the frame's value stack */
207
    result = arg ? 
arg2.11M
:
Py_None27.9M
;
  Branch (207:14): [True: 2.11M, False: 27.9M]
208
    Py_INCREF(result);
209
    _PyFrame_StackPush(frame, result);
210
211
    frame->previous = tstate->cframe->current_frame;
212
213
    gen->gi_exc_state.previous_item = tstate->exc_info;
214
    tstate->exc_info = &gen->gi_exc_state;
215
216
    if (exc) {
  Branch (216:9): [True: 610k, False: 29.4M]
217
        assert(_PyErr_Occurred(tstate));
218
        _PyErr_ChainStackItem(NULL);
219
    }
220
221
    gen->gi_frame_state = FRAME_EXECUTING;
222
    EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR);
223
    result = _PyEval_EvalFrame(tstate, frame, exc);
224
    if (gen->gi_frame_state == FRAME_EXECUTING) {
  Branch (224:9): [True: 3.56M, False: 26.4M]
225
        gen->gi_frame_state = FRAME_COMPLETED;
226
    }
227
    tstate->exc_info = gen->gi_exc_state.previous_item;
228
    gen->gi_exc_state.previous_item = NULL;
229
230
    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
    frame->previous = NULL;
235
236
    /* If the generator just returned (as opposed to yielding), signal
237
     * that the generator is exhausted. */
238
    if (result) {
  Branch (238:9): [True: 29.4M, False: 611k]
239
        if (gen->gi_frame_state == FRAME_SUSPENDED) {
  Branch (239:13): [True: 26.4M, False: 2.95M]
240
            *presult = result;
241
            return PYGEN_NEXT;
242
        }
243
        assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
244
        if (result == Py_None && 
!2.94M
PyAsyncGen_CheckExact(gen) &&
!arg2.94M
) {
  Branch (244:13): [True: 2.94M, False: 7.77k]
  Branch (244:34): [True: 2.94M, False: 151]
  Branch (244:65): [True: 2.69M, False: 255k]
245
            /* Return NULL if called by gen_iternext() */
246
            Py_CLEAR(result);
247
        }
248
    }
249
    else {
250
        if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
  Branch (250:13): [True: 20, False: 611k]
251
            const char *msg = "generator raised StopIteration";
252
            if (PyCoro_CheckExact(gen)) {
253
                msg = "coroutine raised StopIteration";
254
            }
255
            else if (PyAsyncGen_CheckExact(gen)) {
256
                msg = "async generator raised StopIteration";
257
            }
258
            _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
259
        }
260
        else if (PyAsyncGen_CheckExact(gen) &&
261
                
PyErr_ExceptionMatches(PyExc_StopAsyncIteration)463
)
  Branch (261:17): [True: 5, False: 458]
262
        {
263
            /* code in `gen` raised a StopAsyncIteration error:
264
               raise a RuntimeError.
265
            */
266
            const char *msg = "async generator raised StopAsyncIteration";
267
            _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
    _PyErr_ClearExcState(&gen->gi_exc_state);
274
275
    gen->gi_frame_state = FRAME_CLEARED;
276
    _PyFrame_Clear(frame);
277
    *presult = result;
278
    return result ? 
PYGEN_RETURN263k
:
PYGEN_ERROR3.30M
;
  Branch (278:12): [True: 263k, False: 3.30M]
279
}
280
281
static PySendResult
282
PyGen_am_send(PyGenObject *gen, PyObject *arg, PyObject **result)
283
{
284
    return gen_send_ex2(gen, arg, result, 0, 0);
285
}
286
287
static PyObject *
288
gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
289
{
290
    PyObject *result;
291
    if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) {
  Branch (291:9): [True: 2.46k, False: 620k]
292
        if (PyAsyncGen_CheckExact(gen)) {
293
            assert(result == Py_None);
294
            PyErr_SetNone(PyExc_StopAsyncIteration);
295
        }
296
        else if (result == Py_None) {
  Branch (296:18): [True: 1.62k, False: 688]
297
            PyErr_SetNone(PyExc_StopIteration);
298
        }
299
        else {
300
            _PyGen_SetStopIterationValue(result);
301
        }
302
        Py_CLEAR(result);
303
    }
304
    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
gen_send(PyGenObject *gen, PyObject *arg)
313
{
314
    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
gen_close_iter(PyObject *yf)
327
{
328
    PyObject *retval = NULL;
329
330
    if (PyGen_CheckExact(yf) || 
PyCoro_CheckExact645
(yf)) {
331
        retval = gen_close((PyGenObject *)yf, NULL);
332
        if (retval == NULL)
  Branch (332:13): [True: 11, False: 12.6k]
333
            return -1;
334
    }
335
    else {
336
        PyObject *meth;
337
        if (_PyObject_LookupAttr(yf, &_Py_ID(close), &meth) < 0) {
  Branch (337:13): [True: 2, False: 639]
338
            PyErr_WriteUnraisable(yf);
339
        }
340
        if (meth) {
  Branch (340:13): [True: 13, False: 628]
341
            retval = _PyObject_CallNoArgs(meth);
342
            Py_DECREF(meth);
343
            if (retval == NULL)
  Branch (343:17): [True: 0, False: 13]
344
                return -1;
345
        }
346
    }
347
    Py_XDECREF(retval);
348
    return 0;
349
}
350
351
PyObject *
352
_PyGen_yf(PyGenObject *gen)
353
{
354
    PyObject *yf = NULL;
355
356
    if (gen->gi_frame_state < FRAME_CLEARED) {
  Branch (356:9): [True: 630k, False: 9.41k]
357
        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
358
359
        if (gen->gi_frame_state == FRAME_CREATED) {
  Branch (359:13): [True: 401k, False: 229k]
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
            assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND);
364
            return NULL;
365
        }
366
        _Py_CODEUNIT next = frame->prev_instr[1];
367
        if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || 
_Py_OPARG228k
(next) < 2228k
)
  Branch (367:13): [True: 10, False: 228k]
  Branch (367:60): [True: 214k, False: 14.4k]
368
        {
369
            /* Not in a yield from */
370
            return NULL;
371
        }
372
        yf = _PyFrame_StackPeek(frame);
373
        Py_INCREF(yf);
374
    }
375
376
    return yf;
377
}
378
379
static PyObject *
380
gen_close(PyGenObject *gen, PyObject *args)
381
{
382
    PyObject *retval;
383
    PyObject *yf = _PyGen_yf(gen);
384
    int err = 0;
385
386
    if (yf) {
  Branch (386:9): [True: 13.2k, False: 604k]
387
        PyFrameState state = gen->gi_frame_state;
388
        gen->gi_frame_state = FRAME_EXECUTING;
389
        err = gen_close_iter(yf);
390
        gen->gi_frame_state = state;
391
        Py_DECREF(yf);
392
    }
393
    if (err == 0)
  Branch (393:9): [True: 617k, False: 5]
394
        PyErr_SetNone(PyExc_GeneratorExit);
395
    retval = gen_send_ex(gen, Py_None, 1, 1);
396
    if (retval) {
  Branch (396:9): [True: 7, False: 617k]
397
        const char *msg = "generator ignored GeneratorExit";
398
        if (PyCoro_CheckExact(gen)) {
399
            msg = "coroutine ignored GeneratorExit";
400
        } else if (PyAsyncGen_CheckExact(gen)) {
401
            msg = ASYNC_GEN_IGNORED_EXIT_MSG;
402
        }
403
        Py_DECREF(retval);
404
        PyErr_SetString(PyExc_RuntimeError, msg);
405
        return NULL;
406
    }
407
    if (PyErr_ExceptionMatches(PyExc_StopIteration)
  Branch (407:9): [True: 6, False: 617k]
408
        || 
PyErr_ExceptionMatches(PyExc_GeneratorExit)617k
) {
  Branch (408:12): [True: 617k, False: 14]
409
        PyErr_Clear();          /* ignore these errors */
410
        Py_RETURN_NONE;
411
    }
412
    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
_gen_throw(PyGenObject *gen, int close_on_genexit,
425
           PyObject *typ, PyObject *val, PyObject *tb)
426
{
427
    PyObject *yf = _PyGen_yf(gen);
428
429
    if (yf) {
  Branch (429:9): [True: 1.15k, False: 1.43k]
430
        _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
431
        PyObject *ret;
432
        int err;
433
        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&
  Branch (433:13): [True: 10, False: 1.14k]
434
            
close_on_genexit10
  Branch (434:13): [True: 10, False: 0]
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
            PyFrameState state = gen->gi_frame_state;
441
            gen->gi_frame_state = FRAME_EXECUTING;
442
            err = gen_close_iter(yf);
443
            gen->gi_frame_state = state;
444
            Py_DECREF(yf);
445
            if (err < 0)
  Branch (445:17): [True: 6, False: 4]
446
                return gen_send_ex(gen, Py_None, 1, 0);
447
            goto throw_here;
448
        }
449
        if (PyGen_CheckExact(yf) || 
PyCoro_CheckExact1.00k
(yf)) {
450
            /* `yf` is a generator or a coroutine. */
451
            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
            _PyInterpreterFrame *prev = tstate->cframe->current_frame;
458
            frame->previous = prev;
459
            tstate->cframe->current_frame = frame;
460
            /* Close the generator that we are currently iterating with
461
               'yield from' or awaiting on with 'await'. */
462
            PyFrameState state = gen->gi_frame_state;
463
            gen->gi_frame_state = FRAME_EXECUTING;
464
            ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
465
                             typ, val, tb);
466
            gen->gi_frame_state = state;
467
            tstate->cframe->current_frame = prev;
468
            frame->previous = NULL;
469
        } else {
470
            /* `yf` is an iterator or a coroutine-like object. */
471
            PyObject *meth;
472
            if (_PyObject_LookupAttr(yf, &_Py_ID(throw), &meth) < 0) {
  Branch (472:17): [True: 1, False: 600]
473
                Py_DECREF(yf);
474
                return NULL;
475
            }
476
            if (meth == NULL) {
  Branch (476:17): [True: 1, False: 599]
477
                Py_DECREF(yf);
478
                goto throw_here;
479
            }
480
            PyFrameState state = gen->gi_frame_state;
481
            gen->gi_frame_state = FRAME_EXECUTING;
482
            ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
483
            gen->gi_frame_state = state;
484
            Py_DECREF(meth);
485
        }
486
        Py_DECREF(yf);
487
        if (!ret) {
  Branch (487:13): [True: 1.11k, False: 32]
488
            PyObject *val;
489
            /* Pop subiterator from stack */
490
            assert(gen->gi_frame_state < FRAME_CLEARED);
491
            ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe);
492
            assert(ret == yf);
493
            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
            assert(_PyInterpreterFrame_LASTI(frame) >= 0);
498
            /* Backup to SEND */
499
            assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND);
500
            int jump = _Py_OPARG(frame->prev_instr[-1]);
501
            frame->prev_instr += jump - 1;
502
            if (_PyGen_FetchStopIterationValue(&val) == 0) {
  Branch (502:17): [True: 12, False: 1.09k]
503
                ret = gen_send(gen, val);
504
                Py_DECREF(val);
505
            } else {
506
                ret = gen_send_ex(gen, Py_None, 1, 0);
507
            }
508
        }
509
        return ret;
510
    }
511
512
throw_here:
513
    /* First, check the traceback argument, replacing None with
514
       NULL. */
515
    if (tb == Py_None) {
  Branch (515:9): [True: 21, False: 1.42k]
516
        tb = NULL;
517
    }
518
    else if (tb != NULL && 
!1.17k
PyTraceBack_Check1.17k
(tb)) {
  Branch (518:14): [True: 1.17k, False: 251]
  Branch (518:28): [True: 2, False: 1.16k]
519
        PyErr_SetString(PyExc_TypeError,
520
            "throw() third argument must be a traceback object");
521
        return NULL;
522
    }
523
524
    Py_INCREF(typ);
525
    Py_XINCREF(val);
526
    Py_XINCREF(tb);
527
528
    if (PyExceptionClass_Check(typ))
529
        PyErr_NormalizeException(&typ, &val, &tb);
530
531
    else if (PyExceptionInstance_Check(typ)) {
532
        /* Raising an instance.  The value should be a dummy. */
533
        if (val && 
val != 2
Py_None2
) {
  Branch (533:13): [True: 2, False: 188]
  Branch (533:20): [True: 2, False: 0]
534
            PyErr_SetString(PyExc_TypeError,
535
              "instance exception may not have a separate value");
536
            goto failed_throw;
537
        }
538
        else {
539
            /* Normalize to raise <class>, <instance> */
540
            Py_XDECREF(val);
541
            val = typ;
542
            typ = PyExceptionInstance_Class(typ);
543
            Py_INCREF(typ);
544
545
            if (tb == NULL)
  Branch (545:17): [True: 188, False: 0]
546
                /* Returns NULL if there's no traceback */
547
                tb = PyException_GetTraceback(val);
548
        }
549
    }
550
    else {
551
        /* Not something you can raise.  throw() fails. */
552
        PyErr_Format(PyExc_TypeError,
553
                     "exceptions must be classes or instances "
554
                     "deriving from BaseException, not %s",
555
                     Py_TYPE(typ)->tp_name);
556
            goto failed_throw;
557
    }
558
559
    PyErr_Restore(typ, val, tb);
560
    return gen_send_ex(gen, Py_None, 1, 0);
561
562
failed_throw:
563
    /* Didn't use our arguments, so restore their original refcounts */
564
    Py_DECREF(typ);
565
    Py_XDECREF(val);
566
    Py_XDECREF(tb);
567
    return NULL;
568
}
569
570
571
static PyObject *
572
gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs)
573
{
574
    PyObject *typ;
575
    PyObject *tb = NULL;
576
    PyObject *val = NULL;
577
578
    if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) {
579
        return NULL;
580
    }
581
    typ = args[0];
582
    if (nargs == 3) {
  Branch (582:9): [True: 1.18k, False: 829]
583
        val = args[1];
584
        tb = args[2];
585
    }
586
    else if (nargs == 2) {
  Branch (586:14): [True: 7, False: 822]
587
        val = args[1];
588
    }
589
    return _gen_throw(gen, 1, typ, val, tb);
590
}
591
592
593
static PyObject *
594
gen_iternext(PyGenObject *gen)
595
{
596
    PyObject *result;
597
    assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen));
598
    if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) {
  Branch (598:9): [True: 49, False: 27.9M]
599
        if (result != Py_None) {
  Branch (599:13): [True: 49, False: 0]
600
            _PyGen_SetStopIterationValue(result);
601
        }
602
        Py_CLEAR(result);
603
    }
604
    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
_PyGen_SetStopIterationValue(PyObject *value)
615
{
616
    PyObject *e;
617
618
    if (value == NULL ||
  Branch (618:9): [True: 0, False: 1.18k]
619
        (!PyTuple_Check(value) && 
!1.14k
PyExceptionInstance_Check1.14k
(value)))
  Branch (619:10): [True: 1.14k, False: 40]
  Branch (619:35): [True: 1.13k, False: 9]
620
    {
621
        /* Delay exception instantiation if we can */
622
        PyErr_SetObject(PyExc_StopIteration, value);
623
        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
    e = PyObject_CallOneArg(PyExc_StopIteration, value);
635
    if (e == NULL) {
  Branch (635:9): [True: 0, False: 49]
636
        return -1;
637
    }
638
    PyErr_SetObject(PyExc_StopIteration, e);
639
    Py_DECREF(e);
640
    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
_PyGen_FetchStopIterationValue(PyObject **pvalue)
654
{
655
    PyObject *et, *ev, *tb;
656
    PyObject *value = NULL;
657
658
    if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
  Branch (658:9): [True: 611, False: 6.77k]
659
        PyErr_Fetch(&et, &ev, &tb);
660
        if (ev) {
  Branch (660:13): [True: 510, False: 101]
661
            /* exception will usually be normalised already */
662
            if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
663
                value = ((PyStopIterationObject *)ev)->value;
664
                Py_INCREF(value);
665
                Py_DECREF(ev);
666
            } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) {
  Branch (666:24): [True: 409, False: 0]
  Branch (666:53): [True: 409, False: 0]
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
                value = ev;
676
            } else {
677
                /* normalisation required */
678
                PyErr_NormalizeException(&et, &ev, &tb);
679
                if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
  Branch (679:21): [True: 0, False: 0]
680
                    PyErr_Restore(et, ev, tb);
681
                    return -1;
682
                }
683
                value = ((PyStopIterationObject *)ev)->value;
684
                Py_INCREF(value);
685
                Py_DECREF(ev);
686
            }
687
        }
688
        Py_XDECREF(et);
689
        Py_XDECREF(tb);
690
    } else if (PyErr_Occurred()) {
  Branch (690:16): [True: 1.69k, False: 5.08k]
691
        return -1;
692
    }
693
    if (value == NULL) {
  Branch (693:9): [True: 5.18k, False: 510]
694
        value = Py_None;
695
        Py_INCREF(value);
696
    }
697
    *pvalue = value;
698
    return 0;
699
}
700
701
static PyObject *
702
gen_repr(PyGenObject *gen)
703
{
704
    return PyUnicode_FromFormat("<generator object %S at %p>",
705
                                gen->gi_qualname, gen);
706
}
707
708
static PyObject *
709
gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored))
710
{
711
    Py_INCREF(op->gi_name);
712
    return op->gi_name;
713
}
714
715
static int
716
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
    if (value == NULL || 
!3
PyUnicode_Check3
(value)) {
  Branch (720:9): [True: 1, False: 3]
  Branch (720:26): [True: 1, False: 2]
721
        PyErr_SetString(PyExc_TypeError,
722
                        "__name__ must be set to a string object");
723
        return -1;
724
    }
725
    Py_INCREF(value);
726
    Py_XSETREF(op->gi_name, value);
727
    return 0;
728
}
729
730
static PyObject *
731
gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored))
732
{
733
    Py_INCREF(op->gi_qualname);
734
    return op->gi_qualname;
735
}
736
737
static int
738
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
    if (value == NULL || 
!3
PyUnicode_Check3
(value)) {
  Branch (742:9): [True: 1, False: 3]
  Branch (742:26): [True: 1, False: 2]
743
        PyErr_SetString(PyExc_TypeError,
744
                        "__qualname__ must be set to a string object");
745
        return -1;
746
    }
747
    Py_INCREF(value);
748
    Py_XSETREF(op->gi_qualname, value);
749
    return 0;
750
}
751
752
static PyObject *
753
gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored))
754
{
755
    PyObject *yf = _PyGen_yf(gen);
756
    if (yf == NULL)
  Branch (756:9): [True: 8, False: 1]
757
        Py_RETURN_NONE;
758
    return yf;
759
}
760
761
762
static PyObject *
763
gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored))
764
{
765
    if (gen->gi_frame_state == FRAME_EXECUTING) {
  Branch (765:9): [True: 8, False: 15]
766
        Py_RETURN_TRUE;
767
    }
768
    
Py_RETURN_FALSE15
;
769
}
770
771
static PyObject *
772
gen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored))
773
{
774
    return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED);
775
}
776
777
static PyObject *
778
_gen_getframe(PyGenObject *gen, const char *const name)
779
{
780
    if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) {
  Branch (780:9): [True: 0, False: 3.82k]
781
        return NULL;
782
    }
783
    if (gen->gi_frame_state == FRAME_CLEARED) {
  Branch (783:9): [True: 3.40k, False: 415]
784
        Py_RETURN_NONE;
785
    }
786
    return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));
787
}
788
789
static PyObject *
790
gen_getframe(PyGenObject *gen, void *Py_UNUSED(ignored))
791
{
792
    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
gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored))
815
{
816
    Py_ssize_t res;
817
    res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus);
818
    PyCodeObject *code = gen->gi_code;
819
    res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
820
    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
make_gen(PyTypeObject *type, PyFunctionObject *func)
898
{
899
    PyCodeObject *code = (PyCodeObject *)func->func_code;
900
    int slots = code->co_nlocalsplus + code->co_stacksize;
901
    PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots);
902
    if (gen == NULL) {
  Branch (902:9): [True: 0, False: 3.56M]
903
        return NULL;
904
    }
905
    gen->gi_frame_state = FRAME_CLEARED;
906
    gen->gi_code = (PyCodeObject *)func->func_code;
907
    Py_INCREF(gen->gi_code);
908
    gen->gi_weakreflist = NULL;
909
    gen->gi_exc_state.exc_value = NULL;
910
    gen->gi_exc_state.previous_item = NULL;
911
    assert(func->func_name != NULL);
912
    gen->gi_name = Py_NewRef(func->func_name);
913
    assert(func->func_qualname != NULL);
914
    gen->gi_qualname = Py_NewRef(func->func_qualname);
915
    _PyObject_GC_TRACK(gen);
916
    return (PyObject *)gen;
917
}
918
919
static PyObject *
920
compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame);
921
922
PyObject *
923
_Py_MakeCoro(PyFunctionObject *func)
924
{
925
    int coro_flags = ((PyCodeObject *)func->func_code)->co_flags &
926
        (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
927
    assert(coro_flags);
928
    if (coro_flags == CO_GENERATOR) {
  Branch (928:9): [True: 3.53M, False: 29.6k]
929
        return make_gen(&PyGen_Type, func);
930
    }
931
    if (coro_flags == CO_ASYNC_GENERATOR) {
  Branch (931:9): [True: 617, False: 28.9k]
932
        PyAsyncGenObject *o;
933
        o = (PyAsyncGenObject *)make_gen(&PyAsyncGen_Type, func);
934
        if (o == NULL) {
  Branch (934:13): [True: 0, False: 617]
935
            return NULL;
936
        }
937
        o->ag_origin_or_finalizer = NULL;
938
        o->ag_closed = 0;
939
        o->ag_hooks_inited = 0;
940
        o->ag_running_async = 0;
941
        return (PyObject*)o;
942
    }
943
    assert (coro_flags == CO_COROUTINE);
944
    PyObject *coro = make_gen(&PyCoro_Type, func);
945
    if (!coro) {
  Branch (945:9): [True: 0, False: 28.9k]
946
        return NULL;
947
    }
948
    PyThreadState *tstate = _PyThreadState_GET();
949
    int origin_depth = tstate->coroutine_origin_tracking_depth;
950
951
    if (origin_depth == 0) {
  Branch (951:9): [True: 25.8k, False: 3.18k]
952
        ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
953
    } else {
954
        assert(_PyEval_GetFrame());
955
        PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()->previous);
956
        ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
957
        if (!cr_origin) {
  Branch (957:13): [True: 0, False: 3.18k]
958
            Py_DECREF(coro);
959
            return NULL;
960
        }
961
    }
962
    return coro;
963
}
964
965
static PyObject *
966
gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
967
                      PyObject *name, PyObject *qualname)
968
{
969
    PyCodeObject *code = f->f_frame->f_code;
970
    int size = code->co_nlocalsplus + code->co_stacksize;
971
    PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, size);
972
    if (gen == NULL) {
  Branch (972:9): [True: 0, False: 0]
973
        Py_DECREF(f);
974
        return NULL;
975
    }
976
    /* Copy the frame */
977
    assert(f->f_frame->frame_obj == NULL);
978
    assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
979
    _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
980
    _PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame);
981
    gen->gi_frame_state = FRAME_CREATED;
982
    assert(frame->frame_obj == f);
983
    f->f_frame = frame;
984
    frame->owner = FRAME_OWNED_BY_GENERATOR;
985
    assert(PyObject_GC_IsTracked((PyObject *)f));
986
    gen->gi_code = PyFrame_GetCode(f);
987
    Py_INCREF(gen->gi_code);
988
    Py_DECREF(f);
989
    gen->gi_weakreflist = NULL;
990
    gen->gi_exc_state.exc_value = NULL;
991
    gen->gi_exc_state.previous_item = NULL;
992
    if (name != NULL)
  Branch (992:9): [True: 0, False: 0]
993
        gen->gi_name = name;
994
    else
995
        gen->gi_name = gen->gi_code->co_name;
996
    Py_INCREF(gen->gi_name);
997
    if (qualname != NULL)
  Branch (997:9): [True: 0, False: 0]
998
        gen->gi_qualname = qualname;
999
    else
1000
        gen->gi_qualname = gen->gi_code->co_qualname;
1001
    Py_INCREF(gen->gi_qualname);
1002
    _PyObject_GC_TRACK(gen);
1003
    return (PyObject *)gen;
1004
}
1005
1006
PyObject *
1007
PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
1008
{
1009
    return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
1010
}
1011
1012
PyObject *
1013
PyGen_New(PyFrameObject *f)
1014
{
1015
    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
gen_is_coroutine(PyObject *o)
1027
{
1028
    if (PyGen_CheckExact(o)) {
1029
        PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
1030
        if (code->co_flags & CO_ITERABLE_COROUTINE) {
  Branch (1030:13): [True: 3.31k, False: 213]
1031
            return 1;
1032
        }
1033
    }
1034
    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
_PyCoro_GetAwaitableIter(PyObject *o)
1047
{
1048
    unaryfunc getter = NULL;
1049
    PyTypeObject *ot;
1050
1051
    if (PyCoro_CheckExact(o) || 
gen_is_coroutine(o)16.7k
) {
  Branch (1051:33): [True: 3.31k, False: 13.4k]
1052
        /* 'o' is a coroutine. */
1053
        Py_INCREF(o);
1054
        return o;
1055
    }
1056
1057
    ot = Py_TYPE(o);
1058
    if (ot->tp_as_async != NULL) {
  Branch (1058:9): [True: 13.4k, False: 11]
1059
        getter = ot->tp_as_async->am_await;
1060
    }
1061
    if (getter != NULL) {
  Branch (1061:9): [True: 13.3k, False: 26]
1062
        PyObject *res = (*getter)(o);
1063
        if (res != NULL) {
  Branch (1063:13): [True: 13.3k, False: 1]
1064
            if (PyCoro_CheckExact(res) || 
gen_is_coroutine(res)13.3k
) {
  Branch (1064:43): [True: 0, False: 13.3k]
1065
                /* __await__ must return an *iterator*, not
1066
                   a coroutine or another awaitable (see PEP 492) */
1067
                PyErr_SetString(PyExc_TypeError,
1068
                                "__await__() returned a coroutine");
1069
                Py_CLEAR(res);
1070
            } else if (!PyIter_Check(res)) {
  Branch (1070:24): [True: 5, False: 13.3k]
1071
                PyErr_Format(PyExc_TypeError,
1072
                             "__await__() returned non-iterator "
1073
                             "of type '%.100s'",
1074
                             Py_TYPE(res)->tp_name);
1075
                Py_CLEAR(res);
1076
            }
1077
        }
1078
        return res;
1079
    }
1080
1081
    PyErr_Format(PyExc_TypeError,
1082
                 "object %.100s can't be used in 'await' expression",
1083
                 ot->tp_name);
1084
    return NULL;
1085
}
1086
1087
static PyObject *
1088
coro_repr(PyCoroObject *coro)
1089
{
1090
    return PyUnicode_FromFormat("<coroutine object %S at %p>",
1091
                                coro->cr_qualname, coro);
1092
}
1093
1094
static PyObject *
1095
coro_await(PyCoroObject *coro)
1096
{
1097
    PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
1098
    if (cw == NULL) {
  Branch (1098:9): [True: 0, False: 38]
1099
        return NULL;
1100
    }
1101
    Py_INCREF(coro);
1102
    cw->cw_coroutine = coro;
1103
    _PyObject_GC_TRACK(cw);
1104
    return (PyObject *)cw;
1105
}
1106
1107
static PyObject *
1108
coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored))
1109
{
1110
    PyObject *yf = _PyGen_yf((PyGenObject *) coro);
1111
    if (yf == NULL)
  Branch (1111:9): [True: 7, False: 2]
1112
        Py_RETURN_NONE;
1113
    return yf;
1114
}
1115
1116
static PyObject *
1117
cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored))
1118
{
1119
    if (coro->cr_frame_state == FRAME_SUSPENDED) {
  Branch (1119:9): [True: 2, False: 5]
1120
        Py_RETURN_TRUE;
1121
    }
1122
    
Py_RETURN_FALSE5
;
1123
}
1124
1125
static PyObject *
1126
cr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored))
1127
{
1128
    if (coro->cr_frame_state == FRAME_EXECUTING) {
  Branch (1128:9): [True: 2, False: 7]
1129
        Py_RETURN_TRUE;
1130
    }
1131
    
Py_RETURN_FALSE7
;
1132
}
1133
1134
static PyObject *
1135
cr_getframe(PyCoroObject *coro, void *Py_UNUSED(ignored))
1136
{
1137
    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
coro_wrapper_dealloc(PyCoroWrapper *cw)
1244
{
1245
    _PyObject_GC_UNTRACK((PyObject *)cw);
1246
    Py_CLEAR(cw->cw_coroutine);
1247
    PyObject_GC_Del(cw);
1248
}
1249
1250
static PyObject *
1251
coro_wrapper_iternext(PyCoroWrapper *cw)
1252
{
1253
    return gen_iternext((PyGenObject *)cw->cw_coroutine);
1254
}
1255
1256
static PyObject *
1257
coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
1258
{
1259
    return gen_send((PyGenObject *)cw->cw_coroutine, arg);
1260
}
1261
1262
static PyObject *
1263
coro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs)
1264
{
1265
    return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs);
1266
}
1267
1268
static PyObject *
1269
coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
1270
{
1271
    return gen_close((PyGenObject *)cw->cw_coroutine, args);
1272
}
1273
1274
static int
1275
coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
1276
{
1277
    Py_VISIT((PyObject *)cw->cw_coroutine);
1278
    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
compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame)
1333
{
1334
    _PyInterpreterFrame *frame = current_frame;
1335
    /* First count how many frames we have */
1336
    int frame_count = 0;
1337
    for (; frame && 
frame_count < origin_depth35.0k
;
++frame_count31.8k
) {
  Branch (1337:12): [True: 35.0k, False: 1]
  Branch (1337:21): [True: 31.8k, False: 3.18k]
1338
        frame = frame->previous;
1339
    }
1340
1341
    /* Now collect them */
1342
    PyObject *cr_origin = PyTuple_New(frame_count);
1343
    if (cr_origin == NULL) {
  Branch (1343:9): [True: 0, False: 3.18k]
1344
        return NULL;
1345
    }
1346
    frame = current_frame;
1347
    for (int i = 0; i < frame_count; 
++i31.8k
) {
  Branch (1347:21): [True: 31.8k, False: 3.18k]
1348
        PyCodeObject *code = frame->f_code;
1349
        int line = _PyInterpreterFrame_GetLine(frame);
1350
        PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line,
1351
                                            code->co_name);
1352
        if (!frameinfo) {
  Branch (1352:13): [True: 0, False: 31.8k]
1353
            Py_DECREF(cr_origin);
1354
            return NULL;
1355
        }
1356
        PyTuple_SET_ITEM(cr_origin, i, frameinfo);
1357
        frame = frame->previous;
1358
    }
1359
1360
    return cr_origin;
1361
}
1362
1363
PyObject *
1364
PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1365
{
1366
    PyObject *coro = gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
1367
    if (!coro) {
  Branch (1367:9): [True: 0, False: 0]
1368
        return NULL;
1369
    }
1370
1371
    PyThreadState *tstate = _PyThreadState_GET();
1372
    int origin_depth = tstate->coroutine_origin_tracking_depth;
1373
1374
    if (origin_depth == 0) {
  Branch (1374:9): [True: 0, False: 0]
1375
        ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
1376
    } else {
1377
        PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame());
1378
        ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
1379
        if (!cr_origin) {
  Branch (1379:13): [True: 0, False: 0]
1380
            Py_DECREF(coro);
1381
            return NULL;
1382
        }
1383
    }
1384
1385
    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
async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg)
1438
{
1439
    Py_VISIT(gen->ag_origin_or_finalizer);
1440
    return gen_traverse((PyGenObject*)gen, visit, arg);
1441
}
1442
1443
1444
static PyObject *
1445
async_gen_repr(PyAsyncGenObject *o)
1446
{
1447
    return PyUnicode_FromFormat("<async_generator object %S at %p>",
1448
                                o->ag_qualname, o);
1449
}
1450
1451
1452
static int
1453
async_gen_init_hooks(PyAsyncGenObject *o)
1454
{
1455
    PyThreadState *tstate;
1456
    PyObject *finalizer;
1457
    PyObject *firstiter;
1458
1459
    if (o->ag_hooks_inited) {
  Branch (1459:9): [True: 441, False: 224]
1460
        return 0;
1461
    }
1462
1463
    o->ag_hooks_inited = 1;
1464
1465
    tstate = _PyThreadState_GET();
1466
1467
    finalizer = tstate->async_gen_finalizer;
1468
    if (finalizer) {
  Branch (1468:9): [True: 145, False: 79]
1469
        Py_INCREF(finalizer);
1470
        o->ag_origin_or_finalizer = finalizer;
1471
    }
1472
1473
    firstiter = tstate->async_gen_firstiter;
1474
    if (firstiter) {
  Branch (1474:9): [True: 145, False: 79]
1475
        PyObject *res;
1476
1477
        Py_INCREF(firstiter);
1478
        res = PyObject_CallOneArg(firstiter, (PyObject *)o);
1479
        Py_DECREF(firstiter);
1480
        if (res == NULL) {
  Branch (1480:13): [True: 0, False: 145]
1481
            return 1;
1482
        }
1483
        Py_DECREF(res);
1484
    }
1485
1486
    return 0;
1487
}
1488
1489
1490
static PyObject *
1491
async_gen_anext(PyAsyncGenObject *o)
1492
{
1493
    if (async_gen_init_hooks(o)) {
  Branch (1493:9): [True: 0, False: 589]
1494
        return NULL;
1495
    }
1496
    return async_gen_asend_new(o, NULL);
1497
}
1498
1499
1500
static PyObject *
1501
async_gen_asend(PyAsyncGenObject *o, PyObject *arg)
1502
{
1503
    if (async_gen_init_hooks(o)) {
  Branch (1503:9): [True: 0, False: 22]
1504
        return NULL;
1505
    }
1506
    return async_gen_asend_new(o, arg);
1507
}
1508
1509
1510
static PyObject *
1511
async_gen_aclose(PyAsyncGenObject *o, PyObject *arg)
1512
{
1513
    if (async_gen_init_hooks(o)) {
  Branch (1513:9): [True: 0, False: 31]
1514
        return NULL;
1515
    }
1516
    return async_gen_athrow_new(o, NULL);
1517
}
1518
1519
static PyObject *
1520
async_gen_athrow(PyAsyncGenObject *o, PyObject *args)
1521
{
1522
    if (async_gen_init_hooks(o)) {
  Branch (1522:9): [True: 0, False: 23]
1523
        return NULL;
1524
    }
1525
    return async_gen_athrow_new(o, args);
1526
}
1527
1528
static PyObject *
1529
ag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored))
1530
{
1531
    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
get_async_gen_state(void)
1637
{
1638
    PyInterpreterState *interp = _PyInterpreterState_GET();
1639
    return &interp->async_gen;
1640
}
1641
#endif
1642
1643
1644
PyObject *
1645
PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1646
{
1647
    PyAsyncGenObject *o;
1648
    o = (PyAsyncGenObject *)gen_new_with_qualname(
1649
        &PyAsyncGen_Type, f, name, qualname);
1650
    if (o == NULL) {
  Branch (1650:9): [True: 0, False: 0]
1651
        return NULL;
1652
    }
1653
    o->ag_origin_or_finalizer = NULL;
1654
    o->ag_closed = 0;
1655
    o->ag_hooks_inited = 0;
1656
    o->ag_running_async = 0;
1657
    return (PyObject*)o;
1658
}
1659
1660
1661
void
1662
_PyAsyncGen_ClearFreeLists(PyInterpreterState *interp)
1663
{
1664
#if _PyAsyncGen_MAXFREELIST > 0
1665
    struct _Py_async_gen_state *state = &interp->async_gen;
1666
1667
    while (state->value_numfree) {
  Branch (1667:12): [True: 15, False: 13.5k]
1668
        _PyAsyncGenWrappedValue *o;
1669
        o = state->value_freelist[--state->value_numfree];
1670
        assert(_PyAsyncGenWrappedValue_CheckExact(o));
1671
        PyObject_GC_Del(o);
1672
    }
1673
1674
    while (state->asend_numfree) {
  Branch (1674:12): [True: 23, False: 13.5k]
1675
        PyAsyncGenASend *o;
1676
        o = state->asend_freelist[--state->asend_numfree];
1677
        assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type));
1678
        PyObject_GC_Del(o);
1679
    }
1680
#endif
1681
}
1682
1683
void
1684
_PyAsyncGen_Fini(PyInterpreterState *interp)
1685
{
1686
    _PyAsyncGen_ClearFreeLists(interp);
1687
#if defined(Py_DEBUG) && _PyAsyncGen_MAXFREELIST > 0
1688
    struct _Py_async_gen_state *state = &interp->async_gen;
1689
    state->value_numfree = -1;
1690
    state->asend_numfree = -1;
1691
#endif
1692
}
1693
1694
1695
static PyObject *
1696
async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)
1697
{
1698
    if (result == NULL) {
  Branch (1698:9): [True: 200, False: 564]
1699
        if (!PyErr_Occurred()) {
  Branch (1699:13): [True: 10, False: 190]
1700
            PyErr_SetNone(PyExc_StopAsyncIteration);
1701
        }
1702
1703
        if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)
  Branch (1703:13): [True: 160, False: 40]
1704
            || 
PyErr_ExceptionMatches(PyExc_GeneratorExit)40
  Branch (1704:16): [True: 1, False: 39]
1705
        ) {
1706
            gen->ag_closed = 1;
1707
        }
1708
1709
        gen->ag_running_async = 0;
1710
        return NULL;
1711
    }
1712
1713
    if (_PyAsyncGenWrappedValue_CheckExact(result)) {
1714
        /* async yield */
1715
        _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val);
1716
        Py_DECREF(result);
1717
        gen->ag_running_async = 0;
1718
        return NULL;
1719
    }
1720
1721
    return result;
1722
}
1723
1724
1725
/* ---------- Async Generator ASend Awaitable ------------ */
1726
1727
1728
static void
1729
async_gen_asend_dealloc(PyAsyncGenASend *o)
1730
{
1731
    _PyObject_GC_UNTRACK((PyObject *)o);
1732
    Py_CLEAR(o->ags_gen);
1733
    Py_CLEAR(o->ags_sendval);
1734
#if _PyAsyncGen_MAXFREELIST > 0
1735
    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
    assert(state->asend_numfree != -1);
1739
#endif
1740
    if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
  Branch (1740:9): [True: 611, False: 0]
1741
        assert(PyAsyncGenASend_CheckExact(o));
1742
        state->asend_freelist[state->asend_numfree++] = o;
1743
    }
1744
    else
1745
#endif
1746
    {
1747
        PyObject_GC_Del(o);
1748
    }
1749
}
1750
1751
static int
1752
async_gen_asend_traverse(PyAsyncGenASend *o, visitproc visit, void *arg)
1753
{
1754
    Py_VISIT(o->ags_gen);
1755
    Py_VISIT(o->ags_sendval);
1756
    return 0;
1757
}
1758
1759
1760
static PyObject *
1761
async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)
1762
{
1763
    PyObject *result;
1764
1765
    if (o->ags_state == AWAITABLE_STATE_CLOSED) {
  Branch (1765:9): [True: 2, False: 715]
1766
        PyErr_SetString(
1767
            PyExc_RuntimeError,
1768
            "cannot reuse already awaited __anext__()/asend()");
1769
        return NULL;
1770
    }
1771
1772
    if (o->ags_state == AWAITABLE_STATE_INIT) {
  Branch (1772:9): [True: 606, False: 109]
1773
        if (o->ags_gen->ag_running_async) {
  Branch (1773:13): [True: 0, False: 606]
1774
            PyErr_SetString(
1775
                PyExc_RuntimeError,
1776
                "anext(): asynchronous generator is already running");
1777
            return NULL;
1778
        }
1779
1780
        if (arg == NULL || 
arg == 10
Py_None10
) {
  Branch (1780:13): [True: 596, False: 10]
  Branch (1780:28): [True: 7, False: 3]
1781
            arg = o->ags_sendval;
1782
        }
1783
        o->ags_state = AWAITABLE_STATE_ITER;
1784
    }
1785
1786
    o->ags_gen->ag_running_async = 1;
1787
    result = gen_send((PyGenObject*)o->ags_gen, arg);
1788
    result = async_gen_unwrap_value(o->ags_gen, result);
1789
1790
    if (result == NULL) {
  Branch (1790:9): [True: 596, False: 119]
1791
        o->ags_state = AWAITABLE_STATE_CLOSED;
1792
    }
1793
1794
    return result;
1795
}
1796
1797
1798
static PyObject *
1799
async_gen_asend_iternext(PyAsyncGenASend *o)
1800
{
1801
    return async_gen_asend_send(o, NULL);
1802
}
1803
1804
1805
static PyObject *
1806
async_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs)
1807
{
1808
    PyObject *result;
1809
1810
    if (o->ags_state == AWAITABLE_STATE_CLOSED) {
  Branch (1810:9): [True: 0, False: 22]
1811
        PyErr_SetString(
1812
            PyExc_RuntimeError,
1813
            "cannot reuse already awaited __anext__()/asend()");
1814
        return NULL;
1815
    }
1816
1817
    result = gen_throw((PyGenObject*)o->ags_gen, args, nargs);
1818
    result = async_gen_unwrap_value(o->ags_gen, result);
1819
1820
    if (result == NULL) {
  Branch (1820:9): [True: 13, False: 9]
1821
        o->ags_state = AWAITABLE_STATE_CLOSED;
1822
    }
1823
1824
    return result;
1825
}
1826
1827
1828
static PyObject *
1829
async_gen_asend_close(PyAsyncGenASend *o, PyObject *args)
1830
{
1831
    o->ags_state = AWAITABLE_STATE_CLOSED;
1832
    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
async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)
1897
{
1898
    PyAsyncGenASend *o;
1899
#if _PyAsyncGen_MAXFREELIST > 0
1900
    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
    assert(state->asend_numfree != -1);
1904
#endif
1905
    if (state->asend_numfree) {
  Branch (1905:9): [True: 588, False: 23]
1906
        state->asend_numfree--;
1907
        o = state->asend_freelist[state->asend_numfree];
1908
        _Py_NewReference((PyObject *)o);
1909
    }
1910
    else
1911
#endif
1912
    {
1913
        o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type);
1914
        if (o == NULL) {
  Branch (1914:13): [True: 0, False: 23]
1915
            return NULL;
1916
        }
1917
    }
1918
1919
    Py_INCREF(gen);
1920
    o->ags_gen = gen;
1921
1922
    Py_XINCREF(sendval);
1923
    o->ags_sendval = sendval;
1924
1925
    o->ags_state = AWAITABLE_STATE_INIT;
1926
1927
    _PyObject_GC_TRACK((PyObject*)o);
1928
    return (PyObject*)o;
1929
}
1930
1931
1932
/* ---------- Async Generator Value Wrapper ------------ */
1933
1934
1935
static void
1936
async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
1937
{
1938
    _PyObject_GC_UNTRACK((PyObject *)o);
1939
    Py_CLEAR(o->agw_val);
1940
#if _PyAsyncGen_MAXFREELIST > 0
1941
    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
    assert(state->value_numfree != -1);
1945
#endif
1946
    if (state->value_numfree < _PyAsyncGen_MAXFREELIST) {
  Branch (1946:9): [True: 434, False: 0]
1947
        assert(_PyAsyncGenWrappedValue_CheckExact(o));
1948
        state->value_freelist[state->value_numfree++] = o;
1949
        OBJECT_STAT_INC(to_freelist);
1950
    }
1951
    else
1952
#endif
1953
    {
1954
        PyObject_GC_Del(o);
1955
    }
1956
}
1957
1958
1959
static int
1960
async_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue *o,
1961
                               visitproc visit, void *arg)
1962
{
1963
    Py_VISIT(o->agw_val);
1964
    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
_PyAsyncGenValueWrapperNew(PyObject *val)
2013
{
2014
    _PyAsyncGenWrappedValue *o;
2015
    assert(val);
2016
2017
#if _PyAsyncGen_MAXFREELIST > 0
2018
    struct _Py_async_gen_state *state = get_async_gen_state();
2019
#ifdef Py_DEBUG
2020
    // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini()
2021
    assert(state->value_numfree != -1);
2022
#endif
2023
    if (state->value_numfree) {
  Branch (2023:9): [True: 419, False: 15]
2024
        state->value_numfree--;
2025
        o = state->value_freelist[state->value_numfree];
2026
        OBJECT_STAT_INC(from_freelist);
2027
        assert(_PyAsyncGenWrappedValue_CheckExact(o));
2028
        _Py_NewReference((PyObject*)o);
2029
    }
2030
    else
2031
#endif
2032
    {
2033
        o = PyObject_GC_New(_PyAsyncGenWrappedValue,
2034
                            &_PyAsyncGenWrappedValue_Type);
2035
        if (o == NULL) {
  Branch (2035:13): [True: 0, False: 15]
2036
            return NULL;
2037
        }
2038
    }
2039
    o->agw_val = val;
2040
    Py_INCREF(val);
2041
    _PyObject_GC_TRACK((PyObject*)o);
2042
    return (PyObject*)o;
2043
}
2044
2045
2046
/* ---------- Async Generator AThrow awaitable ------------ */
2047
2048
2049
static void
2050
async_gen_athrow_dealloc(PyAsyncGenAThrow *o)
2051
{
2052
    _PyObject_GC_UNTRACK((PyObject *)o);
2053
    Py_CLEAR(o->agt_gen);
2054
    Py_CLEAR(o->agt_args);
2055
    PyObject_GC_Del(o);
2056
}
2057
2058
2059
static int
2060
async_gen_athrow_traverse(PyAsyncGenAThrow *o, visitproc visit, void *arg)
2061
{
2062
    Py_VISIT(o->agt_gen);
2063
    Py_VISIT(o->agt_args);
2064
    return 0;
2065
}
2066
2067
2068
static PyObject *
2069
async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
2070
{
2071
    PyGenObject *gen = (PyGenObject*)o->agt_gen;
2072
    PyObject *retval;
2073
2074
    if (o->agt_state == AWAITABLE_STATE_CLOSED) {
  Branch (2074:9): [True: 1, False: 56]
2075
        PyErr_SetString(
2076
            PyExc_RuntimeError,
2077
            "cannot reuse already awaited aclose()/athrow()");
2078
        return NULL;
2079
    }
2080
2081
    if (gen->gi_frame_state >= FRAME_COMPLETED) {
  Branch (2081:9): [True: 7, False: 49]
2082
        o->agt_state = AWAITABLE_STATE_CLOSED;
2083
        PyErr_SetNone(PyExc_StopIteration);
2084
        return NULL;
2085
    }
2086
2087
    if (o->agt_state == AWAITABLE_STATE_INIT) {
  Branch (2087:9): [True: 39, False: 10]
2088
        if (o->agt_gen->ag_running_async) {
  Branch (2088:13): [True: 0, False: 39]
2089
            o->agt_state = AWAITABLE_STATE_CLOSED;
2090
            if (o->agt_args == NULL) {
  Branch (2090:17): [True: 0, False: 0]
2091
                PyErr_SetString(
2092
                    PyExc_RuntimeError,
2093
                    "aclose(): asynchronous generator is already running");
2094
            }
2095
            else {
2096
                PyErr_SetString(
2097
                    PyExc_RuntimeError,
2098
                    "athrow(): asynchronous generator is already running");
2099
            }
2100
            return NULL;
2101
        }
2102
2103
        if (o->agt_gen->ag_closed) {
  Branch (2103:13): [True: 0, False: 39]
2104
            o->agt_state = AWAITABLE_STATE_CLOSED;
2105
            PyErr_SetNone(PyExc_StopAsyncIteration);
2106
            return NULL;
2107
        }
2108
2109
        if (arg != Py_None) {
  Branch (2109:13): [True: 0, False: 39]
2110
            PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG);
2111
            return NULL;
2112
        }
2113
2114
        o->agt_state = AWAITABLE_STATE_ITER;
2115
        o->agt_gen->ag_running_async = 1;
2116
2117
        if (o->agt_args == NULL) {
  Branch (2117:13): [True: 16, False: 23]
2118
            /* aclose() mode */
2119
            o->agt_gen->ag_closed = 1;
2120
2121
            retval = _gen_throw((PyGenObject *)gen,
2122
                                0,  /* Do not close generator when
2123
                                       PyExc_GeneratorExit is passed */
2124
                                PyExc_GeneratorExit, NULL, NULL);
2125
2126
            if (retval && 
_PyAsyncGenWrappedValue_CheckExact6
(retval)) {
  Branch (2126:17): [True: 6, False: 10]
2127
                Py_DECREF(retval);
2128
                goto yield_close;
2129
            }
2130
        } else {
2131
            PyObject *typ;
2132
            PyObject *tb = NULL;
2133
            PyObject *val = NULL;
2134
2135
            if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,
  Branch (2135:17): [True: 0, False: 23]
2136
                                   &typ, &val, &tb)) {
2137
                return NULL;
2138
            }
2139
2140
            retval = _gen_throw((PyGenObject *)gen,
2141
                                0,  /* Do not close generator when
2142
                                       PyExc_GeneratorExit is passed */
2143
                                typ, val, tb);
2144
            retval = async_gen_unwrap_value(o->agt_gen, retval);
2145
        }
2146
        if (retval == NULL) {
  Branch (2146:13): [True: 31, False: 7]
2147
            goto check_error;
2148
        }
2149
        return retval;
2150
    }
2151
2152
    assert(o->agt_state == AWAITABLE_STATE_ITER);
2153
2154
    retval = gen_send((PyGenObject *)gen, arg);
2155
    if (o->agt_args) {
  Branch (2155:9): [True: 3, False: 7]
2156
        return async_gen_unwrap_value(o->agt_gen, retval);
2157
    } else {
2158
        /* aclose() mode */
2159
        if (retval) {
  Branch (2159:13): [True: 4, False: 3]
2160
            if (_PyAsyncGenWrappedValue_CheckExact(retval)) {
2161
                Py_DECREF(retval);
2162
                goto yield_close;
2163
            }
2164
            else {
2165
                return retval;
2166
            }
2167
        }
2168
        else {
2169
            goto check_error;
2170
        }
2171
    }
2172
2173
yield_close:
2174
    o->agt_gen->ag_running_async = 0;
2175
    o->agt_state = AWAITABLE_STATE_CLOSED;
2176
    PyErr_SetString(
2177
        PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
2178
    return NULL;
2179
2180
check_error:
2181
    o->agt_gen->ag_running_async = 0;
2182
    o->agt_state = AWAITABLE_STATE_CLOSED;
2183
    if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
  Branch (2183:9): [True: 3, False: 31]
2184
            
PyErr_ExceptionMatches(PyExc_GeneratorExit)31
)
  Branch (2184:13): [True: 12, False: 19]
2185
    {
2186
        if (o->agt_args == NULL) {
  Branch (2186:13): [True: 12, False: 3]
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
            PyErr_Clear();
2193
            PyErr_SetNone(PyExc_StopIteration);
2194
        }
2195
    }
2196
    return NULL;
2197
}
2198
2199
2200
static PyObject *
2201
async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs)
2202
{
2203
    PyObject *retval;
2204
2205
    if (o->agt_state == AWAITABLE_STATE_CLOSED) {
  Branch (2205:9): [True: 0, False: 9]
2206
        PyErr_SetString(
2207
            PyExc_RuntimeError,
2208
            "cannot reuse already awaited aclose()/athrow()");
2209
        return NULL;
2210
    }
2211
2212
    retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs);
2213
    if (o->agt_args) {
  Branch (2213:9): [True: 1, False: 8]
2214
        return async_gen_unwrap_value(o->agt_gen, retval);
2215
    } else {
2216
        /* aclose() mode */
2217
        if (retval && 
_PyAsyncGenWrappedValue_CheckExact0
(retval)) {
  Branch (2217:13): [True: 0, False: 8]
2218
            o->agt_gen->ag_running_async = 0;
2219
            o->agt_state = AWAITABLE_STATE_CLOSED;
2220
            Py_DECREF(retval);
2221
            PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);
2222
            return NULL;
2223
        }
2224
        if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||
  Branch (2224:13): [True: 0, False: 8]
2225
            PyErr_ExceptionMatches(PyExc_GeneratorExit))
  Branch (2225:13): [True: 1, False: 7]
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
            PyErr_Clear();
2233
            PyErr_SetNone(PyExc_StopIteration);
2234
        }
2235
        return retval;
2236
    }
2237
}
2238
2239
2240
static PyObject *
2241
async_gen_athrow_iternext(PyAsyncGenAThrow *o)
2242
{
2243
    return async_gen_athrow_send(o, Py_None);
2244
}
2245
2246
2247
static PyObject *
2248
async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)
2249
{
2250
    o->agt_state = AWAITABLE_STATE_CLOSED;
2251
    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
async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args)
2317
{
2318
    PyAsyncGenAThrow *o;
2319
    o = PyObject_GC_New(PyAsyncGenAThrow, &_PyAsyncGenAThrow_Type);
2320
    if (o == NULL) {
  Branch (2320:9): [True: 0, False: 54]
2321
        return NULL;
2322
    }
2323
    o->agt_gen = gen;
2324
    o->agt_args = args;
2325
    o->agt_state = AWAITABLE_STATE_INIT;
2326
    Py_INCREF(gen);
2327
    Py_XINCREF(args);
2328
    _PyObject_GC_TRACK((PyObject*)o);
2329
    return (PyObject*)o;
2330
}