Home | History | Annotate | Download | only in Modules
      1 #include "Python.h"
      2 #include "structmember.h"
      3 
      4 
      5 /*[clinic input]
      6 module _asyncio
      7 [clinic start generated code]*/
      8 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/
      9 
     10 
     11 /* identifiers used from some functions */
     12 _Py_IDENTIFIER(add_done_callback);
     13 _Py_IDENTIFIER(call_soon);
     14 _Py_IDENTIFIER(cancel);
     15 _Py_IDENTIFIER(send);
     16 _Py_IDENTIFIER(throw);
     17 _Py_IDENTIFIER(_step);
     18 _Py_IDENTIFIER(_schedule_callbacks);
     19 _Py_IDENTIFIER(_wakeup);
     20 
     21 
     22 /* State of the _asyncio module */
     23 static PyObject *all_tasks;
     24 static PyObject *current_tasks;
     25 static PyObject *traceback_extract_stack;
     26 static PyObject *asyncio_get_event_loop;
     27 static PyObject *asyncio_future_repr_info_func;
     28 static PyObject *asyncio_task_repr_info_func;
     29 static PyObject *asyncio_task_get_stack_func;
     30 static PyObject *asyncio_task_print_stack_func;
     31 static PyObject *asyncio_InvalidStateError;
     32 static PyObject *asyncio_CancelledError;
     33 static PyObject *inspect_isgenerator;
     34 
     35 
     36 typedef enum {
     37     STATE_PENDING,
     38     STATE_CANCELLED,
     39     STATE_FINISHED
     40 } fut_state;
     41 
     42 #define FutureObj_HEAD(prefix)                                              \
     43     PyObject_HEAD                                                           \
     44     PyObject *prefix##_loop;                                                \
     45     PyObject *prefix##_callbacks;                                           \
     46     PyObject *prefix##_exception;                                           \
     47     PyObject *prefix##_result;                                              \
     48     PyObject *prefix##_source_tb;                                           \
     49     fut_state prefix##_state;                                               \
     50     int prefix##_log_tb;                                                    \
     51     int prefix##_blocking;                                                  \
     52     PyObject *dict;                                                         \
     53     PyObject *prefix##_weakreflist;
     54 
     55 typedef struct {
     56     FutureObj_HEAD(fut)
     57 } FutureObj;
     58 
     59 typedef struct {
     60     FutureObj_HEAD(task)
     61     PyObject *task_fut_waiter;
     62     PyObject *task_coro;
     63     int task_must_cancel;
     64     int task_log_destroy_pending;
     65 } TaskObj;
     66 
     67 typedef struct {
     68     PyObject_HEAD
     69     TaskObj *sw_task;
     70     PyObject *sw_arg;
     71 } TaskSendMethWrapper;
     72 
     73 typedef struct {
     74     PyObject_HEAD
     75     TaskObj *ww_task;
     76 } TaskWakeupMethWrapper;
     77 
     78 
     79 #include "clinic/_asynciomodule.c.h"
     80 
     81 
     82 /*[clinic input]
     83 class _asyncio.Future "FutureObj *" "&Future_Type"
     84 [clinic start generated code]*/
     85 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/
     86 
     87 /* Get FutureIter from Future */
     88 static PyObject* future_new_iter(PyObject *);
     89 static inline int future_call_schedule_callbacks(FutureObj *);
     90 
     91 static int
     92 future_schedule_callbacks(FutureObj *fut)
     93 {
     94     Py_ssize_t len;
     95     PyObject* iters;
     96     int i;
     97 
     98     if (fut->fut_callbacks == NULL) {
     99         PyErr_SetString(PyExc_RuntimeError, "NULL callbacks");
    100         return -1;
    101     }
    102 
    103     len = PyList_GET_SIZE(fut->fut_callbacks);
    104     if (len == 0) {
    105         return 0;
    106     }
    107 
    108     iters = PyList_GetSlice(fut->fut_callbacks, 0, len);
    109     if (iters == NULL) {
    110         return -1;
    111     }
    112     if (PyList_SetSlice(fut->fut_callbacks, 0, len, NULL) < 0) {
    113         Py_DECREF(iters);
    114         return -1;
    115     }
    116 
    117     for (i = 0; i < len; i++) {
    118         PyObject *handle = NULL;
    119         PyObject *cb = PyList_GET_ITEM(iters, i);
    120 
    121         handle = _PyObject_CallMethodId(
    122             fut->fut_loop, &PyId_call_soon, "OO", cb, fut, NULL);
    123 
    124         if (handle == NULL) {
    125             Py_DECREF(iters);
    126             return -1;
    127         }
    128         else {
    129             Py_DECREF(handle);
    130         }
    131     }
    132 
    133     Py_DECREF(iters);
    134     return 0;
    135 }
    136 
    137 static int
    138 future_init(FutureObj *fut, PyObject *loop)
    139 {
    140     PyObject *res = NULL;
    141     _Py_IDENTIFIER(get_debug);
    142 
    143     if (loop == NULL || loop == Py_None) {
    144         loop = PyObject_CallObject(asyncio_get_event_loop, NULL);
    145         if (loop == NULL) {
    146             return -1;
    147         }
    148     }
    149     else {
    150         Py_INCREF(loop);
    151     }
    152     Py_CLEAR(fut->fut_loop);
    153     fut->fut_loop = loop;
    154 
    155     res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
    156     if (res == NULL) {
    157         return -1;
    158     }
    159     if (PyObject_IsTrue(res)) {
    160         Py_CLEAR(res);
    161         fut->fut_source_tb = PyObject_CallObject(traceback_extract_stack, NULL);
    162         if (fut->fut_source_tb == NULL) {
    163             return -1;
    164         }
    165     }
    166     else {
    167         Py_CLEAR(res);
    168     }
    169 
    170     fut->fut_callbacks = PyList_New(0);
    171     if (fut->fut_callbacks == NULL) {
    172         return -1;
    173     }
    174 
    175     return 0;
    176 }
    177 
    178 static PyObject *
    179 future_set_result(FutureObj *fut, PyObject *res)
    180 {
    181     if (fut->fut_state != STATE_PENDING) {
    182         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
    183         return NULL;
    184     }
    185 
    186     Py_INCREF(res);
    187     fut->fut_result = res;
    188     fut->fut_state = STATE_FINISHED;
    189 
    190     if (future_call_schedule_callbacks(fut) == -1) {
    191         return NULL;
    192     }
    193     Py_RETURN_NONE;
    194 }
    195 
    196 static PyObject *
    197 future_set_exception(FutureObj *fut, PyObject *exc)
    198 {
    199     PyObject *exc_val = NULL;
    200 
    201     if (fut->fut_state != STATE_PENDING) {
    202         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
    203         return NULL;
    204     }
    205 
    206     if (PyExceptionClass_Check(exc)) {
    207         exc_val = PyObject_CallObject(exc, NULL);
    208         if (exc_val == NULL) {
    209             return NULL;
    210         }
    211     }
    212     else {
    213         exc_val = exc;
    214         Py_INCREF(exc_val);
    215     }
    216     if (!PyExceptionInstance_Check(exc_val)) {
    217         Py_DECREF(exc_val);
    218         PyErr_SetString(PyExc_TypeError, "invalid exception object");
    219         return NULL;
    220     }
    221     if ((PyObject*)Py_TYPE(exc_val) == PyExc_StopIteration) {
    222         Py_DECREF(exc_val);
    223         PyErr_SetString(PyExc_TypeError,
    224                         "StopIteration interacts badly with generators "
    225                         "and cannot be raised into a Future");
    226         return NULL;
    227     }
    228 
    229     fut->fut_exception = exc_val;
    230     fut->fut_state = STATE_FINISHED;
    231 
    232     if (future_call_schedule_callbacks(fut) == -1) {
    233         return NULL;
    234     }
    235 
    236     fut->fut_log_tb = 1;
    237     Py_RETURN_NONE;
    238 }
    239 
    240 static int
    241 future_get_result(FutureObj *fut, PyObject **result)
    242 {
    243     PyObject *exc;
    244 
    245     if (fut->fut_state == STATE_CANCELLED) {
    246         exc = _PyObject_CallNoArg(asyncio_CancelledError);
    247         if (exc == NULL) {
    248             return -1;
    249         }
    250         *result = exc;
    251         return 1;
    252     }
    253 
    254     if (fut->fut_state != STATE_FINISHED) {
    255         PyObject *msg = PyUnicode_FromString("Result is not ready.");
    256         if (msg == NULL) {
    257             return -1;
    258         }
    259 
    260         exc = _PyObject_CallArg1(asyncio_InvalidStateError, msg);
    261         Py_DECREF(msg);
    262         if (exc == NULL) {
    263             return -1;
    264         }
    265 
    266         *result = exc;
    267         return 1;
    268     }
    269 
    270     fut->fut_log_tb = 0;
    271     if (fut->fut_exception != NULL) {
    272         Py_INCREF(fut->fut_exception);
    273         *result = fut->fut_exception;
    274         return 1;
    275     }
    276 
    277     Py_INCREF(fut->fut_result);
    278     *result = fut->fut_result;
    279     return 0;
    280 }
    281 
    282 static PyObject *
    283 future_add_done_callback(FutureObj *fut, PyObject *arg)
    284 {
    285     if (fut->fut_state != STATE_PENDING) {
    286         PyObject *handle = _PyObject_CallMethodId(
    287             fut->fut_loop, &PyId_call_soon, "OO", arg, fut, NULL);
    288 
    289         if (handle == NULL) {
    290             return NULL;
    291         }
    292         else {
    293             Py_DECREF(handle);
    294         }
    295     }
    296     else {
    297         int err = PyList_Append(fut->fut_callbacks, arg);
    298         if (err != 0) {
    299             return NULL;
    300         }
    301     }
    302     Py_RETURN_NONE;
    303 }
    304 
    305 static PyObject *
    306 future_cancel(FutureObj *fut)
    307 {
    308     if (fut->fut_state != STATE_PENDING) {
    309         Py_RETURN_FALSE;
    310     }
    311     fut->fut_state = STATE_CANCELLED;
    312 
    313     if (future_call_schedule_callbacks(fut) == -1) {
    314         return NULL;
    315     }
    316 
    317     Py_RETURN_TRUE;
    318 }
    319 
    320 /*[clinic input]
    321 _asyncio.Future.__init__
    322 
    323     *
    324     loop: 'O' = NULL
    325 
    326 This class is *almost* compatible with concurrent.futures.Future.
    327 
    328     Differences:
    329 
    330     - result() and exception() do not take a timeout argument and
    331       raise an exception when the future isn't done yet.
    332 
    333     - Callbacks registered with add_done_callback() are always called
    334       via the event loop's call_soon_threadsafe().
    335 
    336     - This class is not compatible with the wait() and as_completed()
    337       methods in the concurrent.futures package.
    338 [clinic start generated code]*/
    339 
    340 static int
    341 _asyncio_Future___init___impl(FutureObj *self, PyObject *loop)
    342 /*[clinic end generated code: output=9ed75799eaccb5d6 input=8e1681f23605be2d]*/
    343 
    344 {
    345     return future_init(self, loop);
    346 }
    347 
    348 static int
    349 FutureObj_clear(FutureObj *fut)
    350 {
    351     Py_CLEAR(fut->fut_loop);
    352     Py_CLEAR(fut->fut_callbacks);
    353     Py_CLEAR(fut->fut_result);
    354     Py_CLEAR(fut->fut_exception);
    355     Py_CLEAR(fut->fut_source_tb);
    356     Py_CLEAR(fut->dict);
    357     return 0;
    358 }
    359 
    360 static int
    361 FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg)
    362 {
    363     Py_VISIT(fut->fut_loop);
    364     Py_VISIT(fut->fut_callbacks);
    365     Py_VISIT(fut->fut_result);
    366     Py_VISIT(fut->fut_exception);
    367     Py_VISIT(fut->fut_source_tb);
    368     Py_VISIT(fut->dict);
    369     return 0;
    370 }
    371 
    372 /*[clinic input]
    373 _asyncio.Future.result
    374 
    375 Return the result this future represents.
    376 
    377 If the future has been cancelled, raises CancelledError.  If the
    378 future's result isn't yet available, raises InvalidStateError.  If
    379 the future is done and has an exception set, this exception is raised.
    380 [clinic start generated code]*/
    381 
    382 static PyObject *
    383 _asyncio_Future_result_impl(FutureObj *self)
    384 /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/
    385 {
    386     PyObject *result;
    387     int res = future_get_result(self, &result);
    388 
    389     if (res == -1) {
    390         return NULL;
    391     }
    392 
    393     if (res == 0) {
    394         return result;
    395     }
    396 
    397     assert(res == 1);
    398 
    399     PyErr_SetObject(PyExceptionInstance_Class(result), result);
    400     Py_DECREF(result);
    401     return NULL;
    402 }
    403 
    404 /*[clinic input]
    405 _asyncio.Future.exception
    406 
    407 Return the exception that was set on this future.
    408 
    409 The exception (or None if no exception was set) is returned only if
    410 the future is done.  If the future has been cancelled, raises
    411 CancelledError.  If the future isn't done yet, raises
    412 InvalidStateError.
    413 [clinic start generated code]*/
    414 
    415 static PyObject *
    416 _asyncio_Future_exception_impl(FutureObj *self)
    417 /*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/
    418 {
    419     if (self->fut_state == STATE_CANCELLED) {
    420         PyErr_SetString(asyncio_CancelledError, "");
    421         return NULL;
    422     }
    423 
    424     if (self->fut_state != STATE_FINISHED) {
    425         PyErr_SetString(asyncio_InvalidStateError, "Result is not ready.");
    426         return NULL;
    427     }
    428 
    429     if (self->fut_exception != NULL) {
    430         self->fut_log_tb = 0;
    431         Py_INCREF(self->fut_exception);
    432         return self->fut_exception;
    433     }
    434 
    435     Py_RETURN_NONE;
    436 }
    437 
    438 /*[clinic input]
    439 _asyncio.Future.set_result
    440 
    441     res: 'O'
    442     /
    443 
    444 Mark the future done and set its result.
    445 
    446 If the future is already done when this method is called, raises
    447 InvalidStateError.
    448 [clinic start generated code]*/
    449 
    450 static PyObject *
    451 _asyncio_Future_set_result(FutureObj *self, PyObject *res)
    452 /*[clinic end generated code: output=a620abfc2796bfb6 input=8619565e0503357e]*/
    453 {
    454     return future_set_result(self, res);
    455 }
    456 
    457 /*[clinic input]
    458 _asyncio.Future.set_exception
    459 
    460     exception: 'O'
    461     /
    462 
    463 Mark the future done and set an exception.
    464 
    465 If the future is already done when this method is called, raises
    466 InvalidStateError.
    467 [clinic start generated code]*/
    468 
    469 static PyObject *
    470 _asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
    471 /*[clinic end generated code: output=f1c1b0cd321be360 input=1377dbe15e6ea186]*/
    472 {
    473     return future_set_exception(self, exception);
    474 }
    475 
    476 /*[clinic input]
    477 _asyncio.Future.add_done_callback
    478 
    479     fn: 'O'
    480     /
    481 
    482 Add a callback to be run when the future becomes done.
    483 
    484 The callback is called with a single argument - the future object. If
    485 the future is already done when this is called, the callback is
    486 scheduled with call_soon.
    487 [clinic start generated code]*/
    488 
    489 static PyObject *
    490 _asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn)
    491 /*[clinic end generated code: output=819e09629b2ec2b5 input=8cce187e32cec6a8]*/
    492 {
    493     return future_add_done_callback(self, fn);
    494 }
    495 
    496 /*[clinic input]
    497 _asyncio.Future.remove_done_callback
    498 
    499     fn: 'O'
    500     /
    501 
    502 Remove all instances of a callback from the "call when done" list.
    503 
    504 Returns the number of callbacks removed.
    505 [clinic start generated code]*/
    506 
    507 static PyObject *
    508 _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
    509 /*[clinic end generated code: output=5ab1fb52b24ef31f input=3fedb73e1409c31c]*/
    510 {
    511     PyObject *newlist;
    512     Py_ssize_t len, i, j=0;
    513 
    514     len = PyList_GET_SIZE(self->fut_callbacks);
    515     if (len == 0) {
    516         return PyLong_FromSsize_t(0);
    517     }
    518 
    519     newlist = PyList_New(len);
    520     if (newlist == NULL) {
    521         return NULL;
    522     }
    523 
    524     for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
    525         int ret;
    526         PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);
    527 
    528         if ((ret = PyObject_RichCompareBool(fn, item, Py_EQ)) < 0) {
    529             goto fail;
    530         }
    531         if (ret == 0) {
    532             Py_INCREF(item);
    533             PyList_SET_ITEM(newlist, j, item);
    534             j++;
    535         }
    536     }
    537 
    538     if (PyList_SetSlice(newlist, j, len, NULL) < 0) {
    539         goto fail;
    540     }
    541     if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) {
    542         goto fail;
    543     }
    544     Py_DECREF(newlist);
    545     return PyLong_FromSsize_t(len - j);
    546 
    547 fail:
    548     Py_DECREF(newlist);
    549     return NULL;
    550 }
    551 
    552 /*[clinic input]
    553 _asyncio.Future.cancel
    554 
    555 Cancel the future and schedule callbacks.
    556 
    557 If the future is already done or cancelled, return False.  Otherwise,
    558 change the future's state to cancelled, schedule the callbacks and
    559 return True.
    560 [clinic start generated code]*/
    561 
    562 static PyObject *
    563 _asyncio_Future_cancel_impl(FutureObj *self)
    564 /*[clinic end generated code: output=e45b932ba8bd68a1 input=515709a127995109]*/
    565 {
    566     return future_cancel(self);
    567 }
    568 
    569 /*[clinic input]
    570 _asyncio.Future.cancelled
    571 
    572 Return True if the future was cancelled.
    573 [clinic start generated code]*/
    574 
    575 static PyObject *
    576 _asyncio_Future_cancelled_impl(FutureObj *self)
    577 /*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/
    578 {
    579     if (self->fut_state == STATE_CANCELLED) {
    580         Py_RETURN_TRUE;
    581     }
    582     else {
    583         Py_RETURN_FALSE;
    584     }
    585 }
    586 
    587 /*[clinic input]
    588 _asyncio.Future.done
    589 
    590 Return True if the future is done.
    591 
    592 Done means either that a result / exception are available, or that the
    593 future was cancelled.
    594 [clinic start generated code]*/
    595 
    596 static PyObject *
    597 _asyncio_Future_done_impl(FutureObj *self)
    598 /*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/
    599 {
    600     if (self->fut_state == STATE_PENDING) {
    601         Py_RETURN_FALSE;
    602     }
    603     else {
    604         Py_RETURN_TRUE;
    605     }
    606 }
    607 
    608 static PyObject *
    609 FutureObj_get_blocking(FutureObj *fut)
    610 {
    611     if (fut->fut_blocking) {
    612         Py_RETURN_TRUE;
    613     }
    614     else {
    615         Py_RETURN_FALSE;
    616     }
    617 }
    618 
    619 static int
    620 FutureObj_set_blocking(FutureObj *fut, PyObject *val)
    621 {
    622     int is_true = PyObject_IsTrue(val);
    623     if (is_true < 0) {
    624         return -1;
    625     }
    626     fut->fut_blocking = is_true;
    627     return 0;
    628 }
    629 
    630 static PyObject *
    631 FutureObj_get_log_traceback(FutureObj *fut)
    632 {
    633     if (fut->fut_log_tb) {
    634         Py_RETURN_TRUE;
    635     }
    636     else {
    637         Py_RETURN_FALSE;
    638     }
    639 }
    640 
    641 static PyObject *
    642 FutureObj_get_loop(FutureObj *fut)
    643 {
    644     if (fut->fut_loop == NULL) {
    645         Py_RETURN_NONE;
    646     }
    647     Py_INCREF(fut->fut_loop);
    648     return fut->fut_loop;
    649 }
    650 
    651 static PyObject *
    652 FutureObj_get_callbacks(FutureObj *fut)
    653 {
    654     if (fut->fut_callbacks == NULL) {
    655         Py_RETURN_NONE;
    656     }
    657     Py_INCREF(fut->fut_callbacks);
    658     return fut->fut_callbacks;
    659 }
    660 
    661 static PyObject *
    662 FutureObj_get_result(FutureObj *fut)
    663 {
    664     if (fut->fut_result == NULL) {
    665         Py_RETURN_NONE;
    666     }
    667     Py_INCREF(fut->fut_result);
    668     return fut->fut_result;
    669 }
    670 
    671 static PyObject *
    672 FutureObj_get_exception(FutureObj *fut)
    673 {
    674     if (fut->fut_exception == NULL) {
    675         Py_RETURN_NONE;
    676     }
    677     Py_INCREF(fut->fut_exception);
    678     return fut->fut_exception;
    679 }
    680 
    681 static PyObject *
    682 FutureObj_get_source_traceback(FutureObj *fut)
    683 {
    684     if (fut->fut_source_tb == NULL) {
    685         Py_RETURN_NONE;
    686     }
    687     Py_INCREF(fut->fut_source_tb);
    688     return fut->fut_source_tb;
    689 }
    690 
    691 static PyObject *
    692 FutureObj_get_state(FutureObj *fut)
    693 {
    694     _Py_IDENTIFIER(PENDING);
    695     _Py_IDENTIFIER(CANCELLED);
    696     _Py_IDENTIFIER(FINISHED);
    697     PyObject *ret = NULL;
    698 
    699     switch (fut->fut_state) {
    700     case STATE_PENDING:
    701         ret = _PyUnicode_FromId(&PyId_PENDING);
    702         break;
    703     case STATE_CANCELLED:
    704         ret = _PyUnicode_FromId(&PyId_CANCELLED);
    705         break;
    706     case STATE_FINISHED:
    707         ret = _PyUnicode_FromId(&PyId_FINISHED);
    708         break;
    709     default:
    710         assert (0);
    711     }
    712     Py_INCREF(ret);
    713     return ret;
    714 }
    715 
    716 /*[clinic input]
    717 _asyncio.Future._repr_info
    718 [clinic start generated code]*/
    719 
    720 static PyObject *
    721 _asyncio_Future__repr_info_impl(FutureObj *self)
    722 /*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/
    723 {
    724     return PyObject_CallFunctionObjArgs(
    725         asyncio_future_repr_info_func, self, NULL);
    726 }
    727 
    728 /*[clinic input]
    729 _asyncio.Future._schedule_callbacks
    730 [clinic start generated code]*/
    731 
    732 static PyObject *
    733 _asyncio_Future__schedule_callbacks_impl(FutureObj *self)
    734 /*[clinic end generated code: output=5e8958d89ea1c5dc input=4f5f295f263f4a88]*/
    735 {
    736     int ret = future_schedule_callbacks(self);
    737     if (ret == -1) {
    738         return NULL;
    739     }
    740     Py_RETURN_NONE;
    741 }
    742 
    743 static PyObject *
    744 FutureObj_repr(FutureObj *fut)
    745 {
    746     _Py_IDENTIFIER(_repr_info);
    747 
    748     PyObject *_repr_info = _PyUnicode_FromId(&PyId__repr_info);  // borrowed
    749     if (_repr_info == NULL) {
    750         return NULL;
    751     }
    752 
    753     PyObject *rinfo = PyObject_CallMethodObjArgs((PyObject*)fut, _repr_info,
    754                                                  NULL);
    755     if (rinfo == NULL) {
    756         return NULL;
    757     }
    758 
    759     PyObject *sp = PyUnicode_FromString(" ");
    760     if (sp == NULL) {
    761         Py_DECREF(rinfo);
    762         return NULL;
    763     }
    764 
    765     PyObject *rinfo_s = PyUnicode_Join(sp, rinfo);
    766     Py_DECREF(sp);
    767     Py_DECREF(rinfo);
    768     if (rinfo_s == NULL) {
    769         return NULL;
    770     }
    771 
    772     PyObject *rstr = NULL;
    773     PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut),
    774                                                  "__name__");
    775     if (type_name != NULL) {
    776         rstr = PyUnicode_FromFormat("<%S %S>", type_name, rinfo_s);
    777         Py_DECREF(type_name);
    778     }
    779     Py_DECREF(rinfo_s);
    780     return rstr;
    781 }
    782 
    783 static void
    784 FutureObj_finalize(FutureObj *fut)
    785 {
    786     _Py_IDENTIFIER(call_exception_handler);
    787     _Py_IDENTIFIER(message);
    788     _Py_IDENTIFIER(exception);
    789     _Py_IDENTIFIER(future);
    790     _Py_IDENTIFIER(source_traceback);
    791 
    792     if (!fut->fut_log_tb) {
    793         return;
    794     }
    795     assert(fut->fut_exception != NULL);
    796     fut->fut_log_tb = 0;;
    797 
    798     PyObject *error_type, *error_value, *error_traceback;
    799     /* Save the current exception, if any. */
    800     PyErr_Fetch(&error_type, &error_value, &error_traceback);
    801 
    802     PyObject *context = NULL;
    803     PyObject *type_name = NULL;
    804     PyObject *message = NULL;
    805     PyObject *func = NULL;
    806     PyObject *res = NULL;
    807 
    808     context = PyDict_New();
    809     if (context == NULL) {
    810         goto finally;
    811     }
    812 
    813     type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__");
    814     if (type_name == NULL) {
    815         goto finally;
    816     }
    817 
    818     message = PyUnicode_FromFormat(
    819         "%S exception was never retrieved", type_name);
    820     if (message == NULL) {
    821         goto finally;
    822     }
    823 
    824     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
    825         _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 ||
    826         _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) {
    827         goto finally;
    828     }
    829     if (fut->fut_source_tb != NULL) {
    830         if (_PyDict_SetItemId(context, &PyId_source_traceback,
    831                               fut->fut_source_tb) < 0) {
    832             goto finally;
    833         }
    834     }
    835 
    836     func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler);
    837     if (func != NULL) {
    838         res = _PyObject_CallArg1(func, context);
    839         if (res == NULL) {
    840             PyErr_WriteUnraisable(func);
    841         }
    842     }
    843 
    844 finally:
    845     Py_CLEAR(context);
    846     Py_CLEAR(type_name);
    847     Py_CLEAR(message);
    848     Py_CLEAR(func);
    849     Py_CLEAR(res);
    850 
    851     /* Restore the saved exception. */
    852     PyErr_Restore(error_type, error_value, error_traceback);
    853 }
    854 
    855 
    856 static PyAsyncMethods FutureType_as_async = {
    857     (unaryfunc)future_new_iter,         /* am_await */
    858     0,                                  /* am_aiter */
    859     0                                   /* am_anext */
    860 };
    861 
    862 static PyMethodDef FutureType_methods[] = {
    863     _ASYNCIO_FUTURE_RESULT_METHODDEF
    864     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
    865     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
    866     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
    867     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
    868     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
    869     _ASYNCIO_FUTURE_CANCEL_METHODDEF
    870     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
    871     _ASYNCIO_FUTURE_DONE_METHODDEF
    872     _ASYNCIO_FUTURE__REPR_INFO_METHODDEF
    873     _ASYNCIO_FUTURE__SCHEDULE_CALLBACKS_METHODDEF
    874     {NULL, NULL}        /* Sentinel */
    875 };
    876 
    877 #define FUTURE_COMMON_GETSETLIST                                              \
    878     {"_state", (getter)FutureObj_get_state, NULL, NULL},                      \
    879     {"_asyncio_future_blocking", (getter)FutureObj_get_blocking,              \
    880                                  (setter)FutureObj_set_blocking, NULL},       \
    881     {"_loop", (getter)FutureObj_get_loop, NULL, NULL},                        \
    882     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \
    883     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \
    884     {"_exception", (getter)FutureObj_get_exception, NULL, NULL},              \
    885     {"_log_traceback", (getter)FutureObj_get_log_traceback, NULL, NULL},      \
    886     {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL},
    887 
    888 static PyGetSetDef FutureType_getsetlist[] = {
    889     FUTURE_COMMON_GETSETLIST
    890     {NULL} /* Sentinel */
    891 };
    892 
    893 static void FutureObj_dealloc(PyObject *self);
    894 
    895 static PyTypeObject FutureType = {
    896     PyVarObject_HEAD_INIT(NULL, 0)
    897     "_asyncio.Future",
    898     sizeof(FutureObj),                       /* tp_basicsize */
    899     .tp_dealloc = FutureObj_dealloc,
    900     .tp_as_async = &FutureType_as_async,
    901     .tp_repr = (reprfunc)FutureObj_repr,
    902     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE
    903         | Py_TPFLAGS_HAVE_FINALIZE,
    904     .tp_doc = _asyncio_Future___init____doc__,
    905     .tp_traverse = (traverseproc)FutureObj_traverse,
    906     .tp_clear = (inquiry)FutureObj_clear,
    907     .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist),
    908     .tp_iter = (getiterfunc)future_new_iter,
    909     .tp_methods = FutureType_methods,
    910     .tp_getset = FutureType_getsetlist,
    911     .tp_dictoffset = offsetof(FutureObj, dict),
    912     .tp_init = (initproc)_asyncio_Future___init__,
    913     .tp_new = PyType_GenericNew,
    914     .tp_finalize = (destructor)FutureObj_finalize,
    915 };
    916 
    917 #define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType)
    918 
    919 static inline int
    920 future_call_schedule_callbacks(FutureObj *fut)
    921 {
    922     if (Future_CheckExact(fut)) {
    923         return future_schedule_callbacks(fut);
    924     }
    925     else {
    926         /* `fut` is a subclass of Future */
    927         PyObject *ret = _PyObject_CallMethodId(
    928             (PyObject*)fut, &PyId__schedule_callbacks, NULL);
    929         if (ret == NULL) {
    930             return -1;
    931         }
    932 
    933         Py_DECREF(ret);
    934         return 0;
    935     }
    936 }
    937 
    938 static void
    939 FutureObj_dealloc(PyObject *self)
    940 {
    941     FutureObj *fut = (FutureObj *)self;
    942 
    943     if (Future_CheckExact(fut)) {
    944         /* When fut is subclass of Future, finalizer is called from
    945          * subtype_dealloc.
    946          */
    947         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
    948             // resurrected.
    949             return;
    950         }
    951     }
    952 
    953     if (fut->fut_weakreflist != NULL) {
    954         PyObject_ClearWeakRefs(self);
    955     }
    956 
    957     (void)FutureObj_clear(fut);
    958     Py_TYPE(fut)->tp_free(fut);
    959 }
    960 
    961 
    962 /*********************** Future Iterator **************************/
    963 
    964 typedef struct {
    965     PyObject_HEAD
    966     FutureObj *future;
    967 } futureiterobject;
    968 
    969 static void
    970 FutureIter_dealloc(futureiterobject *it)
    971 {
    972     PyObject_GC_UnTrack(it);
    973     Py_XDECREF(it->future);
    974     PyObject_GC_Del(it);
    975 }
    976 
    977 static PyObject *
    978 FutureIter_iternext(futureiterobject *it)
    979 {
    980     PyObject *res;
    981     FutureObj *fut = it->future;
    982 
    983     if (fut == NULL) {
    984         return NULL;
    985     }
    986 
    987     if (fut->fut_state == STATE_PENDING) {
    988         if (!fut->fut_blocking) {
    989             fut->fut_blocking = 1;
    990             Py_INCREF(fut);
    991             return (PyObject *)fut;
    992         }
    993         PyErr_Format(PyExc_AssertionError,
    994                      "yield from wasn't used with future");
    995         return NULL;
    996     }
    997 
    998     res = _asyncio_Future_result_impl(fut);
    999     if (res != NULL) {
   1000         /* The result of the Future is not an exception. */
   1001         if (_PyGen_SetStopIterationValue(res) < 0) {
   1002             Py_DECREF(res);
   1003             return NULL;
   1004         }
   1005         Py_DECREF(res);
   1006     }
   1007 
   1008     it->future = NULL;
   1009     Py_DECREF(fut);
   1010     return NULL;
   1011 }
   1012 
   1013 static PyObject *
   1014 FutureIter_send(futureiterobject *self, PyObject *unused)
   1015 {
   1016     /* Future.__iter__ doesn't care about values that are pushed to the
   1017      * generator, it just returns "self.result().
   1018      */
   1019     return FutureIter_iternext(self);
   1020 }
   1021 
   1022 static PyObject *
   1023 FutureIter_throw(futureiterobject *self, PyObject *args)
   1024 {
   1025     PyObject *type=NULL, *val=NULL, *tb=NULL;
   1026     if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb))
   1027         return NULL;
   1028 
   1029     if (val == Py_None) {
   1030         val = NULL;
   1031     }
   1032     if (tb == Py_None) {
   1033         tb = NULL;
   1034     } else if (tb != NULL && !PyTraceBack_Check(tb)) {
   1035         PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback");
   1036         return NULL;
   1037     }
   1038 
   1039     Py_INCREF(type);
   1040     Py_XINCREF(val);
   1041     Py_XINCREF(tb);
   1042 
   1043     if (PyExceptionClass_Check(type)) {
   1044         PyErr_NormalizeException(&type, &val, &tb);
   1045         /* No need to call PyException_SetTraceback since we'll be calling
   1046            PyErr_Restore for `type`, `val`, and `tb`. */
   1047     } else if (PyExceptionInstance_Check(type)) {
   1048         if (val) {
   1049             PyErr_SetString(PyExc_TypeError,
   1050                             "instance exception may not have a separate value");
   1051             goto fail;
   1052         }
   1053         val = type;
   1054         type = PyExceptionInstance_Class(type);
   1055         Py_INCREF(type);
   1056         if (tb == NULL)
   1057             tb = PyException_GetTraceback(val);
   1058     } else {
   1059         PyErr_SetString(PyExc_TypeError,
   1060                         "exceptions must be classes deriving BaseException or "
   1061                         "instances of such a class");
   1062         goto fail;
   1063     }
   1064 
   1065     Py_CLEAR(self->future);
   1066 
   1067     PyErr_Restore(type, val, tb);
   1068 
   1069     return FutureIter_iternext(self);
   1070 
   1071   fail:
   1072     Py_DECREF(type);
   1073     Py_XDECREF(val);
   1074     Py_XDECREF(tb);
   1075     return NULL;
   1076 }
   1077 
   1078 static PyObject *
   1079 FutureIter_close(futureiterobject *self, PyObject *arg)
   1080 {
   1081     Py_CLEAR(self->future);
   1082     Py_RETURN_NONE;
   1083 }
   1084 
   1085 static int
   1086 FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg)
   1087 {
   1088     Py_VISIT(it->future);
   1089     return 0;
   1090 }
   1091 
   1092 static PyMethodDef FutureIter_methods[] = {
   1093     {"send",  (PyCFunction)FutureIter_send, METH_O, NULL},
   1094     {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL},
   1095     {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL},
   1096     {NULL, NULL}        /* Sentinel */
   1097 };
   1098 
   1099 static PyTypeObject FutureIterType = {
   1100     PyVarObject_HEAD_INIT(NULL, 0)
   1101     "_asyncio.FutureIter",
   1102     .tp_basicsize = sizeof(futureiterobject),
   1103     .tp_itemsize = 0,
   1104     .tp_dealloc = (destructor)FutureIter_dealloc,
   1105     .tp_getattro = PyObject_GenericGetAttr,
   1106     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
   1107     .tp_traverse = (traverseproc)FutureIter_traverse,
   1108     .tp_iter = PyObject_SelfIter,
   1109     .tp_iternext = (iternextfunc)FutureIter_iternext,
   1110     .tp_methods = FutureIter_methods,
   1111 };
   1112 
   1113 static PyObject *
   1114 future_new_iter(PyObject *fut)
   1115 {
   1116     futureiterobject *it;
   1117 
   1118     if (!PyObject_TypeCheck(fut, &FutureType)) {
   1119         PyErr_BadInternalCall();
   1120         return NULL;
   1121     }
   1122     it = PyObject_GC_New(futureiterobject, &FutureIterType);
   1123     if (it == NULL) {
   1124         return NULL;
   1125     }
   1126     Py_INCREF(fut);
   1127     it->future = (FutureObj*)fut;
   1128     PyObject_GC_Track(it);
   1129     return (PyObject*)it;
   1130 }
   1131 
   1132 
   1133 /*********************** Task **************************/
   1134 
   1135 
   1136 /*[clinic input]
   1137 class _asyncio.Task "TaskObj *" "&Task_Type"
   1138 [clinic start generated code]*/
   1139 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/
   1140 
   1141 static int task_call_step_soon(TaskObj *, PyObject *);
   1142 static inline PyObject * task_call_wakeup(TaskObj *, PyObject *);
   1143 static inline PyObject * task_call_step(TaskObj *, PyObject *);
   1144 static PyObject * task_wakeup(TaskObj *, PyObject *);
   1145 static PyObject * task_step(TaskObj *, PyObject *);
   1146 
   1147 /* ----- Task._step wrapper */
   1148 
   1149 static int
   1150 TaskSendMethWrapper_clear(TaskSendMethWrapper *o)
   1151 {
   1152     Py_CLEAR(o->sw_task);
   1153     Py_CLEAR(o->sw_arg);
   1154     return 0;
   1155 }
   1156 
   1157 static void
   1158 TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o)
   1159 {
   1160     PyObject_GC_UnTrack(o);
   1161     (void)TaskSendMethWrapper_clear(o);
   1162     Py_TYPE(o)->tp_free(o);
   1163 }
   1164 
   1165 static PyObject *
   1166 TaskSendMethWrapper_call(TaskSendMethWrapper *o,
   1167                          PyObject *args, PyObject *kwds)
   1168 {
   1169     return task_call_step(o->sw_task, o->sw_arg);
   1170 }
   1171 
   1172 static int
   1173 TaskSendMethWrapper_traverse(TaskSendMethWrapper *o,
   1174                              visitproc visit, void *arg)
   1175 {
   1176     Py_VISIT(o->sw_task);
   1177     Py_VISIT(o->sw_arg);
   1178     return 0;
   1179 }
   1180 
   1181 static PyObject *
   1182 TaskSendMethWrapper_get___self__(TaskSendMethWrapper *o)
   1183 {
   1184     if (o->sw_task) {
   1185         Py_INCREF(o->sw_task);
   1186         return (PyObject*)o->sw_task;
   1187     }
   1188     Py_RETURN_NONE;
   1189 }
   1190 
   1191 static PyGetSetDef TaskSendMethWrapper_getsetlist[] = {
   1192     {"__self__", (getter)TaskSendMethWrapper_get___self__, NULL, NULL},
   1193     {NULL} /* Sentinel */
   1194 };
   1195 
   1196 PyTypeObject TaskSendMethWrapper_Type = {
   1197     PyVarObject_HEAD_INIT(NULL, 0)
   1198     "TaskSendMethWrapper",
   1199     .tp_basicsize = sizeof(TaskSendMethWrapper),
   1200     .tp_itemsize = 0,
   1201     .tp_getset = TaskSendMethWrapper_getsetlist,
   1202     .tp_dealloc = (destructor)TaskSendMethWrapper_dealloc,
   1203     .tp_call = (ternaryfunc)TaskSendMethWrapper_call,
   1204     .tp_getattro = PyObject_GenericGetAttr,
   1205     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
   1206     .tp_traverse = (traverseproc)TaskSendMethWrapper_traverse,
   1207     .tp_clear = (inquiry)TaskSendMethWrapper_clear,
   1208 };
   1209 
   1210 static PyObject *
   1211 TaskSendMethWrapper_new(TaskObj *task, PyObject *arg)
   1212 {
   1213     TaskSendMethWrapper *o;
   1214     o = PyObject_GC_New(TaskSendMethWrapper, &TaskSendMethWrapper_Type);
   1215     if (o == NULL) {
   1216         return NULL;
   1217     }
   1218 
   1219     Py_INCREF(task);
   1220     o->sw_task = task;
   1221 
   1222     Py_XINCREF(arg);
   1223     o->sw_arg = arg;
   1224 
   1225     PyObject_GC_Track(o);
   1226     return (PyObject*) o;
   1227 }
   1228 
   1229 /* ----- Task._wakeup wrapper */
   1230 
   1231 static PyObject *
   1232 TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o,
   1233                            PyObject *args, PyObject *kwds)
   1234 {
   1235     PyObject *fut;
   1236 
   1237     if (!PyArg_ParseTuple(args, "O|", &fut)) {
   1238         return NULL;
   1239     }
   1240 
   1241     return task_call_wakeup(o->ww_task, fut);
   1242 }
   1243 
   1244 static int
   1245 TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o)
   1246 {
   1247     Py_CLEAR(o->ww_task);
   1248     return 0;
   1249 }
   1250 
   1251 static int
   1252 TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o,
   1253                                visitproc visit, void *arg)
   1254 {
   1255     Py_VISIT(o->ww_task);
   1256     return 0;
   1257 }
   1258 
   1259 static void
   1260 TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o)
   1261 {
   1262     PyObject_GC_UnTrack(o);
   1263     (void)TaskWakeupMethWrapper_clear(o);
   1264     Py_TYPE(o)->tp_free(o);
   1265 }
   1266 
   1267 PyTypeObject TaskWakeupMethWrapper_Type = {
   1268     PyVarObject_HEAD_INIT(NULL, 0)
   1269     "TaskWakeupMethWrapper",
   1270     .tp_basicsize = sizeof(TaskWakeupMethWrapper),
   1271     .tp_itemsize = 0,
   1272     .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc,
   1273     .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call,
   1274     .tp_getattro = PyObject_GenericGetAttr,
   1275     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
   1276     .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse,
   1277     .tp_clear = (inquiry)TaskWakeupMethWrapper_clear,
   1278 };
   1279 
   1280 static PyObject *
   1281 TaskWakeupMethWrapper_new(TaskObj *task)
   1282 {
   1283     TaskWakeupMethWrapper *o;
   1284     o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type);
   1285     if (o == NULL) {
   1286         return NULL;
   1287     }
   1288 
   1289     Py_INCREF(task);
   1290     o->ww_task = task;
   1291 
   1292     PyObject_GC_Track(o);
   1293     return (PyObject*) o;
   1294 }
   1295 
   1296 /* ----- Task */
   1297 
   1298 /*[clinic input]
   1299 _asyncio.Task.__init__
   1300 
   1301     coro: 'O'
   1302     *
   1303     loop: 'O' = NULL
   1304 
   1305 A coroutine wrapped in a Future.
   1306 [clinic start generated code]*/
   1307 
   1308 static int
   1309 _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
   1310 /*[clinic end generated code: output=9f24774c2287fc2f input=71d8d28c201a18cd]*/
   1311 {
   1312     PyObject *res;
   1313     _Py_IDENTIFIER(add);
   1314 
   1315     if (future_init((FutureObj*)self, loop)) {
   1316         return -1;
   1317     }
   1318 
   1319     self->task_fut_waiter = NULL;
   1320     self->task_must_cancel = 0;
   1321     self->task_log_destroy_pending = 1;
   1322 
   1323     Py_INCREF(coro);
   1324     self->task_coro = coro;
   1325 
   1326     if (task_call_step_soon(self, NULL)) {
   1327         return -1;
   1328     }
   1329 
   1330     res = _PyObject_CallMethodIdObjArgs(all_tasks, &PyId_add, self, NULL);
   1331     if (res == NULL) {
   1332         return -1;
   1333     }
   1334     Py_DECREF(res);
   1335 
   1336     return 0;
   1337 }
   1338 
   1339 static int
   1340 TaskObj_clear(TaskObj *task)
   1341 {
   1342     (void)FutureObj_clear((FutureObj*) task);
   1343     Py_CLEAR(task->task_coro);
   1344     Py_CLEAR(task->task_fut_waiter);
   1345     return 0;
   1346 }
   1347 
   1348 static int
   1349 TaskObj_traverse(TaskObj *task, visitproc visit, void *arg)
   1350 {
   1351     Py_VISIT(task->task_coro);
   1352     Py_VISIT(task->task_fut_waiter);
   1353     (void)FutureObj_traverse((FutureObj*) task, visit, arg);
   1354     return 0;
   1355 }
   1356 
   1357 static PyObject *
   1358 TaskObj_get_log_destroy_pending(TaskObj *task)
   1359 {
   1360     if (task->task_log_destroy_pending) {
   1361         Py_RETURN_TRUE;
   1362     }
   1363     else {
   1364         Py_RETURN_FALSE;
   1365     }
   1366 }
   1367 
   1368 static int
   1369 TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val)
   1370 {
   1371     int is_true = PyObject_IsTrue(val);
   1372     if (is_true < 0) {
   1373         return -1;
   1374     }
   1375     task->task_log_destroy_pending = is_true;
   1376     return 0;
   1377 }
   1378 
   1379 static PyObject *
   1380 TaskObj_get_must_cancel(TaskObj *task)
   1381 {
   1382     if (task->task_must_cancel) {
   1383         Py_RETURN_TRUE;
   1384     }
   1385     else {
   1386         Py_RETURN_FALSE;
   1387     }
   1388 }
   1389 
   1390 static PyObject *
   1391 TaskObj_get_coro(TaskObj *task)
   1392 {
   1393     if (task->task_coro) {
   1394         Py_INCREF(task->task_coro);
   1395         return task->task_coro;
   1396     }
   1397 
   1398     Py_RETURN_NONE;
   1399 }
   1400 
   1401 static PyObject *
   1402 TaskObj_get_fut_waiter(TaskObj *task)
   1403 {
   1404     if (task->task_fut_waiter) {
   1405         Py_INCREF(task->task_fut_waiter);
   1406         return task->task_fut_waiter;
   1407     }
   1408 
   1409     Py_RETURN_NONE;
   1410 }
   1411 
   1412 /*[clinic input]
   1413 @classmethod
   1414 _asyncio.Task.current_task
   1415 
   1416     loop: 'O' = None
   1417 
   1418 Return the currently running task in an event loop or None.
   1419 
   1420 By default the current task for the current event loop is returned.
   1421 
   1422 None is returned when called not in the context of a Task.
   1423 [clinic start generated code]*/
   1424 
   1425 static PyObject *
   1426 _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop)
   1427 /*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/
   1428 {
   1429     PyObject *res;
   1430 
   1431     if (loop == Py_None) {
   1432         loop = _PyObject_CallNoArg(asyncio_get_event_loop);
   1433         if (loop == NULL) {
   1434             return NULL;
   1435         }
   1436 
   1437         res = PyDict_GetItem(current_tasks, loop);
   1438         Py_DECREF(loop);
   1439     }
   1440     else {
   1441         res = PyDict_GetItem(current_tasks, loop);
   1442     }
   1443 
   1444     if (res == NULL) {
   1445         Py_RETURN_NONE;
   1446     }
   1447     else {
   1448         Py_INCREF(res);
   1449         return res;
   1450     }
   1451 }
   1452 
   1453 static PyObject *
   1454 task_all_tasks(PyObject *loop)
   1455 {
   1456     PyObject *task;
   1457     PyObject *task_loop;
   1458     PyObject *set;
   1459     PyObject *iter;
   1460 
   1461     assert(loop != NULL);
   1462 
   1463     set = PySet_New(NULL);
   1464     if (set == NULL) {
   1465         return NULL;
   1466     }
   1467 
   1468     iter = PyObject_GetIter(all_tasks);
   1469     if (iter == NULL) {
   1470         goto fail;
   1471     }
   1472 
   1473     while ((task = PyIter_Next(iter))) {
   1474         task_loop = PyObject_GetAttrString(task, "_loop");
   1475         if (task_loop == NULL) {
   1476             Py_DECREF(task);
   1477             goto fail;
   1478         }
   1479         if (task_loop == loop) {
   1480             if (PySet_Add(set, task) == -1) {
   1481                 Py_DECREF(task_loop);
   1482                 Py_DECREF(task);
   1483                 goto fail;
   1484             }
   1485         }
   1486         Py_DECREF(task_loop);
   1487         Py_DECREF(task);
   1488     }
   1489 
   1490     Py_DECREF(iter);
   1491     return set;
   1492 
   1493 fail:
   1494     Py_XDECREF(set);
   1495     Py_XDECREF(iter);
   1496     return NULL;
   1497 }
   1498 
   1499 /*[clinic input]
   1500 @classmethod
   1501 _asyncio.Task.all_tasks
   1502 
   1503     loop: 'O' = None
   1504 
   1505 Return a set of all tasks for an event loop.
   1506 
   1507 By default all tasks for the current event loop are returned.
   1508 [clinic start generated code]*/
   1509 
   1510 static PyObject *
   1511 _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop)
   1512 /*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/
   1513 {
   1514     PyObject *res;
   1515 
   1516     if (loop == Py_None) {
   1517         loop = _PyObject_CallNoArg(asyncio_get_event_loop);
   1518         if (loop == NULL) {
   1519             return NULL;
   1520         }
   1521 
   1522         res = task_all_tasks(loop);
   1523         Py_DECREF(loop);
   1524     }
   1525     else {
   1526         res = task_all_tasks(loop);
   1527     }
   1528 
   1529     return res;
   1530 }
   1531 
   1532 /*[clinic input]
   1533 _asyncio.Task._repr_info
   1534 [clinic start generated code]*/
   1535 
   1536 static PyObject *
   1537 _asyncio_Task__repr_info_impl(TaskObj *self)
   1538 /*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/
   1539 {
   1540     return PyObject_CallFunctionObjArgs(
   1541         asyncio_task_repr_info_func, self, NULL);
   1542 }
   1543 
   1544 /*[clinic input]
   1545 _asyncio.Task.cancel
   1546 
   1547 Request that this task cancel itself.
   1548 
   1549 This arranges for a CancelledError to be thrown into the
   1550 wrapped coroutine on the next cycle through the event loop.
   1551 The coroutine then has a chance to clean up or even deny
   1552 the request using try/except/finally.
   1553 
   1554 Unlike Future.cancel, this does not guarantee that the
   1555 task will be cancelled: the exception might be caught and
   1556 acted upon, delaying cancellation of the task or preventing
   1557 cancellation completely.  The task may also return a value or
   1558 raise a different exception.
   1559 
   1560 Immediately after this method is called, Task.cancelled() will
   1561 not return True (unless the task was already cancelled).  A
   1562 task will be marked as cancelled when the wrapped coroutine
   1563 terminates with a CancelledError exception (even if cancel()
   1564 was not called).
   1565 [clinic start generated code]*/
   1566 
   1567 static PyObject *
   1568 _asyncio_Task_cancel_impl(TaskObj *self)
   1569 /*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/
   1570 {
   1571     if (self->task_state != STATE_PENDING) {
   1572         Py_RETURN_FALSE;
   1573     }
   1574 
   1575     if (self->task_fut_waiter) {
   1576         PyObject *res;
   1577         int is_true;
   1578 
   1579         res = _PyObject_CallMethodId(
   1580             self->task_fut_waiter, &PyId_cancel, NULL);
   1581         if (res == NULL) {
   1582             return NULL;
   1583         }
   1584 
   1585         is_true = PyObject_IsTrue(res);
   1586         Py_DECREF(res);
   1587         if (is_true < 0) {
   1588             return NULL;
   1589         }
   1590 
   1591         if (is_true) {
   1592             Py_RETURN_TRUE;
   1593         }
   1594     }
   1595 
   1596     self->task_must_cancel = 1;
   1597     Py_RETURN_TRUE;
   1598 }
   1599 
   1600 /*[clinic input]
   1601 _asyncio.Task.get_stack
   1602 
   1603     *
   1604     limit: 'O' = None
   1605 
   1606 Return the list of stack frames for this task's coroutine.
   1607 
   1608 If the coroutine is not done, this returns the stack where it is
   1609 suspended.  If the coroutine has completed successfully or was
   1610 cancelled, this returns an empty list.  If the coroutine was
   1611 terminated by an exception, this returns the list of traceback
   1612 frames.
   1613 
   1614 The frames are always ordered from oldest to newest.
   1615 
   1616 The optional limit gives the maximum number of frames to
   1617 return; by default all available frames are returned.  Its
   1618 meaning differs depending on whether a stack or a traceback is
   1619 returned: the newest frames of a stack are returned, but the
   1620 oldest frames of a traceback are returned.  (This matches the
   1621 behavior of the traceback module.)
   1622 
   1623 For reasons beyond our control, only one stack frame is
   1624 returned for a suspended coroutine.
   1625 [clinic start generated code]*/
   1626 
   1627 static PyObject *
   1628 _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
   1629 /*[clinic end generated code: output=c9aeeeebd1e18118 input=b1920230a766d17a]*/
   1630 {
   1631     return PyObject_CallFunctionObjArgs(
   1632         asyncio_task_get_stack_func, self, limit, NULL);
   1633 }
   1634 
   1635 /*[clinic input]
   1636 _asyncio.Task.print_stack
   1637 
   1638     *
   1639     limit: 'O' = None
   1640     file: 'O' = None
   1641 
   1642 Print the stack or traceback for this task's coroutine.
   1643 
   1644 This produces output similar to that of the traceback module,
   1645 for the frames retrieved by get_stack().  The limit argument
   1646 is passed to get_stack().  The file argument is an I/O stream
   1647 to which the output is written; by default output is written
   1648 to sys.stderr.
   1649 [clinic start generated code]*/
   1650 
   1651 static PyObject *
   1652 _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
   1653                                PyObject *file)
   1654 /*[clinic end generated code: output=7339e10314cd3f4d input=19f1e99ab5400bc3]*/
   1655 {
   1656     return PyObject_CallFunctionObjArgs(
   1657         asyncio_task_print_stack_func, self, limit, file, NULL);
   1658 }
   1659 
   1660 /*[clinic input]
   1661 _asyncio.Task._step
   1662 
   1663     exc: 'O' = NULL
   1664 [clinic start generated code]*/
   1665 
   1666 static PyObject *
   1667 _asyncio_Task__step_impl(TaskObj *self, PyObject *exc)
   1668 /*[clinic end generated code: output=7ed23f0cefd5ae42 input=ada4b2324e5370af]*/
   1669 {
   1670     return task_step(self, exc == Py_None ? NULL : exc);
   1671 }
   1672 
   1673 /*[clinic input]
   1674 _asyncio.Task._wakeup
   1675 
   1676     fut: 'O'
   1677 [clinic start generated code]*/
   1678 
   1679 static PyObject *
   1680 _asyncio_Task__wakeup_impl(TaskObj *self, PyObject *fut)
   1681 /*[clinic end generated code: output=75cb341c760fd071 input=11ee4918a5bdbf21]*/
   1682 {
   1683     return task_wakeup(self, fut);
   1684 }
   1685 
   1686 static void
   1687 TaskObj_finalize(TaskObj *task)
   1688 {
   1689     _Py_IDENTIFIER(call_exception_handler);
   1690     _Py_IDENTIFIER(task);
   1691     _Py_IDENTIFIER(message);
   1692     _Py_IDENTIFIER(source_traceback);
   1693 
   1694     PyObject *message = NULL;
   1695     PyObject *context = NULL;
   1696     PyObject *func = NULL;
   1697     PyObject *res = NULL;
   1698 
   1699     PyObject *error_type, *error_value, *error_traceback;
   1700 
   1701     if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
   1702         goto done;
   1703     }
   1704 
   1705     /* Save the current exception, if any. */
   1706     PyErr_Fetch(&error_type, &error_value, &error_traceback);
   1707 
   1708     context = PyDict_New();
   1709     if (context == NULL) {
   1710         goto finally;
   1711     }
   1712 
   1713     message = PyUnicode_FromString("Task was destroyed but it is pending!");
   1714     if (message == NULL) {
   1715         goto finally;
   1716     }
   1717 
   1718     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
   1719         _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0)
   1720     {
   1721         goto finally;
   1722     }
   1723 
   1724     if (task->task_source_tb != NULL) {
   1725         if (_PyDict_SetItemId(context, &PyId_source_traceback,
   1726                               task->task_source_tb) < 0)
   1727         {
   1728             goto finally;
   1729         }
   1730     }
   1731 
   1732     func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler);
   1733     if (func != NULL) {
   1734         res = _PyObject_CallArg1(func, context);
   1735         if (res == NULL) {
   1736             PyErr_WriteUnraisable(func);
   1737         }
   1738     }
   1739 
   1740 finally:
   1741     Py_CLEAR(context);
   1742     Py_CLEAR(message);
   1743     Py_CLEAR(func);
   1744     Py_CLEAR(res);
   1745 
   1746     /* Restore the saved exception. */
   1747     PyErr_Restore(error_type, error_value, error_traceback);
   1748 
   1749 done:
   1750     FutureObj_finalize((FutureObj*)task);
   1751 }
   1752 
   1753 static void TaskObj_dealloc(PyObject *);  /* Needs Task_CheckExact */
   1754 
   1755 static PyMethodDef TaskType_methods[] = {
   1756     _ASYNCIO_FUTURE_RESULT_METHODDEF
   1757     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
   1758     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
   1759     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
   1760     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
   1761     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
   1762     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
   1763     _ASYNCIO_FUTURE_DONE_METHODDEF
   1764     _ASYNCIO_TASK_CURRENT_TASK_METHODDEF
   1765     _ASYNCIO_TASK_ALL_TASKS_METHODDEF
   1766     _ASYNCIO_TASK_CANCEL_METHODDEF
   1767     _ASYNCIO_TASK_GET_STACK_METHODDEF
   1768     _ASYNCIO_TASK_PRINT_STACK_METHODDEF
   1769     _ASYNCIO_TASK__WAKEUP_METHODDEF
   1770     _ASYNCIO_TASK__STEP_METHODDEF
   1771     _ASYNCIO_TASK__REPR_INFO_METHODDEF
   1772     {NULL, NULL}        /* Sentinel */
   1773 };
   1774 
   1775 static PyGetSetDef TaskType_getsetlist[] = {
   1776     FUTURE_COMMON_GETSETLIST
   1777     {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending,
   1778                              (setter)TaskObj_set_log_destroy_pending, NULL},
   1779     {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL},
   1780     {"_coro", (getter)TaskObj_get_coro, NULL, NULL},
   1781     {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL},
   1782     {NULL} /* Sentinel */
   1783 };
   1784 
   1785 static PyTypeObject TaskType = {
   1786     PyVarObject_HEAD_INIT(NULL, 0)
   1787     "_asyncio.Task",
   1788     sizeof(TaskObj),                       /* tp_basicsize */
   1789     .tp_base = &FutureType,
   1790     .tp_dealloc = TaskObj_dealloc,
   1791     .tp_as_async = &FutureType_as_async,
   1792     .tp_repr = (reprfunc)FutureObj_repr,
   1793     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE
   1794         | Py_TPFLAGS_HAVE_FINALIZE,
   1795     .tp_doc = _asyncio_Task___init____doc__,
   1796     .tp_traverse = (traverseproc)TaskObj_traverse,
   1797     .tp_clear = (inquiry)TaskObj_clear,
   1798     .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist),
   1799     .tp_iter = (getiterfunc)future_new_iter,
   1800     .tp_methods = TaskType_methods,
   1801     .tp_getset = TaskType_getsetlist,
   1802     .tp_dictoffset = offsetof(TaskObj, dict),
   1803     .tp_init = (initproc)_asyncio_Task___init__,
   1804     .tp_new = PyType_GenericNew,
   1805     .tp_finalize = (destructor)TaskObj_finalize,
   1806 };
   1807 
   1808 #define Task_CheckExact(obj) (Py_TYPE(obj) == &TaskType)
   1809 
   1810 static void
   1811 TaskObj_dealloc(PyObject *self)
   1812 {
   1813     TaskObj *task = (TaskObj *)self;
   1814 
   1815     if (Task_CheckExact(self)) {
   1816         /* When fut is subclass of Task, finalizer is called from
   1817          * subtype_dealloc.
   1818          */
   1819         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
   1820             // resurrected.
   1821             return;
   1822         }
   1823     }
   1824 
   1825     if (task->task_weakreflist != NULL) {
   1826         PyObject_ClearWeakRefs(self);
   1827     }
   1828 
   1829     (void)TaskObj_clear(task);
   1830     Py_TYPE(task)->tp_free(task);
   1831 }
   1832 
   1833 static inline PyObject *
   1834 task_call_wakeup(TaskObj *task, PyObject *fut)
   1835 {
   1836     if (Task_CheckExact(task)) {
   1837         return task_wakeup(task, fut);
   1838     }
   1839     else {
   1840         /* `task` is a subclass of Task */
   1841         return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__wakeup,
   1842                                              fut, NULL);
   1843     }
   1844 }
   1845 
   1846 static inline PyObject *
   1847 task_call_step(TaskObj *task, PyObject *arg)
   1848 {
   1849     if (Task_CheckExact(task)) {
   1850         return task_step(task, arg);
   1851     }
   1852     else {
   1853         /* `task` is a subclass of Task */
   1854         if (arg == NULL) {
   1855             arg = Py_None;
   1856         }
   1857         return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step,
   1858                                              arg, NULL);
   1859     }
   1860 }
   1861 
   1862 static int
   1863 task_call_step_soon(TaskObj *task, PyObject *arg)
   1864 {
   1865     PyObject *handle;
   1866 
   1867     PyObject *cb = TaskSendMethWrapper_new(task, arg);
   1868     if (cb == NULL) {
   1869         return -1;
   1870     }
   1871 
   1872     handle = _PyObject_CallMethodIdObjArgs(task->task_loop, &PyId_call_soon,
   1873                                            cb, NULL);
   1874     Py_DECREF(cb);
   1875     if (handle == NULL) {
   1876         return -1;
   1877     }
   1878 
   1879     Py_DECREF(handle);
   1880     return 0;
   1881 }
   1882 
   1883 static PyObject *
   1884 task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...)
   1885 {
   1886     PyObject* msg;
   1887 
   1888     va_list vargs;
   1889 #ifdef HAVE_STDARG_PROTOTYPES
   1890     va_start(vargs, format);
   1891 #else
   1892     va_start(vargs);
   1893 #endif
   1894     msg = PyUnicode_FromFormatV(format, vargs);
   1895     va_end(vargs);
   1896 
   1897     if (msg == NULL) {
   1898         return NULL;
   1899     }
   1900 
   1901     PyObject *e = PyObject_CallFunctionObjArgs(et, msg, NULL);
   1902     Py_DECREF(msg);
   1903     if (e == NULL) {
   1904         return NULL;
   1905     }
   1906 
   1907     if (task_call_step_soon(task, e) == -1) {
   1908         Py_DECREF(e);
   1909         return NULL;
   1910     }
   1911 
   1912     Py_DECREF(e);
   1913     Py_RETURN_NONE;
   1914 }
   1915 
   1916 static PyObject *
   1917 task_step_impl(TaskObj *task, PyObject *exc)
   1918 {
   1919     int res;
   1920     int clear_exc = 0;
   1921     PyObject *result = NULL;
   1922     PyObject *coro = task->task_coro;
   1923     PyObject *o;
   1924 
   1925     if (task->task_state != STATE_PENDING) {
   1926         PyErr_Format(PyExc_AssertionError,
   1927                      "_step(): already done: %R %R",
   1928                      task,
   1929                      exc ? exc : Py_None);
   1930         goto fail;
   1931     }
   1932 
   1933     if (task->task_must_cancel) {
   1934         assert(exc != Py_None);
   1935 
   1936         if (exc) {
   1937             /* Check if exc is a CancelledError */
   1938             res = PyObject_IsInstance(exc, asyncio_CancelledError);
   1939             if (res == -1) {
   1940                 /* An error occurred, abort */
   1941                 goto fail;
   1942             }
   1943             if (res == 0) {
   1944                 /* exc is not CancelledError; reset it to NULL */
   1945                 exc = NULL;
   1946             }
   1947         }
   1948 
   1949         if (!exc) {
   1950             /* exc was not a CancelledError */
   1951             exc = PyObject_CallFunctionObjArgs(asyncio_CancelledError, NULL);
   1952             if (!exc) {
   1953                 goto fail;
   1954             }
   1955             clear_exc = 1;
   1956         }
   1957 
   1958         task->task_must_cancel = 0;
   1959     }
   1960 
   1961     Py_CLEAR(task->task_fut_waiter);
   1962 
   1963     if (exc == NULL) {
   1964         if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) {
   1965             result = _PyGen_Send((PyGenObject*)coro, Py_None);
   1966         }
   1967         else {
   1968             result = _PyObject_CallMethodIdObjArgs(
   1969                 coro, &PyId_send, Py_None, NULL);
   1970         }
   1971     }
   1972     else {
   1973         result = _PyObject_CallMethodIdObjArgs(
   1974             coro, &PyId_throw, exc, NULL);
   1975         if (clear_exc) {
   1976             /* We created 'exc' during this call */
   1977             Py_CLEAR(exc);
   1978         }
   1979     }
   1980 
   1981     if (result == NULL) {
   1982         PyObject *et, *ev, *tb;
   1983 
   1984         if (_PyGen_FetchStopIterationValue(&o) == 0) {
   1985             /* The error is StopIteration and that means that
   1986                the underlying coroutine has resolved */
   1987             PyObject *res = future_set_result((FutureObj*)task, o);
   1988             Py_DECREF(o);
   1989             if (res == NULL) {
   1990                 return NULL;
   1991             }
   1992             Py_DECREF(res);
   1993             Py_RETURN_NONE;
   1994         }
   1995 
   1996         if (PyErr_ExceptionMatches(asyncio_CancelledError)) {
   1997             /* CancelledError */
   1998             PyErr_Clear();
   1999             return future_cancel((FutureObj*)task);
   2000         }
   2001 
   2002         /* Some other exception; pop it and call Task.set_exception() */
   2003         PyErr_Fetch(&et, &ev, &tb);
   2004         assert(et);
   2005         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
   2006             PyErr_NormalizeException(&et, &ev, &tb);
   2007         }
   2008         if (tb != NULL) {
   2009             PyException_SetTraceback(ev, tb);
   2010         }
   2011         o = future_set_exception((FutureObj*)task, ev);
   2012         if (!o) {
   2013             /* An exception in Task.set_exception() */
   2014             Py_XDECREF(et);
   2015             Py_XDECREF(tb);
   2016             Py_XDECREF(ev);
   2017             goto fail;
   2018         }
   2019         assert(o == Py_None);
   2020         Py_CLEAR(o);
   2021 
   2022         if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) {
   2023             /* We've got a BaseException; re-raise it */
   2024             PyErr_Restore(et, ev, tb);
   2025             goto fail;
   2026         }
   2027 
   2028         Py_XDECREF(et);
   2029         Py_XDECREF(tb);
   2030         Py_XDECREF(ev);
   2031 
   2032         Py_RETURN_NONE;
   2033     }
   2034 
   2035     if (result == (PyObject*)task) {
   2036         /* We have a task that wants to await on itself */
   2037         goto self_await;
   2038     }
   2039 
   2040     /* Check if `result` is FutureObj or TaskObj (and not a subclass) */
   2041     if (Future_CheckExact(result) || Task_CheckExact(result)) {
   2042         PyObject *wrapper;
   2043         PyObject *res;
   2044         FutureObj *fut = (FutureObj*)result;
   2045 
   2046         /* Check if `result` future is attached to a different loop */
   2047         if (fut->fut_loop != task->task_loop) {
   2048             goto different_loop;
   2049         }
   2050 
   2051         if (fut->fut_blocking) {
   2052             fut->fut_blocking = 0;
   2053 
   2054             /* result.add_done_callback(task._wakeup) */
   2055             wrapper = TaskWakeupMethWrapper_new(task);
   2056             if (wrapper == NULL) {
   2057                 goto fail;
   2058             }
   2059             res = future_add_done_callback((FutureObj*)result, wrapper);
   2060             Py_DECREF(wrapper);
   2061             if (res == NULL) {
   2062                 goto fail;
   2063             }
   2064             Py_DECREF(res);
   2065 
   2066             /* task._fut_waiter = result */
   2067             task->task_fut_waiter = result;  /* no incref is necessary */
   2068 
   2069             if (task->task_must_cancel) {
   2070                 PyObject *r;
   2071                 r = future_cancel(fut);
   2072                 if (r == NULL) {
   2073                     return NULL;
   2074                 }
   2075                 if (r == Py_True) {
   2076                     task->task_must_cancel = 0;
   2077                 }
   2078                 Py_DECREF(r);
   2079             }
   2080 
   2081             Py_RETURN_NONE;
   2082         }
   2083         else {
   2084             goto yield_insteadof_yf;
   2085         }
   2086     }
   2087 
   2088     /* Check if `result` is a Future-compatible object */
   2089     o = PyObject_GetAttrString(result, "_asyncio_future_blocking");
   2090     if (o == NULL) {
   2091         if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
   2092             PyErr_Clear();
   2093         }
   2094         else {
   2095             goto fail;
   2096         }
   2097     }
   2098     else {
   2099         if (o == Py_None) {
   2100             Py_CLEAR(o);
   2101         }
   2102         else {
   2103             /* `result` is a Future-compatible object */
   2104             PyObject *wrapper;
   2105             PyObject *res;
   2106 
   2107             int blocking = PyObject_IsTrue(o);
   2108             Py_CLEAR(o);
   2109             if (blocking < 0) {
   2110                 goto fail;
   2111             }
   2112 
   2113             /* Check if `result` future is attached to a different loop */
   2114             PyObject *oloop = PyObject_GetAttrString(result, "_loop");
   2115             if (oloop == NULL) {
   2116                 goto fail;
   2117             }
   2118             if (oloop != task->task_loop) {
   2119                 Py_DECREF(oloop);
   2120                 goto different_loop;
   2121             }
   2122             else {
   2123                 Py_DECREF(oloop);
   2124             }
   2125 
   2126             if (blocking) {
   2127                 /* result._asyncio_future_blocking = False */
   2128                 if (PyObject_SetAttrString(
   2129                         result, "_asyncio_future_blocking", Py_False) == -1) {
   2130                     goto fail;
   2131                 }
   2132 
   2133                 /* result.add_done_callback(task._wakeup) */
   2134                 wrapper = TaskWakeupMethWrapper_new(task);
   2135                 if (wrapper == NULL) {
   2136                     goto fail;
   2137                 }
   2138                 res = _PyObject_CallMethodIdObjArgs(result,
   2139                                                     &PyId_add_done_callback,
   2140                                                     wrapper, NULL);
   2141                 Py_DECREF(wrapper);
   2142                 if (res == NULL) {
   2143                     goto fail;
   2144                 }
   2145                 Py_DECREF(res);
   2146 
   2147                 /* task._fut_waiter = result */
   2148                 task->task_fut_waiter = result;  /* no incref is necessary */
   2149 
   2150                 if (task->task_must_cancel) {
   2151                     PyObject *r;
   2152                     int is_true;
   2153                     r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
   2154                     if (r == NULL) {
   2155                         return NULL;
   2156                     }
   2157                     is_true = PyObject_IsTrue(r);
   2158                     Py_DECREF(r);
   2159                     if (is_true < 0) {
   2160                         return NULL;
   2161                     }
   2162                     else if (is_true) {
   2163                         task->task_must_cancel = 0;
   2164                     }
   2165                 }
   2166 
   2167                 Py_RETURN_NONE;
   2168             }
   2169             else {
   2170                 goto yield_insteadof_yf;
   2171             }
   2172         }
   2173     }
   2174 
   2175     /* Check if `result` is None */
   2176     if (result == Py_None) {
   2177         /* Bare yield relinquishes control for one event loop iteration. */
   2178         if (task_call_step_soon(task, NULL)) {
   2179             goto fail;
   2180         }
   2181         return result;
   2182     }
   2183 
   2184     /* Check if `result` is a generator */
   2185     o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL);
   2186     if (o == NULL) {
   2187         /* An exception in inspect.isgenerator */
   2188         goto fail;
   2189     }
   2190     res = PyObject_IsTrue(o);
   2191     Py_CLEAR(o);
   2192     if (res == -1) {
   2193         /* An exception while checking if 'val' is True */
   2194         goto fail;
   2195     }
   2196     if (res == 1) {
   2197         /* `result` is a generator */
   2198         PyObject *ret;
   2199         ret = task_set_error_soon(
   2200             task, PyExc_RuntimeError,
   2201             "yield was used instead of yield from for "
   2202             "generator in task %R with %S", task, result);
   2203         Py_DECREF(result);
   2204         return ret;
   2205     }
   2206 
   2207     /* The `result` is none of the above */
   2208     Py_DECREF(result);
   2209     return task_set_error_soon(
   2210         task, PyExc_RuntimeError, "Task got bad yield: %R", result);
   2211 
   2212 self_await:
   2213     o = task_set_error_soon(
   2214         task, PyExc_RuntimeError,
   2215         "Task cannot await on itself: %R", task);
   2216     Py_DECREF(result);
   2217     return o;
   2218 
   2219 yield_insteadof_yf:
   2220     o = task_set_error_soon(
   2221         task, PyExc_RuntimeError,
   2222         "yield was used instead of yield from "
   2223         "in task %R with %R",
   2224         task, result);
   2225     Py_DECREF(result);
   2226     return o;
   2227 
   2228 different_loop:
   2229     o = task_set_error_soon(
   2230         task, PyExc_RuntimeError,
   2231         "Task %R got Future %R attached to a different loop",
   2232         task, result);
   2233     Py_DECREF(result);
   2234     return o;
   2235 
   2236 fail:
   2237     Py_XDECREF(result);
   2238     return NULL;
   2239 }
   2240 
   2241 static PyObject *
   2242 task_step(TaskObj *task, PyObject *exc)
   2243 {
   2244     PyObject *res;
   2245     PyObject *ot;
   2246 
   2247     if (PyDict_SetItem(current_tasks,
   2248                        task->task_loop, (PyObject*)task) == -1)
   2249     {
   2250         return NULL;
   2251     }
   2252 
   2253     res = task_step_impl(task, exc);
   2254 
   2255     if (res == NULL) {
   2256         PyObject *et, *ev, *tb;
   2257         PyErr_Fetch(&et, &ev, &tb);
   2258         ot = _PyDict_Pop(current_tasks, task->task_loop, NULL);
   2259         if (ot == NULL) {
   2260             Py_XDECREF(et);
   2261             Py_XDECREF(tb);
   2262             Py_XDECREF(ev);
   2263             return NULL;
   2264         }
   2265         Py_DECREF(ot);
   2266         PyErr_Restore(et, ev, tb);
   2267         return NULL;
   2268     }
   2269     else {
   2270         ot = _PyDict_Pop(current_tasks, task->task_loop, NULL);
   2271         if (ot == NULL) {
   2272             Py_DECREF(res);
   2273             return NULL;
   2274         }
   2275         else {
   2276             Py_DECREF(ot);
   2277             return res;
   2278         }
   2279     }
   2280 }
   2281 
   2282 static PyObject *
   2283 task_wakeup(TaskObj *task, PyObject *o)
   2284 {
   2285     assert(o);
   2286 
   2287     if (Future_CheckExact(o) || Task_CheckExact(o)) {
   2288         PyObject *fut_result = NULL;
   2289         int res = future_get_result((FutureObj*)o, &fut_result);
   2290         PyObject *result;
   2291 
   2292         switch(res) {
   2293         case -1:
   2294             assert(fut_result == NULL);
   2295             return NULL;
   2296         case 0:
   2297             Py_DECREF(fut_result);
   2298             return task_call_step(task, NULL);
   2299         default:
   2300             assert(res == 1);
   2301             result = task_call_step(task, fut_result);
   2302             Py_DECREF(fut_result);
   2303             return result;
   2304         }
   2305     }
   2306 
   2307     PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
   2308     if (fut_result == NULL) {
   2309         PyObject *et, *ev, *tb;
   2310         PyObject *res;
   2311 
   2312         PyErr_Fetch(&et, &ev, &tb);
   2313         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
   2314             PyErr_NormalizeException(&et, &ev, &tb);
   2315         }
   2316 
   2317         res = task_call_step(task, ev);
   2318 
   2319         Py_XDECREF(et);
   2320         Py_XDECREF(tb);
   2321         Py_XDECREF(ev);
   2322 
   2323         return res;
   2324     }
   2325     else {
   2326         Py_DECREF(fut_result);
   2327         return task_call_step(task, NULL);
   2328     }
   2329 }
   2330 
   2331 
   2332 /*********************** Module **************************/
   2333 
   2334 
   2335 static void
   2336 module_free(void *m)
   2337 {
   2338     Py_CLEAR(current_tasks);
   2339     Py_CLEAR(all_tasks);
   2340     Py_CLEAR(traceback_extract_stack);
   2341     Py_CLEAR(asyncio_get_event_loop);
   2342     Py_CLEAR(asyncio_future_repr_info_func);
   2343     Py_CLEAR(asyncio_task_repr_info_func);
   2344     Py_CLEAR(asyncio_task_get_stack_func);
   2345     Py_CLEAR(asyncio_task_print_stack_func);
   2346     Py_CLEAR(asyncio_InvalidStateError);
   2347     Py_CLEAR(asyncio_CancelledError);
   2348     Py_CLEAR(inspect_isgenerator);
   2349 }
   2350 
   2351 static int
   2352 module_init(void)
   2353 {
   2354     PyObject *module = NULL;
   2355     PyObject *cls;
   2356 
   2357 #define WITH_MOD(NAME) \
   2358     Py_CLEAR(module); \
   2359     module = PyImport_ImportModule(NAME); \
   2360     if (module == NULL) { \
   2361         return -1; \
   2362     }
   2363 
   2364 #define GET_MOD_ATTR(VAR, NAME) \
   2365     VAR = PyObject_GetAttrString(module, NAME); \
   2366     if (VAR == NULL) { \
   2367         goto fail; \
   2368     }
   2369 
   2370     WITH_MOD("asyncio.events")
   2371     GET_MOD_ATTR(asyncio_get_event_loop, "get_event_loop")
   2372 
   2373     WITH_MOD("asyncio.base_futures")
   2374     GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info")
   2375     GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError")
   2376     GET_MOD_ATTR(asyncio_CancelledError, "CancelledError")
   2377 
   2378     WITH_MOD("asyncio.base_tasks")
   2379     GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info")
   2380     GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack")
   2381     GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack")
   2382 
   2383     WITH_MOD("inspect")
   2384     GET_MOD_ATTR(inspect_isgenerator, "isgenerator")
   2385 
   2386     WITH_MOD("traceback")
   2387     GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
   2388 
   2389     WITH_MOD("weakref")
   2390     GET_MOD_ATTR(cls, "WeakSet")
   2391     all_tasks = PyObject_CallObject(cls, NULL);
   2392     Py_CLEAR(cls);
   2393     if (all_tasks == NULL) {
   2394         goto fail;
   2395     }
   2396 
   2397     current_tasks = PyDict_New();
   2398     if (current_tasks == NULL) {
   2399         goto fail;
   2400     }
   2401 
   2402     Py_CLEAR(module);
   2403     return 0;
   2404 
   2405 fail:
   2406     Py_CLEAR(module);
   2407     module_free(NULL);
   2408     return -1;
   2409 
   2410 #undef WITH_MOD
   2411 #undef GET_MOD_ATTR
   2412 }
   2413 
   2414 PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
   2415 
   2416 static struct PyModuleDef _asynciomodule = {
   2417     PyModuleDef_HEAD_INIT,      /* m_base */
   2418     "_asyncio",                 /* m_name */
   2419     module_doc,                 /* m_doc */
   2420     -1,                         /* m_size */
   2421     NULL,                       /* m_methods */
   2422     NULL,                       /* m_slots */
   2423     NULL,                       /* m_traverse */
   2424     NULL,                       /* m_clear */
   2425     (freefunc)module_free       /* m_free */
   2426 };
   2427 
   2428 
   2429 PyMODINIT_FUNC
   2430 PyInit__asyncio(void)
   2431 {
   2432     if (module_init() < 0) {
   2433         return NULL;
   2434     }
   2435     if (PyType_Ready(&FutureType) < 0) {
   2436         return NULL;
   2437     }
   2438     if (PyType_Ready(&FutureIterType) < 0) {
   2439         return NULL;
   2440     }
   2441     if (PyType_Ready(&TaskSendMethWrapper_Type) < 0) {
   2442         return NULL;
   2443     }
   2444     if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
   2445         return NULL;
   2446     }
   2447     if (PyType_Ready(&TaskType) < 0) {
   2448         return NULL;
   2449     }
   2450 
   2451     PyObject *m = PyModule_Create(&_asynciomodule);
   2452     if (m == NULL) {
   2453         return NULL;
   2454     }
   2455 
   2456     Py_INCREF(&FutureType);
   2457     if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) {
   2458         Py_DECREF(&FutureType);
   2459         return NULL;
   2460     }
   2461 
   2462     Py_INCREF(&TaskType);
   2463     if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) {
   2464         Py_DECREF(&TaskType);
   2465         return NULL;
   2466     }
   2467 
   2468     return m;
   2469 }
   2470