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