• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "Python.h"
2 #include "pycore_pyerrors.h"      // _PyErr_ClearExcState()
3 #include <stddef.h>               // offsetof()
4 
5 
6 /*[clinic input]
7 module _asyncio
8 [clinic start generated code]*/
9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/
10 
11 
12 /* identifiers used from some functions */
13 _Py_IDENTIFIER(__asyncio_running_event_loop__);
14 _Py_IDENTIFIER(_asyncio_future_blocking);
15 _Py_IDENTIFIER(add_done_callback);
16 _Py_IDENTIFIER(call_soon);
17 _Py_IDENTIFIER(cancel);
18 _Py_IDENTIFIER(get_event_loop);
19 _Py_IDENTIFIER(throw);
20 
21 
22 /* State of the _asyncio module */
23 static PyObject *asyncio_mod;
24 static PyObject *traceback_extract_stack;
25 static PyObject *asyncio_get_event_loop_policy;
26 static PyObject *asyncio_future_repr_info_func;
27 static PyObject *asyncio_iscoroutine_func;
28 static PyObject *asyncio_task_get_stack_func;
29 static PyObject *asyncio_task_print_stack_func;
30 static PyObject *asyncio_task_repr_info_func;
31 static PyObject *asyncio_InvalidStateError;
32 static PyObject *asyncio_CancelledError;
33 static PyObject *context_kwname;
34 static int module_initialized;
35 
36 static PyObject *cached_running_holder;
37 static volatile uint64_t cached_running_holder_tsid;
38 
39 /* Counter for autogenerated Task names */
40 static uint64_t task_name_counter = 0;
41 
42 /* WeakSet containing all alive tasks. */
43 static PyObject *all_tasks;
44 
45 /* Dictionary containing tasks that are currently active in
46    all running event loops.  {EventLoop: Task} */
47 static PyObject *current_tasks;
48 
49 /* An isinstance type cache for the 'is_coroutine()' function. */
50 static PyObject *iscoroutine_typecache;
51 
52 
53 typedef enum {
54     STATE_PENDING,
55     STATE_CANCELLED,
56     STATE_FINISHED
57 } fut_state;
58 
59 #define FutureObj_HEAD(prefix)                                              \
60     PyObject_HEAD                                                           \
61     PyObject *prefix##_loop;                                                \
62     PyObject *prefix##_callback0;                                           \
63     PyObject *prefix##_context0;                                            \
64     PyObject *prefix##_callbacks;                                           \
65     PyObject *prefix##_exception;                                           \
66     PyObject *prefix##_result;                                              \
67     PyObject *prefix##_source_tb;                                           \
68     PyObject *prefix##_cancel_msg;                                          \
69     fut_state prefix##_state;                                               \
70     int prefix##_log_tb;                                                    \
71     int prefix##_blocking;                                                  \
72     PyObject *dict;                                                         \
73     PyObject *prefix##_weakreflist;                                         \
74     _PyErr_StackItem prefix##_cancelled_exc_state;
75 
76 typedef struct {
77     FutureObj_HEAD(fut)
78 } FutureObj;
79 
80 typedef struct {
81     FutureObj_HEAD(task)
82     PyObject *task_fut_waiter;
83     PyObject *task_coro;
84     PyObject *task_name;
85     PyObject *task_context;
86     int task_must_cancel;
87     int task_log_destroy_pending;
88 } TaskObj;
89 
90 typedef struct {
91     PyObject_HEAD
92     TaskObj *sw_task;
93     PyObject *sw_arg;
94 } TaskStepMethWrapper;
95 
96 typedef struct {
97     PyObject_HEAD
98     PyObject *rl_loop;
99 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
100     pid_t rl_pid;
101 #endif
102 } PyRunningLoopHolder;
103 
104 
105 static PyTypeObject FutureType;
106 static PyTypeObject TaskType;
107 static PyTypeObject PyRunningLoopHolder_Type;
108 
109 
110 #define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType)
111 #define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType)
112 
113 #define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType)
114 #define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType)
115 
116 #include "clinic/_asynciomodule.c.h"
117 
118 
119 /*[clinic input]
120 class _asyncio.Future "FutureObj *" "&Future_Type"
121 [clinic start generated code]*/
122 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/
123 
124 
125 /* Get FutureIter from Future */
126 static PyObject * future_new_iter(PyObject *);
127 
128 static PyRunningLoopHolder * new_running_loop_holder(PyObject *);
129 
130 
131 static int
_is_coroutine(PyObject * coro)132 _is_coroutine(PyObject *coro)
133 {
134     /* 'coro' is not a native coroutine, call asyncio.iscoroutine()
135        to check if it's another coroutine flavour.
136 
137        Do this check after 'future_init()'; in case we need to raise
138        an error, __del__ needs a properly initialized object.
139     */
140     PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro);
141     if (res == NULL) {
142         return -1;
143     }
144 
145     int is_res_true = PyObject_IsTrue(res);
146     Py_DECREF(res);
147     if (is_res_true <= 0) {
148         return is_res_true;
149     }
150 
151     if (PySet_GET_SIZE(iscoroutine_typecache) < 100) {
152         /* Just in case we don't want to cache more than 100
153            positive types.  That shouldn't ever happen, unless
154            someone stressing the system on purpose.
155         */
156         if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) {
157             return -1;
158         }
159     }
160 
161     return 1;
162 }
163 
164 
165 static inline int
is_coroutine(PyObject * coro)166 is_coroutine(PyObject *coro)
167 {
168     if (PyCoro_CheckExact(coro)) {
169         return 1;
170     }
171 
172     /* Check if `type(coro)` is in the cache.
173        Caching makes is_coroutine() function almost as fast as
174        PyCoro_CheckExact() for non-native coroutine-like objects
175        (like coroutines compiled with Cython).
176 
177        asyncio.iscoroutine() has its own type caching mechanism.
178        This cache allows us to avoid the cost of even calling
179        a pure-Python function in 99.9% cases.
180     */
181     int has_it = PySet_Contains(
182         iscoroutine_typecache, (PyObject*) Py_TYPE(coro));
183     if (has_it == 0) {
184         /* type(coro) is not in iscoroutine_typecache */
185         return _is_coroutine(coro);
186     }
187 
188     /* either an error has occurred or
189        type(coro) is in iscoroutine_typecache
190     */
191     return has_it;
192 }
193 
194 
195 static PyObject *
get_future_loop(PyObject * fut)196 get_future_loop(PyObject *fut)
197 {
198     /* Implementation of `asyncio.futures._get_loop` */
199 
200     _Py_IDENTIFIER(get_loop);
201     _Py_IDENTIFIER(_loop);
202     PyObject *getloop;
203 
204     if (Future_CheckExact(fut) || Task_CheckExact(fut)) {
205         PyObject *loop = ((FutureObj *)fut)->fut_loop;
206         Py_INCREF(loop);
207         return loop;
208     }
209 
210     if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) {
211         return NULL;
212     }
213     if (getloop != NULL) {
214         PyObject *res = PyObject_CallNoArgs(getloop);
215         Py_DECREF(getloop);
216         return res;
217     }
218 
219     return _PyObject_GetAttrId(fut, &PyId__loop);
220 }
221 
222 
223 static int
get_running_loop(PyObject ** loop)224 get_running_loop(PyObject **loop)
225 {
226     PyObject *rl;
227 
228     PyThreadState *ts = PyThreadState_Get();
229     uint64_t ts_id = PyThreadState_GetID(ts);
230     if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) {
231         // Fast path, check the cache.
232         rl = cached_running_holder;  // borrowed
233     }
234     else {
235         PyObject *ts_dict = _PyThreadState_GetDict(ts);  // borrowed
236         if (ts_dict == NULL) {
237             goto not_found;
238         }
239 
240         rl = _PyDict_GetItemIdWithError(
241             ts_dict, &PyId___asyncio_running_event_loop__);  // borrowed
242         if (rl == NULL) {
243             if (PyErr_Occurred()) {
244                 goto error;
245             }
246             else {
247                 goto not_found;
248             }
249         }
250 
251         cached_running_holder = rl;  // borrowed
252         cached_running_holder_tsid = ts_id;
253     }
254 
255     assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type));
256     PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop;
257 
258     if (running_loop == Py_None) {
259         goto not_found;
260     }
261 
262 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
263     /* On Windows there is no getpid, but there is also no os.fork(),
264        so there is no need for this check.
265     */
266     if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) {
267         goto not_found;
268     }
269 #endif
270 
271     Py_INCREF(running_loop);
272     *loop = running_loop;
273     return 0;
274 
275 not_found:
276     *loop = NULL;
277     return 0;
278 
279 error:
280     *loop = NULL;
281     return -1;
282 }
283 
284 
285 static int
set_running_loop(PyObject * loop)286 set_running_loop(PyObject *loop)
287 {
288     PyObject *ts_dict = NULL;
289 
290     PyThreadState *tstate = PyThreadState_Get();
291     if (tstate != NULL) {
292         ts_dict = _PyThreadState_GetDict(tstate);  // borrowed
293     }
294 
295     if (ts_dict == NULL) {
296         PyErr_SetString(
297             PyExc_RuntimeError, "thread-local storage is not available");
298         return -1;
299     }
300 
301     PyRunningLoopHolder *rl = new_running_loop_holder(loop);
302     if (rl == NULL) {
303         return -1;
304     }
305 
306     if (_PyDict_SetItemId(
307             ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0)
308     {
309         Py_DECREF(rl);  // will cleanup loop & current_pid
310         return -1;
311     }
312     Py_DECREF(rl);
313 
314     cached_running_holder = (PyObject *)rl;
315     cached_running_holder_tsid = PyThreadState_GetID(tstate);
316 
317     return 0;
318 }
319 
320 
321 static PyObject *
get_event_loop(int stacklevel)322 get_event_loop(int stacklevel)
323 {
324     PyObject *loop;
325     PyObject *policy;
326 
327     if (get_running_loop(&loop)) {
328         return NULL;
329     }
330     if (loop != NULL) {
331         return loop;
332     }
333 
334     if (PyErr_WarnEx(PyExc_DeprecationWarning,
335                      "There is no current event loop",
336                      stacklevel))
337     {
338         return NULL;
339     }
340 
341     policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy);
342     if (policy == NULL) {
343         return NULL;
344     }
345 
346     loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop);
347     Py_DECREF(policy);
348     return loop;
349 }
350 
351 
352 static int
call_soon(PyObject * loop,PyObject * func,PyObject * arg,PyObject * ctx)353 call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx)
354 {
355     PyObject *handle;
356     PyObject *stack[3];
357     Py_ssize_t nargs;
358 
359     if (ctx == NULL) {
360         handle = _PyObject_CallMethodIdObjArgs(
361             loop, &PyId_call_soon, func, arg, NULL);
362     }
363     else {
364         /* Use FASTCALL to pass a keyword-only argument to call_soon */
365 
366         PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon);
367         if (callable == NULL) {
368             return -1;
369         }
370 
371         /* All refs in 'stack' are borrowed. */
372         nargs = 1;
373         stack[0] = func;
374         if (arg != NULL) {
375             stack[1] = arg;
376             nargs++;
377         }
378         stack[nargs] = (PyObject *)ctx;
379 
380         handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname);
381         Py_DECREF(callable);
382     }
383 
384     if (handle == NULL) {
385         return -1;
386     }
387     Py_DECREF(handle);
388     return 0;
389 }
390 
391 
392 static inline int
future_is_alive(FutureObj * fut)393 future_is_alive(FutureObj *fut)
394 {
395     return fut->fut_loop != NULL;
396 }
397 
398 
399 static inline int
future_ensure_alive(FutureObj * fut)400 future_ensure_alive(FutureObj *fut)
401 {
402     if (!future_is_alive(fut)) {
403         PyErr_SetString(PyExc_RuntimeError,
404                         "Future object is not initialized.");
405         return -1;
406     }
407     return 0;
408 }
409 
410 
411 #define ENSURE_FUTURE_ALIVE(fut)                                \
412     do {                                                        \
413         assert(Future_Check(fut) || Task_Check(fut));           \
414         if (future_ensure_alive((FutureObj*)fut)) {             \
415             return NULL;                                        \
416         }                                                       \
417     } while(0);
418 
419 
420 static int
future_schedule_callbacks(FutureObj * fut)421 future_schedule_callbacks(FutureObj *fut)
422 {
423     Py_ssize_t len;
424     Py_ssize_t i;
425 
426     if (fut->fut_callback0 != NULL) {
427         /* There's a 1st callback */
428 
429         int ret = call_soon(
430             fut->fut_loop, fut->fut_callback0,
431             (PyObject *)fut, fut->fut_context0);
432 
433         Py_CLEAR(fut->fut_callback0);
434         Py_CLEAR(fut->fut_context0);
435         if (ret) {
436             /* If an error occurs in pure-Python implementation,
437                all callbacks are cleared. */
438             Py_CLEAR(fut->fut_callbacks);
439             return ret;
440         }
441 
442         /* we called the first callback, now try calling
443            callbacks from the 'fut_callbacks' list. */
444     }
445 
446     if (fut->fut_callbacks == NULL) {
447         /* No more callbacks, return. */
448         return 0;
449     }
450 
451     len = PyList_GET_SIZE(fut->fut_callbacks);
452     if (len == 0) {
453         /* The list of callbacks was empty; clear it and return. */
454         Py_CLEAR(fut->fut_callbacks);
455         return 0;
456     }
457 
458     for (i = 0; i < len; i++) {
459         PyObject *cb_tup = PyList_GET_ITEM(fut->fut_callbacks, i);
460         PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0);
461         PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1);
462 
463         if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) {
464             /* If an error occurs in pure-Python implementation,
465                all callbacks are cleared. */
466             Py_CLEAR(fut->fut_callbacks);
467             return -1;
468         }
469     }
470 
471     Py_CLEAR(fut->fut_callbacks);
472     return 0;
473 }
474 
475 
476 static int
future_init(FutureObj * fut,PyObject * loop)477 future_init(FutureObj *fut, PyObject *loop)
478 {
479     PyObject *res;
480     int is_true;
481     _Py_IDENTIFIER(get_debug);
482 
483     // Same to FutureObj_clear() but not clearing fut->dict
484     Py_CLEAR(fut->fut_loop);
485     Py_CLEAR(fut->fut_callback0);
486     Py_CLEAR(fut->fut_context0);
487     Py_CLEAR(fut->fut_callbacks);
488     Py_CLEAR(fut->fut_result);
489     Py_CLEAR(fut->fut_exception);
490     Py_CLEAR(fut->fut_source_tb);
491     Py_CLEAR(fut->fut_cancel_msg);
492     _PyErr_ClearExcState(&fut->fut_cancelled_exc_state);
493 
494     fut->fut_state = STATE_PENDING;
495     fut->fut_log_tb = 0;
496     fut->fut_blocking = 0;
497 
498     if (loop == Py_None) {
499         loop = get_event_loop(1);
500         if (loop == NULL) {
501             return -1;
502         }
503     }
504     else {
505         Py_INCREF(loop);
506     }
507     fut->fut_loop = loop;
508 
509     res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug);
510     if (res == NULL) {
511         return -1;
512     }
513     is_true = PyObject_IsTrue(res);
514     Py_DECREF(res);
515     if (is_true < 0) {
516         return -1;
517     }
518     if (is_true && !_Py_IsFinalizing()) {
519         /* Only try to capture the traceback if the interpreter is not being
520            finalized.  The original motivation to add a `_Py_IsFinalizing()`
521            call was to prevent SIGSEGV when a Future is created in a __del__
522            method, which is called during the interpreter shutdown and the
523            traceback module is already unloaded.
524         */
525         fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack);
526         if (fut->fut_source_tb == NULL) {
527             return -1;
528         }
529     }
530 
531     return 0;
532 }
533 
534 static PyObject *
future_set_result(FutureObj * fut,PyObject * res)535 future_set_result(FutureObj *fut, PyObject *res)
536 {
537     if (future_ensure_alive(fut)) {
538         return NULL;
539     }
540 
541     if (fut->fut_state != STATE_PENDING) {
542         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
543         return NULL;
544     }
545 
546     assert(!fut->fut_result);
547     Py_INCREF(res);
548     fut->fut_result = res;
549     fut->fut_state = STATE_FINISHED;
550 
551     if (future_schedule_callbacks(fut) == -1) {
552         return NULL;
553     }
554     Py_RETURN_NONE;
555 }
556 
557 static PyObject *
future_set_exception(FutureObj * fut,PyObject * exc)558 future_set_exception(FutureObj *fut, PyObject *exc)
559 {
560     PyObject *exc_val = NULL;
561 
562     if (fut->fut_state != STATE_PENDING) {
563         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
564         return NULL;
565     }
566 
567     if (PyExceptionClass_Check(exc)) {
568         exc_val = PyObject_CallNoArgs(exc);
569         if (exc_val == NULL) {
570             return NULL;
571         }
572         if (fut->fut_state != STATE_PENDING) {
573             Py_DECREF(exc_val);
574             PyErr_SetString(asyncio_InvalidStateError, "invalid state");
575             return NULL;
576         }
577     }
578     else {
579         exc_val = exc;
580         Py_INCREF(exc_val);
581     }
582     if (!PyExceptionInstance_Check(exc_val)) {
583         Py_DECREF(exc_val);
584         PyErr_SetString(PyExc_TypeError, "invalid exception object");
585         return NULL;
586     }
587     if (Py_IS_TYPE(exc_val, (PyTypeObject *)PyExc_StopIteration)) {
588         Py_DECREF(exc_val);
589         PyErr_SetString(PyExc_TypeError,
590                         "StopIteration interacts badly with generators "
591                         "and cannot be raised into a Future");
592         return NULL;
593     }
594 
595     assert(!fut->fut_exception);
596     fut->fut_exception = exc_val;
597     fut->fut_state = STATE_FINISHED;
598 
599     if (future_schedule_callbacks(fut) == -1) {
600         return NULL;
601     }
602 
603     fut->fut_log_tb = 1;
604     Py_RETURN_NONE;
605 }
606 
607 static PyObject *
create_cancelled_error(PyObject * msg)608 create_cancelled_error(PyObject *msg)
609 {
610     PyObject *exc;
611     if (msg == NULL || msg == Py_None) {
612         exc = PyObject_CallNoArgs(asyncio_CancelledError);
613     } else {
614         exc = PyObject_CallOneArg(asyncio_CancelledError, msg);
615     }
616     return exc;
617 }
618 
619 static void
future_set_cancelled_error(FutureObj * fut)620 future_set_cancelled_error(FutureObj *fut)
621 {
622     PyObject *exc = create_cancelled_error(fut->fut_cancel_msg);
623     PyErr_SetObject(asyncio_CancelledError, exc);
624     Py_DECREF(exc);
625 
626     _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state);
627 }
628 
629 static int
future_get_result(FutureObj * fut,PyObject ** result)630 future_get_result(FutureObj *fut, PyObject **result)
631 {
632     if (fut->fut_state == STATE_CANCELLED) {
633         future_set_cancelled_error(fut);
634         return -1;
635     }
636 
637     if (fut->fut_state != STATE_FINISHED) {
638         PyErr_SetString(asyncio_InvalidStateError, "Result is not set.");
639         return -1;
640     }
641 
642     fut->fut_log_tb = 0;
643     if (fut->fut_exception != NULL) {
644         Py_INCREF(fut->fut_exception);
645         *result = fut->fut_exception;
646         return 1;
647     }
648 
649     Py_INCREF(fut->fut_result);
650     *result = fut->fut_result;
651     return 0;
652 }
653 
654 static PyObject *
future_add_done_callback(FutureObj * fut,PyObject * arg,PyObject * ctx)655 future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx)
656 {
657     if (!future_is_alive(fut)) {
658         PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
659         return NULL;
660     }
661 
662     if (fut->fut_state != STATE_PENDING) {
663         /* The future is done/cancelled, so schedule the callback
664            right away. */
665         if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) {
666             return NULL;
667         }
668     }
669     else {
670         /* The future is pending, add a callback.
671 
672            Callbacks in the future object are stored as follows:
673 
674               callback0 -- a pointer to the first callback
675               callbacks -- a list of 2nd, 3rd, ... callbacks
676 
677            Invariants:
678 
679             * callbacks != NULL:
680                 There are some callbacks in in the list.  Just
681                 add the new callback to it.
682 
683             * callbacks == NULL and callback0 == NULL:
684                 This is the first callback.  Set it to callback0.
685 
686             * callbacks == NULL and callback0 != NULL:
687                 This is a second callback.  Initialize callbacks
688                 with a new list and add the new callback to it.
689         */
690 
691         if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) {
692             Py_INCREF(arg);
693             fut->fut_callback0 = arg;
694             Py_INCREF(ctx);
695             fut->fut_context0 = ctx;
696         }
697         else {
698             PyObject *tup = PyTuple_New(2);
699             if (tup == NULL) {
700                 return NULL;
701             }
702             Py_INCREF(arg);
703             PyTuple_SET_ITEM(tup, 0, arg);
704             Py_INCREF(ctx);
705             PyTuple_SET_ITEM(tup, 1, (PyObject *)ctx);
706 
707             if (fut->fut_callbacks != NULL) {
708                 int err = PyList_Append(fut->fut_callbacks, tup);
709                 if (err) {
710                     Py_DECREF(tup);
711                     return NULL;
712                 }
713                 Py_DECREF(tup);
714             }
715             else {
716                 fut->fut_callbacks = PyList_New(1);
717                 if (fut->fut_callbacks == NULL) {
718                     Py_DECREF(tup);
719                     return NULL;
720                 }
721 
722                 PyList_SET_ITEM(fut->fut_callbacks, 0, tup);  /* borrow */
723             }
724         }
725     }
726 
727     Py_RETURN_NONE;
728 }
729 
730 static PyObject *
future_cancel(FutureObj * fut,PyObject * msg)731 future_cancel(FutureObj *fut, PyObject *msg)
732 {
733     fut->fut_log_tb = 0;
734 
735     if (fut->fut_state != STATE_PENDING) {
736         Py_RETURN_FALSE;
737     }
738     fut->fut_state = STATE_CANCELLED;
739 
740     Py_XINCREF(msg);
741     Py_XSETREF(fut->fut_cancel_msg, msg);
742 
743     if (future_schedule_callbacks(fut) == -1) {
744         return NULL;
745     }
746 
747     Py_RETURN_TRUE;
748 }
749 
750 /*[clinic input]
751 _asyncio.Future.__init__
752 
753     *
754     loop: object = None
755 
756 This class is *almost* compatible with concurrent.futures.Future.
757 
758     Differences:
759 
760     - result() and exception() do not take a timeout argument and
761       raise an exception when the future isn't done yet.
762 
763     - Callbacks registered with add_done_callback() are always called
764       via the event loop's call_soon_threadsafe().
765 
766     - This class is not compatible with the wait() and as_completed()
767       methods in the concurrent.futures package.
768 [clinic start generated code]*/
769 
770 static int
_asyncio_Future___init___impl(FutureObj * self,PyObject * loop)771 _asyncio_Future___init___impl(FutureObj *self, PyObject *loop)
772 /*[clinic end generated code: output=9ed75799eaccb5d6 input=89af317082bc0bf8]*/
773 
774 {
775     return future_init(self, loop);
776 }
777 
778 static int
FutureObj_clear(FutureObj * fut)779 FutureObj_clear(FutureObj *fut)
780 {
781     Py_CLEAR(fut->fut_loop);
782     Py_CLEAR(fut->fut_callback0);
783     Py_CLEAR(fut->fut_context0);
784     Py_CLEAR(fut->fut_callbacks);
785     Py_CLEAR(fut->fut_result);
786     Py_CLEAR(fut->fut_exception);
787     Py_CLEAR(fut->fut_source_tb);
788     Py_CLEAR(fut->fut_cancel_msg);
789     _PyErr_ClearExcState(&fut->fut_cancelled_exc_state);
790     Py_CLEAR(fut->dict);
791     return 0;
792 }
793 
794 static int
FutureObj_traverse(FutureObj * fut,visitproc visit,void * arg)795 FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg)
796 {
797     Py_VISIT(fut->fut_loop);
798     Py_VISIT(fut->fut_callback0);
799     Py_VISIT(fut->fut_context0);
800     Py_VISIT(fut->fut_callbacks);
801     Py_VISIT(fut->fut_result);
802     Py_VISIT(fut->fut_exception);
803     Py_VISIT(fut->fut_source_tb);
804     Py_VISIT(fut->fut_cancel_msg);
805     Py_VISIT(fut->dict);
806 
807     _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state;
808     Py_VISIT(exc_state->exc_type);
809     Py_VISIT(exc_state->exc_value);
810     Py_VISIT(exc_state->exc_traceback);
811 
812     return 0;
813 }
814 
815 /*[clinic input]
816 _asyncio.Future.result
817 
818 Return the result this future represents.
819 
820 If the future has been cancelled, raises CancelledError.  If the
821 future's result isn't yet available, raises InvalidStateError.  If
822 the future is done and has an exception set, this exception is raised.
823 [clinic start generated code]*/
824 
825 static PyObject *
_asyncio_Future_result_impl(FutureObj * self)826 _asyncio_Future_result_impl(FutureObj *self)
827 /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/
828 {
829     PyObject *result;
830 
831     if (!future_is_alive(self)) {
832         PyErr_SetString(asyncio_InvalidStateError,
833                         "Future object is not initialized.");
834         return NULL;
835     }
836 
837     int res = future_get_result(self, &result);
838 
839     if (res == -1) {
840         return NULL;
841     }
842 
843     if (res == 0) {
844         return result;
845     }
846 
847     assert(res == 1);
848 
849     PyErr_SetObject(PyExceptionInstance_Class(result), result);
850     Py_DECREF(result);
851     return NULL;
852 }
853 
854 /*[clinic input]
855 _asyncio.Future.exception
856 
857 Return the exception that was set on this future.
858 
859 The exception (or None if no exception was set) is returned only if
860 the future is done.  If the future has been cancelled, raises
861 CancelledError.  If the future isn't done yet, raises
862 InvalidStateError.
863 [clinic start generated code]*/
864 
865 static PyObject *
_asyncio_Future_exception_impl(FutureObj * self)866 _asyncio_Future_exception_impl(FutureObj *self)
867 /*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/
868 {
869     if (!future_is_alive(self)) {
870         PyErr_SetString(asyncio_InvalidStateError,
871                         "Future object is not initialized.");
872         return NULL;
873     }
874 
875     if (self->fut_state == STATE_CANCELLED) {
876         future_set_cancelled_error(self);
877         return NULL;
878     }
879 
880     if (self->fut_state != STATE_FINISHED) {
881         PyErr_SetString(asyncio_InvalidStateError, "Exception is not set.");
882         return NULL;
883     }
884 
885     if (self->fut_exception != NULL) {
886         self->fut_log_tb = 0;
887         Py_INCREF(self->fut_exception);
888         return self->fut_exception;
889     }
890 
891     Py_RETURN_NONE;
892 }
893 
894 /*[clinic input]
895 _asyncio.Future.set_result
896 
897     result: object
898     /
899 
900 Mark the future done and set its result.
901 
902 If the future is already done when this method is called, raises
903 InvalidStateError.
904 [clinic start generated code]*/
905 
906 static PyObject *
_asyncio_Future_set_result(FutureObj * self,PyObject * result)907 _asyncio_Future_set_result(FutureObj *self, PyObject *result)
908 /*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/
909 {
910     ENSURE_FUTURE_ALIVE(self)
911     return future_set_result(self, result);
912 }
913 
914 /*[clinic input]
915 _asyncio.Future.set_exception
916 
917     exception: object
918     /
919 
920 Mark the future done and set an exception.
921 
922 If the future is already done when this method is called, raises
923 InvalidStateError.
924 [clinic start generated code]*/
925 
926 static PyObject *
_asyncio_Future_set_exception(FutureObj * self,PyObject * exception)927 _asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
928 /*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/
929 {
930     ENSURE_FUTURE_ALIVE(self)
931     return future_set_exception(self, exception);
932 }
933 
934 /*[clinic input]
935 _asyncio.Future.add_done_callback
936 
937     fn: object
938     /
939     *
940     context: object = NULL
941 
942 Add a callback to be run when the future becomes done.
943 
944 The callback is called with a single argument - the future object. If
945 the future is already done when this is called, the callback is
946 scheduled with call_soon.
947 [clinic start generated code]*/
948 
949 static PyObject *
_asyncio_Future_add_done_callback_impl(FutureObj * self,PyObject * fn,PyObject * context)950 _asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn,
951                                        PyObject *context)
952 /*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/
953 {
954     if (context == NULL) {
955         context = PyContext_CopyCurrent();
956         if (context == NULL) {
957             return NULL;
958         }
959         PyObject *res = future_add_done_callback(self, fn, context);
960         Py_DECREF(context);
961         return res;
962     }
963     return future_add_done_callback(self, fn, context);
964 }
965 
966 /*[clinic input]
967 _asyncio.Future.remove_done_callback
968 
969     fn: object
970     /
971 
972 Remove all instances of a callback from the "call when done" list.
973 
974 Returns the number of callbacks removed.
975 [clinic start generated code]*/
976 
977 static PyObject *
_asyncio_Future_remove_done_callback(FutureObj * self,PyObject * fn)978 _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
979 /*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/
980 {
981     PyObject *newlist;
982     Py_ssize_t len, i, j=0;
983     Py_ssize_t cleared_callback0 = 0;
984 
985     ENSURE_FUTURE_ALIVE(self)
986 
987     if (self->fut_callback0 != NULL) {
988         int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ);
989         if (cmp == -1) {
990             return NULL;
991         }
992         if (cmp == 1) {
993             /* callback0 == fn */
994             Py_CLEAR(self->fut_callback0);
995             Py_CLEAR(self->fut_context0);
996             cleared_callback0 = 1;
997         }
998     }
999 
1000     if (self->fut_callbacks == NULL) {
1001         return PyLong_FromSsize_t(cleared_callback0);
1002     }
1003 
1004     len = PyList_GET_SIZE(self->fut_callbacks);
1005     if (len == 0) {
1006         Py_CLEAR(self->fut_callbacks);
1007         return PyLong_FromSsize_t(cleared_callback0);
1008     }
1009 
1010     if (len == 1) {
1011         PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0);
1012         int cmp = PyObject_RichCompareBool(
1013             PyTuple_GET_ITEM(cb_tup, 0), fn, Py_EQ);
1014         if (cmp == -1) {
1015             return NULL;
1016         }
1017         if (cmp == 1) {
1018             /* callbacks[0] == fn */
1019             Py_CLEAR(self->fut_callbacks);
1020             return PyLong_FromSsize_t(1 + cleared_callback0);
1021         }
1022         /* callbacks[0] != fn and len(callbacks) == 1 */
1023         return PyLong_FromSsize_t(cleared_callback0);
1024     }
1025 
1026     newlist = PyList_New(len);
1027     if (newlist == NULL) {
1028         return NULL;
1029     }
1030 
1031     for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
1032         int ret;
1033         PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);
1034         Py_INCREF(item);
1035         ret = PyObject_RichCompareBool(PyTuple_GET_ITEM(item, 0), fn, Py_EQ);
1036         if (ret == 0) {
1037             if (j < len) {
1038                 PyList_SET_ITEM(newlist, j, item);
1039                 j++;
1040                 continue;
1041             }
1042             ret = PyList_Append(newlist, item);
1043         }
1044         Py_DECREF(item);
1045         if (ret < 0) {
1046             goto fail;
1047         }
1048     }
1049 
1050     if (j == 0) {
1051         Py_CLEAR(self->fut_callbacks);
1052         Py_DECREF(newlist);
1053         return PyLong_FromSsize_t(len + cleared_callback0);
1054     }
1055 
1056     if (j < len) {
1057         Py_SET_SIZE(newlist, j);
1058     }
1059     j = PyList_GET_SIZE(newlist);
1060     len = PyList_GET_SIZE(self->fut_callbacks);
1061     if (j != len) {
1062         if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) {
1063             goto fail;
1064         }
1065     }
1066     Py_DECREF(newlist);
1067     return PyLong_FromSsize_t(len - j + cleared_callback0);
1068 
1069 fail:
1070     Py_DECREF(newlist);
1071     return NULL;
1072 }
1073 
1074 /*[clinic input]
1075 _asyncio.Future.cancel
1076 
1077     msg: object = None
1078 
1079 Cancel the future and schedule callbacks.
1080 
1081 If the future is already done or cancelled, return False.  Otherwise,
1082 change the future's state to cancelled, schedule the callbacks and
1083 return True.
1084 [clinic start generated code]*/
1085 
1086 static PyObject *
_asyncio_Future_cancel_impl(FutureObj * self,PyObject * msg)1087 _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg)
1088 /*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/
1089 {
1090     ENSURE_FUTURE_ALIVE(self)
1091     return future_cancel(self, msg);
1092 }
1093 
1094 /*[clinic input]
1095 _asyncio.Future.cancelled
1096 
1097 Return True if the future was cancelled.
1098 [clinic start generated code]*/
1099 
1100 static PyObject *
_asyncio_Future_cancelled_impl(FutureObj * self)1101 _asyncio_Future_cancelled_impl(FutureObj *self)
1102 /*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/
1103 {
1104     if (future_is_alive(self) && self->fut_state == STATE_CANCELLED) {
1105         Py_RETURN_TRUE;
1106     }
1107     else {
1108         Py_RETURN_FALSE;
1109     }
1110 }
1111 
1112 /*[clinic input]
1113 _asyncio.Future.done
1114 
1115 Return True if the future is done.
1116 
1117 Done means either that a result / exception are available, or that the
1118 future was cancelled.
1119 [clinic start generated code]*/
1120 
1121 static PyObject *
_asyncio_Future_done_impl(FutureObj * self)1122 _asyncio_Future_done_impl(FutureObj *self)
1123 /*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/
1124 {
1125     if (!future_is_alive(self) || self->fut_state == STATE_PENDING) {
1126         Py_RETURN_FALSE;
1127     }
1128     else {
1129         Py_RETURN_TRUE;
1130     }
1131 }
1132 
1133 /*[clinic input]
1134 _asyncio.Future.get_loop
1135 
1136 Return the event loop the Future is bound to.
1137 [clinic start generated code]*/
1138 
1139 static PyObject *
_asyncio_Future_get_loop_impl(FutureObj * self)1140 _asyncio_Future_get_loop_impl(FutureObj *self)
1141 /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/
1142 {
1143     ENSURE_FUTURE_ALIVE(self)
1144     Py_INCREF(self->fut_loop);
1145     return self->fut_loop;
1146 }
1147 
1148 static PyObject *
FutureObj_get_blocking(FutureObj * fut,void * Py_UNUSED (ignored))1149 FutureObj_get_blocking(FutureObj *fut, void *Py_UNUSED(ignored))
1150 {
1151     if (future_is_alive(fut) && fut->fut_blocking) {
1152         Py_RETURN_TRUE;
1153     }
1154     else {
1155         Py_RETURN_FALSE;
1156     }
1157 }
1158 
1159 static int
FutureObj_set_blocking(FutureObj * fut,PyObject * val,void * Py_UNUSED (ignored))1160 FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
1161 {
1162     if (future_ensure_alive(fut)) {
1163         return -1;
1164     }
1165     if (val == NULL) {
1166         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1167         return -1;
1168     }
1169 
1170     int is_true = PyObject_IsTrue(val);
1171     if (is_true < 0) {
1172         return -1;
1173     }
1174     fut->fut_blocking = is_true;
1175     return 0;
1176 }
1177 
1178 static PyObject *
FutureObj_get_log_traceback(FutureObj * fut,void * Py_UNUSED (ignored))1179 FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
1180 {
1181     ENSURE_FUTURE_ALIVE(fut)
1182     if (fut->fut_log_tb) {
1183         Py_RETURN_TRUE;
1184     }
1185     else {
1186         Py_RETURN_FALSE;
1187     }
1188 }
1189 
1190 static int
FutureObj_set_log_traceback(FutureObj * fut,PyObject * val,void * Py_UNUSED (ignored))1191 FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
1192 {
1193     if (val == NULL) {
1194         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1195         return -1;
1196     }
1197     int is_true = PyObject_IsTrue(val);
1198     if (is_true < 0) {
1199         return -1;
1200     }
1201     if (is_true) {
1202         PyErr_SetString(PyExc_ValueError,
1203                         "_log_traceback can only be set to False");
1204         return -1;
1205     }
1206     fut->fut_log_tb = is_true;
1207     return 0;
1208 }
1209 
1210 static PyObject *
FutureObj_get_loop(FutureObj * fut,void * Py_UNUSED (ignored))1211 FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored))
1212 {
1213     if (!future_is_alive(fut)) {
1214         Py_RETURN_NONE;
1215     }
1216     Py_INCREF(fut->fut_loop);
1217     return fut->fut_loop;
1218 }
1219 
1220 static PyObject *
FutureObj_get_callbacks(FutureObj * fut,void * Py_UNUSED (ignored))1221 FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored))
1222 {
1223     Py_ssize_t i;
1224 
1225     ENSURE_FUTURE_ALIVE(fut)
1226 
1227     if (fut->fut_callback0 == NULL) {
1228         if (fut->fut_callbacks == NULL) {
1229             Py_RETURN_NONE;
1230         }
1231 
1232         Py_INCREF(fut->fut_callbacks);
1233         return fut->fut_callbacks;
1234     }
1235 
1236     Py_ssize_t len = 1;
1237     if (fut->fut_callbacks != NULL) {
1238         len += PyList_GET_SIZE(fut->fut_callbacks);
1239     }
1240 
1241 
1242     PyObject *new_list = PyList_New(len);
1243     if (new_list == NULL) {
1244         return NULL;
1245     }
1246 
1247     PyObject *tup0 = PyTuple_New(2);
1248     if (tup0 == NULL) {
1249         Py_DECREF(new_list);
1250         return NULL;
1251     }
1252 
1253     Py_INCREF(fut->fut_callback0);
1254     PyTuple_SET_ITEM(tup0, 0, fut->fut_callback0);
1255     assert(fut->fut_context0 != NULL);
1256     Py_INCREF(fut->fut_context0);
1257     PyTuple_SET_ITEM(tup0, 1, (PyObject *)fut->fut_context0);
1258 
1259     PyList_SET_ITEM(new_list, 0, tup0);
1260 
1261     if (fut->fut_callbacks != NULL) {
1262         for (i = 0; i < PyList_GET_SIZE(fut->fut_callbacks); i++) {
1263             PyObject *cb = PyList_GET_ITEM(fut->fut_callbacks, i);
1264             Py_INCREF(cb);
1265             PyList_SET_ITEM(new_list, i + 1, cb);
1266         }
1267     }
1268 
1269     return new_list;
1270 }
1271 
1272 static PyObject *
FutureObj_get_result(FutureObj * fut,void * Py_UNUSED (ignored))1273 FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored))
1274 {
1275     ENSURE_FUTURE_ALIVE(fut)
1276     if (fut->fut_result == NULL) {
1277         Py_RETURN_NONE;
1278     }
1279     Py_INCREF(fut->fut_result);
1280     return fut->fut_result;
1281 }
1282 
1283 static PyObject *
FutureObj_get_exception(FutureObj * fut,void * Py_UNUSED (ignored))1284 FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored))
1285 {
1286     ENSURE_FUTURE_ALIVE(fut)
1287     if (fut->fut_exception == NULL) {
1288         Py_RETURN_NONE;
1289     }
1290     Py_INCREF(fut->fut_exception);
1291     return fut->fut_exception;
1292 }
1293 
1294 static PyObject *
FutureObj_get_source_traceback(FutureObj * fut,void * Py_UNUSED (ignored))1295 FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
1296 {
1297     if (!future_is_alive(fut) || fut->fut_source_tb == NULL) {
1298         Py_RETURN_NONE;
1299     }
1300     Py_INCREF(fut->fut_source_tb);
1301     return fut->fut_source_tb;
1302 }
1303 
1304 static PyObject *
FutureObj_get_cancel_message(FutureObj * fut,void * Py_UNUSED (ignored))1305 FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored))
1306 {
1307     if (fut->fut_cancel_msg == NULL) {
1308         Py_RETURN_NONE;
1309     }
1310     Py_INCREF(fut->fut_cancel_msg);
1311     return fut->fut_cancel_msg;
1312 }
1313 
1314 static int
FutureObj_set_cancel_message(FutureObj * fut,PyObject * msg,void * Py_UNUSED (ignored))1315 FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg,
1316                              void *Py_UNUSED(ignored))
1317 {
1318     if (msg == NULL) {
1319         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1320         return -1;
1321     }
1322     Py_INCREF(msg);
1323     Py_XSETREF(fut->fut_cancel_msg, msg);
1324     return 0;
1325 }
1326 
1327 static PyObject *
FutureObj_get_state(FutureObj * fut,void * Py_UNUSED (ignored))1328 FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored))
1329 {
1330     _Py_IDENTIFIER(PENDING);
1331     _Py_IDENTIFIER(CANCELLED);
1332     _Py_IDENTIFIER(FINISHED);
1333     PyObject *ret = NULL;
1334 
1335     ENSURE_FUTURE_ALIVE(fut)
1336 
1337     switch (fut->fut_state) {
1338     case STATE_PENDING:
1339         ret = _PyUnicode_FromId(&PyId_PENDING);
1340         break;
1341     case STATE_CANCELLED:
1342         ret = _PyUnicode_FromId(&PyId_CANCELLED);
1343         break;
1344     case STATE_FINISHED:
1345         ret = _PyUnicode_FromId(&PyId_FINISHED);
1346         break;
1347     default:
1348         assert (0);
1349     }
1350     Py_XINCREF(ret);
1351     return ret;
1352 }
1353 
1354 /*[clinic input]
1355 _asyncio.Future._make_cancelled_error
1356 
1357 Create the CancelledError to raise if the Future is cancelled.
1358 
1359 This should only be called once when handling a cancellation since
1360 it erases the context exception value.
1361 [clinic start generated code]*/
1362 
1363 static PyObject *
_asyncio_Future__make_cancelled_error_impl(FutureObj * self)1364 _asyncio_Future__make_cancelled_error_impl(FutureObj *self)
1365 /*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/
1366 {
1367     PyObject *exc = create_cancelled_error(self->fut_cancel_msg);
1368     _PyErr_StackItem *exc_state = &self->fut_cancelled_exc_state;
1369     /* Transfer ownership of exc_value from exc_state to exc since we are
1370        done with it. */
1371     PyException_SetContext(exc, exc_state->exc_value);
1372     exc_state->exc_value = NULL;
1373 
1374     return exc;
1375 }
1376 
1377 /*[clinic input]
1378 _asyncio.Future._repr_info
1379 [clinic start generated code]*/
1380 
1381 static PyObject *
_asyncio_Future__repr_info_impl(FutureObj * self)1382 _asyncio_Future__repr_info_impl(FutureObj *self)
1383 /*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/
1384 {
1385     return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self);
1386 }
1387 
1388 static PyObject *
FutureObj_repr(FutureObj * fut)1389 FutureObj_repr(FutureObj *fut)
1390 {
1391     _Py_IDENTIFIER(_repr_info);
1392 
1393     ENSURE_FUTURE_ALIVE(fut)
1394 
1395     PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut,
1396                                                    &PyId__repr_info);
1397     if (rinfo == NULL) {
1398         return NULL;
1399     }
1400 
1401     PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo);
1402     Py_DECREF(rinfo);
1403     if (rinfo_s == NULL) {
1404         return NULL;
1405     }
1406 
1407     PyObject *rstr = PyUnicode_FromFormat("<%s %U>",
1408                                           _PyType_Name(Py_TYPE(fut)), rinfo_s);
1409     Py_DECREF(rinfo_s);
1410     return rstr;
1411 }
1412 
1413 static void
FutureObj_finalize(FutureObj * fut)1414 FutureObj_finalize(FutureObj *fut)
1415 {
1416     _Py_IDENTIFIER(call_exception_handler);
1417     _Py_IDENTIFIER(message);
1418     _Py_IDENTIFIER(exception);
1419     _Py_IDENTIFIER(future);
1420     _Py_IDENTIFIER(source_traceback);
1421 
1422     PyObject *error_type, *error_value, *error_traceback;
1423     PyObject *context;
1424     PyObject *message = NULL;
1425     PyObject *func;
1426 
1427     if (!fut->fut_log_tb) {
1428         return;
1429     }
1430     assert(fut->fut_exception != NULL);
1431     fut->fut_log_tb = 0;
1432 
1433     /* Save the current exception, if any. */
1434     PyErr_Fetch(&error_type, &error_value, &error_traceback);
1435 
1436     context = PyDict_New();
1437     if (context == NULL) {
1438         goto finally;
1439     }
1440 
1441     message = PyUnicode_FromFormat(
1442         "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut)));
1443     if (message == NULL) {
1444         goto finally;
1445     }
1446 
1447     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
1448         _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 ||
1449         _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) {
1450         goto finally;
1451     }
1452     if (fut->fut_source_tb != NULL) {
1453         if (_PyDict_SetItemId(context, &PyId_source_traceback,
1454                               fut->fut_source_tb) < 0) {
1455             goto finally;
1456         }
1457     }
1458 
1459     func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler);
1460     if (func != NULL) {
1461         PyObject *res = PyObject_CallOneArg(func, context);
1462         if (res == NULL) {
1463             PyErr_WriteUnraisable(func);
1464         }
1465         else {
1466             Py_DECREF(res);
1467         }
1468         Py_DECREF(func);
1469     }
1470 
1471 finally:
1472     Py_XDECREF(context);
1473     Py_XDECREF(message);
1474 
1475     /* Restore the saved exception. */
1476     PyErr_Restore(error_type, error_value, error_traceback);
1477 }
1478 
1479 static PyAsyncMethods FutureType_as_async = {
1480     (unaryfunc)future_new_iter,         /* am_await */
1481     0,                                  /* am_aiter */
1482     0,                                  /* am_anext */
1483     0,                                  /* am_send  */
1484 };
1485 
1486 static PyMethodDef FutureType_methods[] = {
1487     _ASYNCIO_FUTURE_RESULT_METHODDEF
1488     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
1489     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
1490     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
1491     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
1492     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
1493     _ASYNCIO_FUTURE_CANCEL_METHODDEF
1494     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
1495     _ASYNCIO_FUTURE_DONE_METHODDEF
1496     _ASYNCIO_FUTURE_GET_LOOP_METHODDEF
1497     _ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF
1498     _ASYNCIO_FUTURE__REPR_INFO_METHODDEF
1499     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
1500     {NULL, NULL}        /* Sentinel */
1501 };
1502 
1503 #define FUTURE_COMMON_GETSETLIST                                              \
1504     {"_state", (getter)FutureObj_get_state, NULL, NULL},                      \
1505     {"_asyncio_future_blocking", (getter)FutureObj_get_blocking,              \
1506                                  (setter)FutureObj_set_blocking, NULL},       \
1507     {"_loop", (getter)FutureObj_get_loop, NULL, NULL},                        \
1508     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \
1509     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \
1510     {"_exception", (getter)FutureObj_get_exception, NULL, NULL},              \
1511     {"_log_traceback", (getter)FutureObj_get_log_traceback,                   \
1512                        (setter)FutureObj_set_log_traceback, NULL},            \
1513     {"_source_traceback", (getter)FutureObj_get_source_traceback,             \
1514                           NULL, NULL},                                        \
1515     {"_cancel_message", (getter)FutureObj_get_cancel_message,                 \
1516                         (setter)FutureObj_set_cancel_message, NULL},
1517 
1518 static PyGetSetDef FutureType_getsetlist[] = {
1519     FUTURE_COMMON_GETSETLIST
1520     {NULL} /* Sentinel */
1521 };
1522 
1523 static void FutureObj_dealloc(PyObject *self);
1524 
1525 static PyTypeObject FutureType = {
1526     PyVarObject_HEAD_INIT(NULL, 0)
1527     "_asyncio.Future",
1528     sizeof(FutureObj),                       /* tp_basicsize */
1529     .tp_dealloc = FutureObj_dealloc,
1530     .tp_as_async = &FutureType_as_async,
1531     .tp_repr = (reprfunc)FutureObj_repr,
1532     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
1533     .tp_doc = _asyncio_Future___init____doc__,
1534     .tp_traverse = (traverseproc)FutureObj_traverse,
1535     .tp_clear = (inquiry)FutureObj_clear,
1536     .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist),
1537     .tp_iter = (getiterfunc)future_new_iter,
1538     .tp_methods = FutureType_methods,
1539     .tp_getset = FutureType_getsetlist,
1540     .tp_dictoffset = offsetof(FutureObj, dict),
1541     .tp_init = (initproc)_asyncio_Future___init__,
1542     .tp_new = PyType_GenericNew,
1543     .tp_finalize = (destructor)FutureObj_finalize,
1544 };
1545 
1546 static void
FutureObj_dealloc(PyObject * self)1547 FutureObj_dealloc(PyObject *self)
1548 {
1549     FutureObj *fut = (FutureObj *)self;
1550 
1551     if (Future_CheckExact(fut)) {
1552         /* When fut is subclass of Future, finalizer is called from
1553          * subtype_dealloc.
1554          */
1555         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
1556             // resurrected.
1557             return;
1558         }
1559     }
1560 
1561     PyObject_GC_UnTrack(self);
1562 
1563     if (fut->fut_weakreflist != NULL) {
1564         PyObject_ClearWeakRefs(self);
1565     }
1566 
1567     (void)FutureObj_clear(fut);
1568     Py_TYPE(fut)->tp_free(fut);
1569 }
1570 
1571 
1572 /*********************** Future Iterator **************************/
1573 
1574 typedef struct {
1575     PyObject_HEAD
1576     FutureObj *future;
1577 } futureiterobject;
1578 
1579 
1580 #define FI_FREELIST_MAXLEN 255
1581 static futureiterobject *fi_freelist = NULL;
1582 static Py_ssize_t fi_freelist_len = 0;
1583 
1584 
1585 static void
FutureIter_dealloc(futureiterobject * it)1586 FutureIter_dealloc(futureiterobject *it)
1587 {
1588     PyObject_GC_UnTrack(it);
1589     Py_CLEAR(it->future);
1590 
1591     if (fi_freelist_len < FI_FREELIST_MAXLEN) {
1592         fi_freelist_len++;
1593         it->future = (FutureObj*) fi_freelist;
1594         fi_freelist = it;
1595     }
1596     else {
1597         PyObject_GC_Del(it);
1598     }
1599 }
1600 
1601 static PySendResult
FutureIter_am_send(futureiterobject * it,PyObject * Py_UNUSED (arg),PyObject ** result)1602 FutureIter_am_send(futureiterobject *it,
1603                    PyObject *Py_UNUSED(arg),
1604                    PyObject **result)
1605 {
1606     /* arg is unused, see the comment on FutureIter_send for clarification */
1607 
1608     PyObject *res;
1609     FutureObj *fut = it->future;
1610 
1611     *result = NULL;
1612     if (fut == NULL) {
1613         return PYGEN_ERROR;
1614     }
1615 
1616     if (fut->fut_state == STATE_PENDING) {
1617         if (!fut->fut_blocking) {
1618             fut->fut_blocking = 1;
1619             Py_INCREF(fut);
1620             *result = (PyObject *)fut;
1621             return PYGEN_NEXT;
1622         }
1623         PyErr_SetString(PyExc_RuntimeError,
1624                         "await wasn't used with future");
1625         return PYGEN_ERROR;
1626     }
1627 
1628     it->future = NULL;
1629     res = _asyncio_Future_result_impl(fut);
1630     if (res != NULL) {
1631         Py_DECREF(fut);
1632         *result = res;
1633         return PYGEN_RETURN;
1634     }
1635 
1636     Py_DECREF(fut);
1637     return PYGEN_ERROR;
1638 }
1639 
1640 static PyObject *
FutureIter_iternext(futureiterobject * it)1641 FutureIter_iternext(futureiterobject *it)
1642 {
1643     PyObject *result;
1644     switch (FutureIter_am_send(it, Py_None, &result)) {
1645         case PYGEN_RETURN:
1646             (void)_PyGen_SetStopIterationValue(result);
1647             Py_DECREF(result);
1648             return NULL;
1649         case PYGEN_NEXT:
1650             return result;
1651         case PYGEN_ERROR:
1652             return NULL;
1653         default:
1654             Py_UNREACHABLE();
1655     }
1656 }
1657 
1658 static PyObject *
FutureIter_send(futureiterobject * self,PyObject * unused)1659 FutureIter_send(futureiterobject *self, PyObject *unused)
1660 {
1661     /* Future.__iter__ doesn't care about values that are pushed to the
1662      * generator, it just returns self.result().
1663      */
1664     return FutureIter_iternext(self);
1665 }
1666 
1667 static PyObject *
FutureIter_throw(futureiterobject * self,PyObject * args)1668 FutureIter_throw(futureiterobject *self, PyObject *args)
1669 {
1670     PyObject *type, *val = NULL, *tb = NULL;
1671     if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb))
1672         return NULL;
1673 
1674     if (val == Py_None) {
1675         val = NULL;
1676     }
1677     if (tb == Py_None) {
1678         tb = NULL;
1679     } else if (tb != NULL && !PyTraceBack_Check(tb)) {
1680         PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback");
1681         return NULL;
1682     }
1683 
1684     Py_INCREF(type);
1685     Py_XINCREF(val);
1686     Py_XINCREF(tb);
1687 
1688     if (PyExceptionClass_Check(type)) {
1689         PyErr_NormalizeException(&type, &val, &tb);
1690         /* No need to call PyException_SetTraceback since we'll be calling
1691            PyErr_Restore for `type`, `val`, and `tb`. */
1692     } else if (PyExceptionInstance_Check(type)) {
1693         if (val) {
1694             PyErr_SetString(PyExc_TypeError,
1695                             "instance exception may not have a separate value");
1696             goto fail;
1697         }
1698         val = type;
1699         type = PyExceptionInstance_Class(type);
1700         Py_INCREF(type);
1701         if (tb == NULL)
1702             tb = PyException_GetTraceback(val);
1703     } else {
1704         PyErr_SetString(PyExc_TypeError,
1705                         "exceptions must be classes deriving BaseException or "
1706                         "instances of such a class");
1707         goto fail;
1708     }
1709 
1710     Py_CLEAR(self->future);
1711 
1712     PyErr_Restore(type, val, tb);
1713 
1714     return NULL;
1715 
1716   fail:
1717     Py_DECREF(type);
1718     Py_XDECREF(val);
1719     Py_XDECREF(tb);
1720     return NULL;
1721 }
1722 
1723 static PyObject *
FutureIter_close(futureiterobject * self,PyObject * arg)1724 FutureIter_close(futureiterobject *self, PyObject *arg)
1725 {
1726     Py_CLEAR(self->future);
1727     Py_RETURN_NONE;
1728 }
1729 
1730 static int
FutureIter_traverse(futureiterobject * it,visitproc visit,void * arg)1731 FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg)
1732 {
1733     Py_VISIT(it->future);
1734     return 0;
1735 }
1736 
1737 static PyMethodDef FutureIter_methods[] = {
1738     {"send",  (PyCFunction)FutureIter_send, METH_O, NULL},
1739     {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL},
1740     {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL},
1741     {NULL, NULL}        /* Sentinel */
1742 };
1743 
1744 static PyAsyncMethods FutureIterType_as_async = {
1745     0,                                  /* am_await */
1746     0,                                  /* am_aiter */
1747     0,                                  /* am_anext */
1748     (sendfunc)FutureIter_am_send,       /* am_send  */
1749 };
1750 
1751 
1752 static PyTypeObject FutureIterType = {
1753     PyVarObject_HEAD_INIT(NULL, 0)
1754     "_asyncio.FutureIter",
1755     .tp_basicsize = sizeof(futureiterobject),
1756     .tp_itemsize = 0,
1757     .tp_dealloc = (destructor)FutureIter_dealloc,
1758     .tp_as_async = &FutureIterType_as_async,
1759     .tp_getattro = PyObject_GenericGetAttr,
1760     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1761     .tp_traverse = (traverseproc)FutureIter_traverse,
1762     .tp_iter = PyObject_SelfIter,
1763     .tp_iternext = (iternextfunc)FutureIter_iternext,
1764     .tp_methods = FutureIter_methods,
1765 };
1766 
1767 static PyObject *
future_new_iter(PyObject * fut)1768 future_new_iter(PyObject *fut)
1769 {
1770     futureiterobject *it;
1771 
1772     if (!PyObject_TypeCheck(fut, &FutureType)) {
1773         PyErr_BadInternalCall();
1774         return NULL;
1775     }
1776 
1777     ENSURE_FUTURE_ALIVE(fut)
1778 
1779     if (fi_freelist_len) {
1780         fi_freelist_len--;
1781         it = fi_freelist;
1782         fi_freelist = (futureiterobject*) it->future;
1783         it->future = NULL;
1784         _Py_NewReference((PyObject*) it);
1785     }
1786     else {
1787         it = PyObject_GC_New(futureiterobject, &FutureIterType);
1788         if (it == NULL) {
1789             return NULL;
1790         }
1791     }
1792 
1793     Py_INCREF(fut);
1794     it->future = (FutureObj*)fut;
1795     PyObject_GC_Track(it);
1796     return (PyObject*)it;
1797 }
1798 
1799 
1800 /*********************** Task **************************/
1801 
1802 
1803 /*[clinic input]
1804 class _asyncio.Task "TaskObj *" "&Task_Type"
1805 [clinic start generated code]*/
1806 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/
1807 
1808 static int task_call_step_soon(TaskObj *, PyObject *);
1809 static PyObject * task_wakeup(TaskObj *, PyObject *);
1810 static PyObject * task_step(TaskObj *, PyObject *);
1811 
1812 /* ----- Task._step wrapper */
1813 
1814 static int
TaskStepMethWrapper_clear(TaskStepMethWrapper * o)1815 TaskStepMethWrapper_clear(TaskStepMethWrapper *o)
1816 {
1817     Py_CLEAR(o->sw_task);
1818     Py_CLEAR(o->sw_arg);
1819     return 0;
1820 }
1821 
1822 static void
TaskStepMethWrapper_dealloc(TaskStepMethWrapper * o)1823 TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o)
1824 {
1825     PyObject_GC_UnTrack(o);
1826     (void)TaskStepMethWrapper_clear(o);
1827     Py_TYPE(o)->tp_free(o);
1828 }
1829 
1830 static PyObject *
TaskStepMethWrapper_call(TaskStepMethWrapper * o,PyObject * args,PyObject * kwds)1831 TaskStepMethWrapper_call(TaskStepMethWrapper *o,
1832                          PyObject *args, PyObject *kwds)
1833 {
1834     if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
1835         PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments");
1836         return NULL;
1837     }
1838     if (args != NULL && PyTuple_GET_SIZE(args) != 0) {
1839         PyErr_SetString(PyExc_TypeError, "function takes no positional arguments");
1840         return NULL;
1841     }
1842     return task_step(o->sw_task, o->sw_arg);
1843 }
1844 
1845 static int
TaskStepMethWrapper_traverse(TaskStepMethWrapper * o,visitproc visit,void * arg)1846 TaskStepMethWrapper_traverse(TaskStepMethWrapper *o,
1847                              visitproc visit, void *arg)
1848 {
1849     Py_VISIT(o->sw_task);
1850     Py_VISIT(o->sw_arg);
1851     return 0;
1852 }
1853 
1854 static PyObject *
TaskStepMethWrapper_get___self__(TaskStepMethWrapper * o,void * Py_UNUSED (ignored))1855 TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored))
1856 {
1857     if (o->sw_task) {
1858         Py_INCREF(o->sw_task);
1859         return (PyObject*)o->sw_task;
1860     }
1861     Py_RETURN_NONE;
1862 }
1863 
1864 static PyGetSetDef TaskStepMethWrapper_getsetlist[] = {
1865     {"__self__", (getter)TaskStepMethWrapper_get___self__, NULL, NULL},
1866     {NULL} /* Sentinel */
1867 };
1868 
1869 static PyTypeObject TaskStepMethWrapper_Type = {
1870     PyVarObject_HEAD_INIT(NULL, 0)
1871     "TaskStepMethWrapper",
1872     .tp_basicsize = sizeof(TaskStepMethWrapper),
1873     .tp_itemsize = 0,
1874     .tp_getset = TaskStepMethWrapper_getsetlist,
1875     .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc,
1876     .tp_call = (ternaryfunc)TaskStepMethWrapper_call,
1877     .tp_getattro = PyObject_GenericGetAttr,
1878     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1879     .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse,
1880     .tp_clear = (inquiry)TaskStepMethWrapper_clear,
1881 };
1882 
1883 static PyObject *
TaskStepMethWrapper_new(TaskObj * task,PyObject * arg)1884 TaskStepMethWrapper_new(TaskObj *task, PyObject *arg)
1885 {
1886     TaskStepMethWrapper *o;
1887     o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type);
1888     if (o == NULL) {
1889         return NULL;
1890     }
1891 
1892     Py_INCREF(task);
1893     o->sw_task = task;
1894 
1895     Py_XINCREF(arg);
1896     o->sw_arg = arg;
1897 
1898     PyObject_GC_Track(o);
1899     return (PyObject*) o;
1900 }
1901 
1902 /* ----- Task._wakeup implementation */
1903 
1904 static  PyMethodDef TaskWakeupDef = {
1905     "task_wakeup",
1906     (PyCFunction)task_wakeup,
1907     METH_O,
1908     NULL
1909 };
1910 
1911 /* ----- Task introspection helpers */
1912 
1913 static int
register_task(PyObject * task)1914 register_task(PyObject *task)
1915 {
1916     _Py_IDENTIFIER(add);
1917 
1918     PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks,
1919                                                  &PyId_add, task);
1920     if (res == NULL) {
1921         return -1;
1922     }
1923     Py_DECREF(res);
1924     return 0;
1925 }
1926 
1927 
1928 static int
unregister_task(PyObject * task)1929 unregister_task(PyObject *task)
1930 {
1931     _Py_IDENTIFIER(discard);
1932 
1933     PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks,
1934                                                  &PyId_discard, task);
1935     if (res == NULL) {
1936         return -1;
1937     }
1938     Py_DECREF(res);
1939     return 0;
1940 }
1941 
1942 
1943 static int
enter_task(PyObject * loop,PyObject * task)1944 enter_task(PyObject *loop, PyObject *task)
1945 {
1946     PyObject *item;
1947     Py_hash_t hash;
1948     hash = PyObject_Hash(loop);
1949     if (hash == -1) {
1950         return -1;
1951     }
1952     item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash);
1953     if (item != NULL) {
1954         Py_INCREF(item);
1955         PyErr_Format(
1956             PyExc_RuntimeError,
1957             "Cannot enter into task %R while another " \
1958             "task %R is being executed.",
1959             task, item, NULL);
1960         Py_DECREF(item);
1961         return -1;
1962     }
1963     if (PyErr_Occurred()) {
1964         return -1;
1965     }
1966     return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash);
1967 }
1968 
1969 
1970 static int
leave_task(PyObject * loop,PyObject * task)1971 leave_task(PyObject *loop, PyObject *task)
1972 /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/
1973 {
1974     PyObject *item;
1975     Py_hash_t hash;
1976     hash = PyObject_Hash(loop);
1977     if (hash == -1) {
1978         return -1;
1979     }
1980     item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash);
1981     if (item != task) {
1982         if (item == NULL) {
1983             /* Not entered, replace with None */
1984             item = Py_None;
1985         }
1986         PyErr_Format(
1987             PyExc_RuntimeError,
1988             "Leaving task %R does not match the current task %R.",
1989             task, item, NULL);
1990         return -1;
1991     }
1992     return _PyDict_DelItem_KnownHash(current_tasks, loop, hash);
1993 }
1994 
1995 /* ----- Task */
1996 
1997 /*[clinic input]
1998 _asyncio.Task.__init__
1999 
2000     coro: object
2001     *
2002     loop: object = None
2003     name: object = None
2004 
2005 A coroutine wrapped in a Future.
2006 [clinic start generated code]*/
2007 
2008 static int
_asyncio_Task___init___impl(TaskObj * self,PyObject * coro,PyObject * loop,PyObject * name)2009 _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
2010                             PyObject *name)
2011 /*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/
2012 {
2013     if (future_init((FutureObj*)self, loop)) {
2014         return -1;
2015     }
2016 
2017     int is_coro = is_coroutine(coro);
2018     if (is_coro == -1) {
2019         return -1;
2020     }
2021     if (is_coro == 0) {
2022         self->task_log_destroy_pending = 0;
2023         PyErr_Format(PyExc_TypeError,
2024                      "a coroutine was expected, got %R",
2025                      coro, NULL);
2026         return -1;
2027     }
2028 
2029     Py_XSETREF(self->task_context, PyContext_CopyCurrent());
2030     if (self->task_context == NULL) {
2031         return -1;
2032     }
2033 
2034     Py_CLEAR(self->task_fut_waiter);
2035     self->task_must_cancel = 0;
2036     self->task_log_destroy_pending = 1;
2037     Py_INCREF(coro);
2038     Py_XSETREF(self->task_coro, coro);
2039 
2040     if (name == Py_None) {
2041         name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter);
2042     } else if (!PyUnicode_CheckExact(name)) {
2043         name = PyObject_Str(name);
2044     } else {
2045         Py_INCREF(name);
2046     }
2047     Py_XSETREF(self->task_name, name);
2048     if (self->task_name == NULL) {
2049         return -1;
2050     }
2051 
2052     if (task_call_step_soon(self, NULL)) {
2053         return -1;
2054     }
2055     return register_task((PyObject*)self);
2056 }
2057 
2058 static int
TaskObj_clear(TaskObj * task)2059 TaskObj_clear(TaskObj *task)
2060 {
2061     (void)FutureObj_clear((FutureObj*) task);
2062     Py_CLEAR(task->task_context);
2063     Py_CLEAR(task->task_coro);
2064     Py_CLEAR(task->task_name);
2065     Py_CLEAR(task->task_fut_waiter);
2066     return 0;
2067 }
2068 
2069 static int
TaskObj_traverse(TaskObj * task,visitproc visit,void * arg)2070 TaskObj_traverse(TaskObj *task, visitproc visit, void *arg)
2071 {
2072     Py_VISIT(task->task_context);
2073     Py_VISIT(task->task_coro);
2074     Py_VISIT(task->task_name);
2075     Py_VISIT(task->task_fut_waiter);
2076     (void)FutureObj_traverse((FutureObj*) task, visit, arg);
2077     return 0;
2078 }
2079 
2080 static PyObject *
TaskObj_get_log_destroy_pending(TaskObj * task,void * Py_UNUSED (ignored))2081 TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored))
2082 {
2083     if (task->task_log_destroy_pending) {
2084         Py_RETURN_TRUE;
2085     }
2086     else {
2087         Py_RETURN_FALSE;
2088     }
2089 }
2090 
2091 static int
TaskObj_set_log_destroy_pending(TaskObj * task,PyObject * val,void * Py_UNUSED (ignored))2092 TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored))
2093 {
2094     if (val == NULL) {
2095         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
2096         return -1;
2097     }
2098     int is_true = PyObject_IsTrue(val);
2099     if (is_true < 0) {
2100         return -1;
2101     }
2102     task->task_log_destroy_pending = is_true;
2103     return 0;
2104 }
2105 
2106 static PyObject *
TaskObj_get_must_cancel(TaskObj * task,void * Py_UNUSED (ignored))2107 TaskObj_get_must_cancel(TaskObj *task, void *Py_UNUSED(ignored))
2108 {
2109     if (task->task_must_cancel) {
2110         Py_RETURN_TRUE;
2111     }
2112     else {
2113         Py_RETURN_FALSE;
2114     }
2115 }
2116 
2117 static PyObject *
TaskObj_get_coro(TaskObj * task,void * Py_UNUSED (ignored))2118 TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored))
2119 {
2120     if (task->task_coro) {
2121         Py_INCREF(task->task_coro);
2122         return task->task_coro;
2123     }
2124 
2125     Py_RETURN_NONE;
2126 }
2127 
2128 static PyObject *
TaskObj_get_fut_waiter(TaskObj * task,void * Py_UNUSED (ignored))2129 TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored))
2130 {
2131     if (task->task_fut_waiter) {
2132         Py_INCREF(task->task_fut_waiter);
2133         return task->task_fut_waiter;
2134     }
2135 
2136     Py_RETURN_NONE;
2137 }
2138 
2139 /*[clinic input]
2140 _asyncio.Task._make_cancelled_error
2141 
2142 Create the CancelledError to raise if the Task is cancelled.
2143 
2144 This should only be called once when handling a cancellation since
2145 it erases the context exception value.
2146 [clinic start generated code]*/
2147 
2148 static PyObject *
_asyncio_Task__make_cancelled_error_impl(TaskObj * self)2149 _asyncio_Task__make_cancelled_error_impl(TaskObj *self)
2150 /*[clinic end generated code: output=55a819e8b4276fab input=52c0e32de8e2f840]*/
2151 {
2152     FutureObj *fut = (FutureObj*)self;
2153     return _asyncio_Future__make_cancelled_error_impl(fut);
2154 }
2155 
2156 
2157 /*[clinic input]
2158 _asyncio.Task._repr_info
2159 [clinic start generated code]*/
2160 
2161 static PyObject *
_asyncio_Task__repr_info_impl(TaskObj * self)2162 _asyncio_Task__repr_info_impl(TaskObj *self)
2163 /*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/
2164 {
2165     return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self);
2166 }
2167 
2168 /*[clinic input]
2169 _asyncio.Task.cancel
2170 
2171     msg: object = None
2172 
2173 Request that this task cancel itself.
2174 
2175 This arranges for a CancelledError to be thrown into the
2176 wrapped coroutine on the next cycle through the event loop.
2177 The coroutine then has a chance to clean up or even deny
2178 the request using try/except/finally.
2179 
2180 Unlike Future.cancel, this does not guarantee that the
2181 task will be cancelled: the exception might be caught and
2182 acted upon, delaying cancellation of the task or preventing
2183 cancellation completely.  The task may also return a value or
2184 raise a different exception.
2185 
2186 Immediately after this method is called, Task.cancelled() will
2187 not return True (unless the task was already cancelled).  A
2188 task will be marked as cancelled when the wrapped coroutine
2189 terminates with a CancelledError exception (even if cancel()
2190 was not called).
2191 [clinic start generated code]*/
2192 
2193 static PyObject *
_asyncio_Task_cancel_impl(TaskObj * self,PyObject * msg)2194 _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
2195 /*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00]*/
2196 {
2197     self->task_log_tb = 0;
2198 
2199     if (self->task_state != STATE_PENDING) {
2200         Py_RETURN_FALSE;
2201     }
2202 
2203     if (self->task_fut_waiter) {
2204         PyObject *res;
2205         int is_true;
2206 
2207         res = _PyObject_CallMethodIdOneArg(self->task_fut_waiter,
2208                                            &PyId_cancel, msg);
2209         if (res == NULL) {
2210             return NULL;
2211         }
2212 
2213         is_true = PyObject_IsTrue(res);
2214         Py_DECREF(res);
2215         if (is_true < 0) {
2216             return NULL;
2217         }
2218 
2219         if (is_true) {
2220             Py_RETURN_TRUE;
2221         }
2222     }
2223 
2224     self->task_must_cancel = 1;
2225     Py_XINCREF(msg);
2226     Py_XSETREF(self->task_cancel_msg, msg);
2227     Py_RETURN_TRUE;
2228 }
2229 
2230 /*[clinic input]
2231 _asyncio.Task.get_stack
2232 
2233     *
2234     limit: object = None
2235 
2236 Return the list of stack frames for this task's coroutine.
2237 
2238 If the coroutine is not done, this returns the stack where it is
2239 suspended.  If the coroutine has completed successfully or was
2240 cancelled, this returns an empty list.  If the coroutine was
2241 terminated by an exception, this returns the list of traceback
2242 frames.
2243 
2244 The frames are always ordered from oldest to newest.
2245 
2246 The optional limit gives the maximum number of frames to
2247 return; by default all available frames are returned.  Its
2248 meaning differs depending on whether a stack or a traceback is
2249 returned: the newest frames of a stack are returned, but the
2250 oldest frames of a traceback are returned.  (This matches the
2251 behavior of the traceback module.)
2252 
2253 For reasons beyond our control, only one stack frame is
2254 returned for a suspended coroutine.
2255 [clinic start generated code]*/
2256 
2257 static PyObject *
_asyncio_Task_get_stack_impl(TaskObj * self,PyObject * limit)2258 _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
2259 /*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/
2260 {
2261     return PyObject_CallFunctionObjArgs(
2262         asyncio_task_get_stack_func, self, limit, NULL);
2263 }
2264 
2265 /*[clinic input]
2266 _asyncio.Task.print_stack
2267 
2268     *
2269     limit: object = None
2270     file: object = None
2271 
2272 Print the stack or traceback for this task's coroutine.
2273 
2274 This produces output similar to that of the traceback module,
2275 for the frames retrieved by get_stack().  The limit argument
2276 is passed to get_stack().  The file argument is an I/O stream
2277 to which the output is written; by default output is written
2278 to sys.stderr.
2279 [clinic start generated code]*/
2280 
2281 static PyObject *
_asyncio_Task_print_stack_impl(TaskObj * self,PyObject * limit,PyObject * file)2282 _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
2283                                PyObject *file)
2284 /*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/
2285 {
2286     return PyObject_CallFunctionObjArgs(
2287         asyncio_task_print_stack_func, self, limit, file, NULL);
2288 }
2289 
2290 /*[clinic input]
2291 _asyncio.Task.set_result
2292 
2293     result: object
2294     /
2295 [clinic start generated code]*/
2296 
2297 static PyObject *
_asyncio_Task_set_result(TaskObj * self,PyObject * result)2298 _asyncio_Task_set_result(TaskObj *self, PyObject *result)
2299 /*[clinic end generated code: output=1dcae308bfcba318 input=9d1a00c07be41bab]*/
2300 {
2301     PyErr_SetString(PyExc_RuntimeError,
2302                     "Task does not support set_result operation");
2303     return NULL;
2304 }
2305 
2306 /*[clinic input]
2307 _asyncio.Task.set_exception
2308 
2309     exception: object
2310     /
2311 [clinic start generated code]*/
2312 
2313 static PyObject *
_asyncio_Task_set_exception(TaskObj * self,PyObject * exception)2314 _asyncio_Task_set_exception(TaskObj *self, PyObject *exception)
2315 /*[clinic end generated code: output=bc377fc28067303d input=9a8f65c83dcf893a]*/
2316 {
2317     PyErr_SetString(PyExc_RuntimeError,
2318                     "Task does not support set_exception operation");
2319     return NULL;
2320 }
2321 
2322 /*[clinic input]
2323 _asyncio.Task.get_coro
2324 [clinic start generated code]*/
2325 
2326 static PyObject *
_asyncio_Task_get_coro_impl(TaskObj * self)2327 _asyncio_Task_get_coro_impl(TaskObj *self)
2328 /*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/
2329 {
2330     Py_INCREF(self->task_coro);
2331     return self->task_coro;
2332 }
2333 
2334 /*[clinic input]
2335 _asyncio.Task.get_name
2336 [clinic start generated code]*/
2337 
2338 static PyObject *
_asyncio_Task_get_name_impl(TaskObj * self)2339 _asyncio_Task_get_name_impl(TaskObj *self)
2340 /*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/
2341 {
2342     if (self->task_name) {
2343         Py_INCREF(self->task_name);
2344         return self->task_name;
2345     }
2346 
2347     Py_RETURN_NONE;
2348 }
2349 
2350 /*[clinic input]
2351 _asyncio.Task.set_name
2352 
2353     value: object
2354     /
2355 [clinic start generated code]*/
2356 
2357 static PyObject *
_asyncio_Task_set_name(TaskObj * self,PyObject * value)2358 _asyncio_Task_set_name(TaskObj *self, PyObject *value)
2359 /*[clinic end generated code: output=138a8d51e32057d6 input=a8359b6e65f8fd31]*/
2360 {
2361     if (!PyUnicode_CheckExact(value)) {
2362         value = PyObject_Str(value);
2363         if (value == NULL) {
2364             return NULL;
2365         }
2366     } else {
2367         Py_INCREF(value);
2368     }
2369 
2370     Py_XSETREF(self->task_name, value);
2371     Py_RETURN_NONE;
2372 }
2373 
2374 static void
TaskObj_finalize(TaskObj * task)2375 TaskObj_finalize(TaskObj *task)
2376 {
2377     _Py_IDENTIFIER(call_exception_handler);
2378     _Py_IDENTIFIER(task);
2379     _Py_IDENTIFIER(message);
2380     _Py_IDENTIFIER(source_traceback);
2381 
2382     PyObject *context;
2383     PyObject *message = NULL;
2384     PyObject *func;
2385     PyObject *error_type, *error_value, *error_traceback;
2386 
2387     if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
2388         goto done;
2389     }
2390 
2391     /* Save the current exception, if any. */
2392     PyErr_Fetch(&error_type, &error_value, &error_traceback);
2393 
2394     context = PyDict_New();
2395     if (context == NULL) {
2396         goto finally;
2397     }
2398 
2399     message = PyUnicode_FromString("Task was destroyed but it is pending!");
2400     if (message == NULL) {
2401         goto finally;
2402     }
2403 
2404     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
2405         _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0)
2406     {
2407         goto finally;
2408     }
2409 
2410     if (task->task_source_tb != NULL) {
2411         if (_PyDict_SetItemId(context, &PyId_source_traceback,
2412                               task->task_source_tb) < 0)
2413         {
2414             goto finally;
2415         }
2416     }
2417 
2418     func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler);
2419     if (func != NULL) {
2420         PyObject *res = PyObject_CallOneArg(func, context);
2421         if (res == NULL) {
2422             PyErr_WriteUnraisable(func);
2423         }
2424         else {
2425             Py_DECREF(res);
2426         }
2427         Py_DECREF(func);
2428     }
2429 
2430 finally:
2431     Py_XDECREF(context);
2432     Py_XDECREF(message);
2433 
2434     /* Restore the saved exception. */
2435     PyErr_Restore(error_type, error_value, error_traceback);
2436 
2437 done:
2438     FutureObj_finalize((FutureObj*)task);
2439 }
2440 
2441 static void TaskObj_dealloc(PyObject *);  /* Needs Task_CheckExact */
2442 
2443 static PyMethodDef TaskType_methods[] = {
2444     _ASYNCIO_FUTURE_RESULT_METHODDEF
2445     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
2446     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
2447     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
2448     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
2449     _ASYNCIO_FUTURE_DONE_METHODDEF
2450     _ASYNCIO_TASK_SET_RESULT_METHODDEF
2451     _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF
2452     _ASYNCIO_TASK_CANCEL_METHODDEF
2453     _ASYNCIO_TASK_GET_STACK_METHODDEF
2454     _ASYNCIO_TASK_PRINT_STACK_METHODDEF
2455     _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF
2456     _ASYNCIO_TASK__REPR_INFO_METHODDEF
2457     _ASYNCIO_TASK_GET_NAME_METHODDEF
2458     _ASYNCIO_TASK_SET_NAME_METHODDEF
2459     _ASYNCIO_TASK_GET_CORO_METHODDEF
2460     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
2461     {NULL, NULL}        /* Sentinel */
2462 };
2463 
2464 static PyGetSetDef TaskType_getsetlist[] = {
2465     FUTURE_COMMON_GETSETLIST
2466     {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending,
2467                              (setter)TaskObj_set_log_destroy_pending, NULL},
2468     {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL},
2469     {"_coro", (getter)TaskObj_get_coro, NULL, NULL},
2470     {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL},
2471     {NULL} /* Sentinel */
2472 };
2473 
2474 static PyTypeObject TaskType = {
2475     PyVarObject_HEAD_INIT(NULL, 0)
2476     "_asyncio.Task",
2477     sizeof(TaskObj),                       /* tp_basicsize */
2478     .tp_base = &FutureType,
2479     .tp_dealloc = TaskObj_dealloc,
2480     .tp_as_async = &FutureType_as_async,
2481     .tp_repr = (reprfunc)FutureObj_repr,
2482     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
2483     .tp_doc = _asyncio_Task___init____doc__,
2484     .tp_traverse = (traverseproc)TaskObj_traverse,
2485     .tp_clear = (inquiry)TaskObj_clear,
2486     .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist),
2487     .tp_iter = (getiterfunc)future_new_iter,
2488     .tp_methods = TaskType_methods,
2489     .tp_getset = TaskType_getsetlist,
2490     .tp_dictoffset = offsetof(TaskObj, dict),
2491     .tp_init = (initproc)_asyncio_Task___init__,
2492     .tp_new = PyType_GenericNew,
2493     .tp_finalize = (destructor)TaskObj_finalize,
2494 };
2495 
2496 static void
TaskObj_dealloc(PyObject * self)2497 TaskObj_dealloc(PyObject *self)
2498 {
2499     TaskObj *task = (TaskObj *)self;
2500 
2501     if (Task_CheckExact(self)) {
2502         /* When fut is subclass of Task, finalizer is called from
2503          * subtype_dealloc.
2504          */
2505         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
2506             // resurrected.
2507             return;
2508         }
2509     }
2510 
2511     PyObject_GC_UnTrack(self);
2512 
2513     if (task->task_weakreflist != NULL) {
2514         PyObject_ClearWeakRefs(self);
2515     }
2516 
2517     (void)TaskObj_clear(task);
2518     Py_TYPE(task)->tp_free(task);
2519 }
2520 
2521 static int
task_call_step_soon(TaskObj * task,PyObject * arg)2522 task_call_step_soon(TaskObj *task, PyObject *arg)
2523 {
2524     PyObject *cb = TaskStepMethWrapper_new(task, arg);
2525     if (cb == NULL) {
2526         return -1;
2527     }
2528 
2529     int ret = call_soon(task->task_loop, cb, NULL, task->task_context);
2530     Py_DECREF(cb);
2531     return ret;
2532 }
2533 
2534 static PyObject *
task_set_error_soon(TaskObj * task,PyObject * et,const char * format,...)2535 task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...)
2536 {
2537     PyObject* msg;
2538 
2539     va_list vargs;
2540 #ifdef HAVE_STDARG_PROTOTYPES
2541     va_start(vargs, format);
2542 #else
2543     va_start(vargs);
2544 #endif
2545     msg = PyUnicode_FromFormatV(format, vargs);
2546     va_end(vargs);
2547 
2548     if (msg == NULL) {
2549         return NULL;
2550     }
2551 
2552     PyObject *e = PyObject_CallOneArg(et, msg);
2553     Py_DECREF(msg);
2554     if (e == NULL) {
2555         return NULL;
2556     }
2557 
2558     if (task_call_step_soon(task, e) == -1) {
2559         Py_DECREF(e);
2560         return NULL;
2561     }
2562 
2563     Py_DECREF(e);
2564     Py_RETURN_NONE;
2565 }
2566 
2567 static inline int
gen_status_from_result(PyObject ** result)2568 gen_status_from_result(PyObject **result)
2569 {
2570     if (*result != NULL) {
2571         return PYGEN_NEXT;
2572     }
2573     if (_PyGen_FetchStopIterationValue(result) == 0) {
2574         return PYGEN_RETURN;
2575     }
2576 
2577     assert(PyErr_Occurred());
2578     return PYGEN_ERROR;
2579 }
2580 
2581 static PyObject *
task_step_impl(TaskObj * task,PyObject * exc)2582 task_step_impl(TaskObj *task, PyObject *exc)
2583 {
2584     int res;
2585     int clear_exc = 0;
2586     PyObject *result = NULL;
2587     PyObject *coro;
2588     PyObject *o;
2589 
2590     if (task->task_state != STATE_PENDING) {
2591         PyErr_Format(asyncio_InvalidStateError,
2592                      "_step(): already done: %R %R",
2593                      task,
2594                      exc ? exc : Py_None);
2595         goto fail;
2596     }
2597 
2598     if (task->task_must_cancel) {
2599         assert(exc != Py_None);
2600 
2601         if (exc) {
2602             /* Check if exc is a CancelledError */
2603             res = PyObject_IsInstance(exc, asyncio_CancelledError);
2604             if (res == -1) {
2605                 /* An error occurred, abort */
2606                 goto fail;
2607             }
2608             if (res == 0) {
2609                 /* exc is not CancelledError; reset it to NULL */
2610                 exc = NULL;
2611             }
2612         }
2613 
2614         if (!exc) {
2615             /* exc was not a CancelledError */
2616             exc = create_cancelled_error(task->task_cancel_msg);
2617 
2618             if (!exc) {
2619                 goto fail;
2620             }
2621             clear_exc = 1;
2622         }
2623 
2624         task->task_must_cancel = 0;
2625     }
2626 
2627     Py_CLEAR(task->task_fut_waiter);
2628 
2629     coro = task->task_coro;
2630     if (coro == NULL) {
2631         PyErr_SetString(PyExc_RuntimeError, "uninitialized Task object");
2632         if (clear_exc) {
2633             /* We created 'exc' during this call */
2634             Py_DECREF(exc);
2635         }
2636         return NULL;
2637     }
2638 
2639     int gen_status = PYGEN_ERROR;
2640     if (exc == NULL) {
2641         gen_status = PyIter_Send(coro, Py_None, &result);
2642     }
2643     else {
2644         result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc);
2645         gen_status = gen_status_from_result(&result);
2646         if (clear_exc) {
2647             /* We created 'exc' during this call */
2648             Py_DECREF(exc);
2649         }
2650     }
2651 
2652     if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) {
2653         PyObject *et, *ev, *tb;
2654 
2655         if (result != NULL) {
2656             /* The error is StopIteration and that means that
2657                the underlying coroutine has resolved */
2658 
2659             PyObject *res;
2660             if (task->task_must_cancel) {
2661                 // Task is cancelled right before coro stops.
2662                 task->task_must_cancel = 0;
2663                 res = future_cancel((FutureObj*)task, task->task_cancel_msg);
2664             }
2665             else {
2666                 res = future_set_result((FutureObj*)task, result);
2667             }
2668 
2669             Py_DECREF(result);
2670 
2671             if (res == NULL) {
2672                 return NULL;
2673             }
2674             Py_DECREF(res);
2675             Py_RETURN_NONE;
2676         }
2677 
2678         if (PyErr_ExceptionMatches(asyncio_CancelledError)) {
2679             /* CancelledError */
2680             PyErr_Fetch(&et, &ev, &tb);
2681 
2682             FutureObj *fut = (FutureObj*)task;
2683             _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state;
2684             exc_state->exc_type = et;
2685             exc_state->exc_value = ev;
2686             exc_state->exc_traceback = tb;
2687 
2688             return future_cancel(fut, NULL);
2689         }
2690 
2691         /* Some other exception; pop it and call Task.set_exception() */
2692         PyErr_Fetch(&et, &ev, &tb);
2693 
2694         assert(et);
2695         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
2696             PyErr_NormalizeException(&et, &ev, &tb);
2697         }
2698         if (tb != NULL) {
2699             PyException_SetTraceback(ev, tb);
2700         }
2701         o = future_set_exception((FutureObj*)task, ev);
2702         if (!o) {
2703             /* An exception in Task.set_exception() */
2704             Py_DECREF(et);
2705             Py_XDECREF(tb);
2706             Py_XDECREF(ev);
2707             goto fail;
2708         }
2709         assert(o == Py_None);
2710         Py_DECREF(o);
2711 
2712         if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) ||
2713             PyErr_GivenExceptionMatches(et, PyExc_SystemExit))
2714         {
2715             /* We've got a KeyboardInterrupt or a SystemError; re-raise it */
2716             PyErr_Restore(et, ev, tb);
2717             goto fail;
2718         }
2719 
2720         Py_DECREF(et);
2721         Py_XDECREF(tb);
2722         Py_XDECREF(ev);
2723 
2724         Py_RETURN_NONE;
2725     }
2726 
2727     if (result == (PyObject*)task) {
2728         /* We have a task that wants to await on itself */
2729         goto self_await;
2730     }
2731 
2732     /* Check if `result` is FutureObj or TaskObj (and not a subclass) */
2733     if (Future_CheckExact(result) || Task_CheckExact(result)) {
2734         PyObject *wrapper;
2735         PyObject *res;
2736         FutureObj *fut = (FutureObj*)result;
2737 
2738         /* Check if `result` future is attached to a different loop */
2739         if (fut->fut_loop != task->task_loop) {
2740             goto different_loop;
2741         }
2742 
2743         if (!fut->fut_blocking) {
2744             goto yield_insteadof_yf;
2745         }
2746 
2747         fut->fut_blocking = 0;
2748 
2749         /* result.add_done_callback(task._wakeup) */
2750         wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task);
2751         if (wrapper == NULL) {
2752             goto fail;
2753         }
2754         res = future_add_done_callback(
2755             (FutureObj*)result, wrapper, task->task_context);
2756         Py_DECREF(wrapper);
2757         if (res == NULL) {
2758             goto fail;
2759         }
2760         Py_DECREF(res);
2761 
2762         /* task._fut_waiter = result */
2763         task->task_fut_waiter = result;  /* no incref is necessary */
2764 
2765         if (task->task_must_cancel) {
2766             PyObject *r;
2767             int is_true;
2768             r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel,
2769                                              task->task_cancel_msg);
2770             if (r == NULL) {
2771                 return NULL;
2772             }
2773             is_true = PyObject_IsTrue(r);
2774             Py_DECREF(r);
2775             if (is_true < 0) {
2776                 return NULL;
2777             }
2778             else if (is_true) {
2779                 task->task_must_cancel = 0;
2780             }
2781         }
2782 
2783         Py_RETURN_NONE;
2784     }
2785 
2786     /* Check if `result` is None */
2787     if (result == Py_None) {
2788         /* Bare yield relinquishes control for one event loop iteration. */
2789         if (task_call_step_soon(task, NULL)) {
2790             goto fail;
2791         }
2792         return result;
2793     }
2794 
2795     /* Check if `result` is a Future-compatible object */
2796     if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) {
2797         goto fail;
2798     }
2799     if (o != NULL && o != Py_None) {
2800         /* `result` is a Future-compatible object */
2801         PyObject *wrapper;
2802         PyObject *res;
2803 
2804         int blocking = PyObject_IsTrue(o);
2805         Py_DECREF(o);
2806         if (blocking < 0) {
2807             goto fail;
2808         }
2809 
2810         /* Check if `result` future is attached to a different loop */
2811         PyObject *oloop = get_future_loop(result);
2812         if (oloop == NULL) {
2813             goto fail;
2814         }
2815         if (oloop != task->task_loop) {
2816             Py_DECREF(oloop);
2817             goto different_loop;
2818         }
2819         Py_DECREF(oloop);
2820 
2821         if (!blocking) {
2822             goto yield_insteadof_yf;
2823         }
2824 
2825         /* result._asyncio_future_blocking = False */
2826         if (_PyObject_SetAttrId(
2827                 result, &PyId__asyncio_future_blocking, Py_False) == -1) {
2828             goto fail;
2829         }
2830 
2831         wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task);
2832         if (wrapper == NULL) {
2833             goto fail;
2834         }
2835 
2836         /* result.add_done_callback(task._wakeup) */
2837         PyObject *add_cb = _PyObject_GetAttrId(
2838             result, &PyId_add_done_callback);
2839         if (add_cb == NULL) {
2840             Py_DECREF(wrapper);
2841             goto fail;
2842         }
2843         PyObject *stack[2];
2844         stack[0] = wrapper;
2845         stack[1] = (PyObject *)task->task_context;
2846         res = PyObject_Vectorcall(add_cb, stack, 1, context_kwname);
2847         Py_DECREF(add_cb);
2848         Py_DECREF(wrapper);
2849         if (res == NULL) {
2850             goto fail;
2851         }
2852         Py_DECREF(res);
2853 
2854         /* task._fut_waiter = result */
2855         task->task_fut_waiter = result;  /* no incref is necessary */
2856 
2857         if (task->task_must_cancel) {
2858             PyObject *r;
2859             int is_true;
2860             r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel,
2861                                              task->task_cancel_msg);
2862             if (r == NULL) {
2863                 return NULL;
2864             }
2865             is_true = PyObject_IsTrue(r);
2866             Py_DECREF(r);
2867             if (is_true < 0) {
2868                 return NULL;
2869             }
2870             else if (is_true) {
2871                 task->task_must_cancel = 0;
2872             }
2873         }
2874 
2875         Py_RETURN_NONE;
2876     }
2877 
2878     Py_XDECREF(o);
2879     /* Check if `result` is a generator */
2880     res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type);
2881     if (res < 0) {
2882         goto fail;
2883     }
2884     if (res) {
2885         /* `result` is a generator */
2886         o = task_set_error_soon(
2887             task, PyExc_RuntimeError,
2888             "yield was used instead of yield from for "
2889             "generator in task %R with %R", task, result);
2890         Py_DECREF(result);
2891         return o;
2892     }
2893 
2894     /* The `result` is none of the above */
2895     o = task_set_error_soon(
2896         task, PyExc_RuntimeError, "Task got bad yield: %R", result);
2897     Py_DECREF(result);
2898     return o;
2899 
2900 self_await:
2901     o = task_set_error_soon(
2902         task, PyExc_RuntimeError,
2903         "Task cannot await on itself: %R", task);
2904     Py_DECREF(result);
2905     return o;
2906 
2907 yield_insteadof_yf:
2908     o = task_set_error_soon(
2909         task, PyExc_RuntimeError,
2910         "yield was used instead of yield from "
2911         "in task %R with %R",
2912         task, result);
2913     Py_DECREF(result);
2914     return o;
2915 
2916 different_loop:
2917     o = task_set_error_soon(
2918         task, PyExc_RuntimeError,
2919         "Task %R got Future %R attached to a different loop",
2920         task, result);
2921     Py_DECREF(result);
2922     return o;
2923 
2924 fail:
2925     Py_XDECREF(result);
2926     return NULL;
2927 }
2928 
2929 static PyObject *
task_step(TaskObj * task,PyObject * exc)2930 task_step(TaskObj *task, PyObject *exc)
2931 {
2932     PyObject *res;
2933 
2934     if (enter_task(task->task_loop, (PyObject*)task) < 0) {
2935         return NULL;
2936     }
2937 
2938     res = task_step_impl(task, exc);
2939 
2940     if (res == NULL) {
2941         PyObject *et, *ev, *tb;
2942         PyErr_Fetch(&et, &ev, &tb);
2943         leave_task(task->task_loop, (PyObject*)task);
2944         _PyErr_ChainExceptions(et, ev, tb);
2945         return NULL;
2946     }
2947     else {
2948         if (leave_task(task->task_loop, (PyObject*)task) < 0) {
2949             Py_DECREF(res);
2950             return NULL;
2951         }
2952         else {
2953             return res;
2954         }
2955     }
2956 }
2957 
2958 static PyObject *
task_wakeup(TaskObj * task,PyObject * o)2959 task_wakeup(TaskObj *task, PyObject *o)
2960 {
2961     PyObject *et, *ev, *tb;
2962     PyObject *result;
2963     assert(o);
2964 
2965     if (Future_CheckExact(o) || Task_CheckExact(o)) {
2966         PyObject *fut_result = NULL;
2967         int res = future_get_result((FutureObj*)o, &fut_result);
2968 
2969         switch(res) {
2970         case -1:
2971             assert(fut_result == NULL);
2972             break; /* exception raised */
2973         case 0:
2974             Py_DECREF(fut_result);
2975             return task_step(task, NULL);
2976         default:
2977             assert(res == 1);
2978             result = task_step(task, fut_result);
2979             Py_DECREF(fut_result);
2980             return result;
2981         }
2982     }
2983     else {
2984         PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
2985         if (fut_result != NULL) {
2986             Py_DECREF(fut_result);
2987             return task_step(task, NULL);
2988         }
2989         /* exception raised */
2990     }
2991 
2992     PyErr_Fetch(&et, &ev, &tb);
2993     if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
2994         PyErr_NormalizeException(&et, &ev, &tb);
2995     }
2996 
2997     result = task_step(task, ev);
2998 
2999     Py_DECREF(et);
3000     Py_XDECREF(tb);
3001     Py_XDECREF(ev);
3002 
3003     return result;
3004 }
3005 
3006 
3007 /*********************** Functions **************************/
3008 
3009 
3010 /*[clinic input]
3011 _asyncio._get_running_loop
3012 
3013 Return the running event loop or None.
3014 
3015 This is a low-level function intended to be used by event loops.
3016 This function is thread-specific.
3017 
3018 [clinic start generated code]*/
3019 
3020 static PyObject *
_asyncio__get_running_loop_impl(PyObject * module)3021 _asyncio__get_running_loop_impl(PyObject *module)
3022 /*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/
3023 {
3024     PyObject *loop;
3025     if (get_running_loop(&loop)) {
3026         return NULL;
3027     }
3028     if (loop == NULL) {
3029         /* There's no currently running event loop */
3030         Py_RETURN_NONE;
3031     }
3032     return loop;
3033 }
3034 
3035 /*[clinic input]
3036 _asyncio._set_running_loop
3037     loop: 'O'
3038     /
3039 
3040 Set the running event loop.
3041 
3042 This is a low-level function intended to be used by event loops.
3043 This function is thread-specific.
3044 [clinic start generated code]*/
3045 
3046 static PyObject *
_asyncio__set_running_loop(PyObject * module,PyObject * loop)3047 _asyncio__set_running_loop(PyObject *module, PyObject *loop)
3048 /*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/
3049 {
3050     if (set_running_loop(loop)) {
3051         return NULL;
3052     }
3053     Py_RETURN_NONE;
3054 }
3055 
3056 /*[clinic input]
3057 _asyncio.get_event_loop
3058 
3059 Return an asyncio event loop.
3060 
3061 When called from a coroutine or a callback (e.g. scheduled with
3062 call_soon or similar API), this function will always return the
3063 running event loop.
3064 
3065 If there is no running event loop set, the function will return
3066 the result of `get_event_loop_policy().get_event_loop()` call.
3067 [clinic start generated code]*/
3068 
3069 static PyObject *
_asyncio_get_event_loop_impl(PyObject * module)3070 _asyncio_get_event_loop_impl(PyObject *module)
3071 /*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
3072 {
3073     return get_event_loop(1);
3074 }
3075 
3076 /*[clinic input]
3077 _asyncio._get_event_loop
3078     stacklevel: int = 3
3079 [clinic start generated code]*/
3080 
3081 static PyObject *
_asyncio__get_event_loop_impl(PyObject * module,int stacklevel)3082 _asyncio__get_event_loop_impl(PyObject *module, int stacklevel)
3083 /*[clinic end generated code: output=9c1d6d3c802e67c9 input=d17aebbd686f711d]*/
3084 {
3085     return get_event_loop(stacklevel-1);
3086 }
3087 
3088 /*[clinic input]
3089 _asyncio.get_running_loop
3090 
3091 Return the running event loop.  Raise a RuntimeError if there is none.
3092 
3093 This function is thread-specific.
3094 [clinic start generated code]*/
3095 
3096 static PyObject *
_asyncio_get_running_loop_impl(PyObject * module)3097 _asyncio_get_running_loop_impl(PyObject *module)
3098 /*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/
3099 {
3100     PyObject *loop;
3101     if (get_running_loop(&loop)) {
3102         return NULL;
3103     }
3104     if (loop == NULL) {
3105         /* There's no currently running event loop */
3106         PyErr_SetString(
3107             PyExc_RuntimeError, "no running event loop");
3108     }
3109     return loop;
3110 }
3111 
3112 /*[clinic input]
3113 _asyncio._register_task
3114 
3115     task: object
3116 
3117 Register a new task in asyncio as executed by loop.
3118 
3119 Returns None.
3120 [clinic start generated code]*/
3121 
3122 static PyObject *
_asyncio__register_task_impl(PyObject * module,PyObject * task)3123 _asyncio__register_task_impl(PyObject *module, PyObject *task)
3124 /*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/
3125 {
3126     if (register_task(task) < 0) {
3127         return NULL;
3128     }
3129     Py_RETURN_NONE;
3130 }
3131 
3132 
3133 /*[clinic input]
3134 _asyncio._unregister_task
3135 
3136     task: object
3137 
3138 Unregister a task.
3139 
3140 Returns None.
3141 [clinic start generated code]*/
3142 
3143 static PyObject *
_asyncio__unregister_task_impl(PyObject * module,PyObject * task)3144 _asyncio__unregister_task_impl(PyObject *module, PyObject *task)
3145 /*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/
3146 {
3147     if (unregister_task(task) < 0) {
3148         return NULL;
3149     }
3150     Py_RETURN_NONE;
3151 }
3152 
3153 
3154 /*[clinic input]
3155 _asyncio._enter_task
3156 
3157     loop: object
3158     task: object
3159 
3160 Enter into task execution or resume suspended task.
3161 
3162 Task belongs to loop.
3163 
3164 Returns None.
3165 [clinic start generated code]*/
3166 
3167 static PyObject *
_asyncio__enter_task_impl(PyObject * module,PyObject * loop,PyObject * task)3168 _asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task)
3169 /*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/
3170 {
3171     if (enter_task(loop, task) < 0) {
3172         return NULL;
3173     }
3174     Py_RETURN_NONE;
3175 }
3176 
3177 
3178 /*[clinic input]
3179 _asyncio._leave_task
3180 
3181     loop: object
3182     task: object
3183 
3184 Leave task execution or suspend a task.
3185 
3186 Task belongs to loop.
3187 
3188 Returns None.
3189 [clinic start generated code]*/
3190 
3191 static PyObject *
_asyncio__leave_task_impl(PyObject * module,PyObject * loop,PyObject * task)3192 _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task)
3193 /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/
3194 {
3195     if (leave_task(loop, task) < 0) {
3196         return NULL;
3197     }
3198     Py_RETURN_NONE;
3199 }
3200 
3201 
3202 /*********************** PyRunningLoopHolder ********************/
3203 
3204 
3205 static PyRunningLoopHolder *
new_running_loop_holder(PyObject * loop)3206 new_running_loop_holder(PyObject *loop)
3207 {
3208     PyRunningLoopHolder *rl = PyObject_New(
3209         PyRunningLoopHolder, &PyRunningLoopHolder_Type);
3210     if (rl == NULL) {
3211         return NULL;
3212     }
3213 
3214 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
3215     rl->rl_pid = getpid();
3216 #endif
3217 
3218     Py_INCREF(loop);
3219     rl->rl_loop = loop;
3220 
3221     return rl;
3222 }
3223 
3224 
3225 static void
PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder * rl)3226 PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl)
3227 {
3228     if (cached_running_holder == (PyObject *)rl) {
3229         cached_running_holder = NULL;
3230     }
3231     Py_CLEAR(rl->rl_loop);
3232     PyObject_Free(rl);
3233 }
3234 
3235 
3236 static PyTypeObject PyRunningLoopHolder_Type = {
3237     PyVarObject_HEAD_INIT(NULL, 0)
3238     "_RunningLoopHolder",
3239     sizeof(PyRunningLoopHolder),
3240     .tp_getattro = PyObject_GenericGetAttr,
3241     .tp_flags = Py_TPFLAGS_DEFAULT,
3242     .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc,
3243 };
3244 
3245 
3246 /*********************** Module **************************/
3247 
3248 
3249 static void
module_free_freelists(void)3250 module_free_freelists(void)
3251 {
3252     PyObject *next;
3253     PyObject *current;
3254 
3255     next = (PyObject*) fi_freelist;
3256     while (next != NULL) {
3257         assert(fi_freelist_len > 0);
3258         fi_freelist_len--;
3259 
3260         current = next;
3261         next = (PyObject*) ((futureiterobject*) current)->future;
3262         PyObject_GC_Del(current);
3263     }
3264     assert(fi_freelist_len == 0);
3265     fi_freelist = NULL;
3266 }
3267 
3268 
3269 static void
module_free(void * m)3270 module_free(void *m)
3271 {
3272     Py_CLEAR(asyncio_mod);
3273     Py_CLEAR(traceback_extract_stack);
3274     Py_CLEAR(asyncio_future_repr_info_func);
3275     Py_CLEAR(asyncio_get_event_loop_policy);
3276     Py_CLEAR(asyncio_iscoroutine_func);
3277     Py_CLEAR(asyncio_task_get_stack_func);
3278     Py_CLEAR(asyncio_task_print_stack_func);
3279     Py_CLEAR(asyncio_task_repr_info_func);
3280     Py_CLEAR(asyncio_InvalidStateError);
3281     Py_CLEAR(asyncio_CancelledError);
3282 
3283     Py_CLEAR(all_tasks);
3284     Py_CLEAR(current_tasks);
3285     Py_CLEAR(iscoroutine_typecache);
3286 
3287     Py_CLEAR(context_kwname);
3288 
3289     module_free_freelists();
3290 
3291     module_initialized = 0;
3292 }
3293 
3294 static int
module_init(void)3295 module_init(void)
3296 {
3297     PyObject *module = NULL;
3298     if (module_initialized) {
3299         return 0;
3300     }
3301 
3302     asyncio_mod = PyImport_ImportModule("asyncio");
3303     if (asyncio_mod == NULL) {
3304         goto fail;
3305     }
3306 
3307     current_tasks = PyDict_New();
3308     if (current_tasks == NULL) {
3309         goto fail;
3310     }
3311 
3312     iscoroutine_typecache = PySet_New(NULL);
3313     if (iscoroutine_typecache == NULL) {
3314         goto fail;
3315     }
3316 
3317 
3318     context_kwname = Py_BuildValue("(s)", "context");
3319     if (context_kwname == NULL) {
3320         goto fail;
3321     }
3322 
3323 #define WITH_MOD(NAME) \
3324     Py_CLEAR(module); \
3325     module = PyImport_ImportModule(NAME); \
3326     if (module == NULL) { \
3327         goto fail; \
3328     }
3329 
3330 #define GET_MOD_ATTR(VAR, NAME) \
3331     VAR = PyObject_GetAttrString(module, NAME); \
3332     if (VAR == NULL) { \
3333         goto fail; \
3334     }
3335 
3336     WITH_MOD("asyncio.events")
3337     GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy")
3338 
3339     WITH_MOD("asyncio.base_futures")
3340     GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info")
3341 
3342     WITH_MOD("asyncio.exceptions")
3343     GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError")
3344     GET_MOD_ATTR(asyncio_CancelledError, "CancelledError")
3345 
3346     WITH_MOD("asyncio.base_tasks")
3347     GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info")
3348     GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack")
3349     GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack")
3350 
3351     WITH_MOD("asyncio.coroutines")
3352     GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine")
3353 
3354     WITH_MOD("traceback")
3355     GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
3356 
3357     PyObject *weak_set;
3358     WITH_MOD("weakref")
3359     GET_MOD_ATTR(weak_set, "WeakSet");
3360     all_tasks = PyObject_CallNoArgs(weak_set);
3361     Py_CLEAR(weak_set);
3362     if (all_tasks == NULL) {
3363         goto fail;
3364     }
3365 
3366     module_initialized = 1;
3367     Py_DECREF(module);
3368     return 0;
3369 
3370 fail:
3371     Py_CLEAR(module);
3372     module_free(NULL);
3373     return -1;
3374 
3375 #undef WITH_MOD
3376 #undef GET_MOD_ATTR
3377 }
3378 
3379 PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
3380 
3381 static PyMethodDef asyncio_methods[] = {
3382     _ASYNCIO_GET_EVENT_LOOP_METHODDEF
3383     _ASYNCIO__GET_EVENT_LOOP_METHODDEF
3384     _ASYNCIO_GET_RUNNING_LOOP_METHODDEF
3385     _ASYNCIO__GET_RUNNING_LOOP_METHODDEF
3386     _ASYNCIO__SET_RUNNING_LOOP_METHODDEF
3387     _ASYNCIO__REGISTER_TASK_METHODDEF
3388     _ASYNCIO__UNREGISTER_TASK_METHODDEF
3389     _ASYNCIO__ENTER_TASK_METHODDEF
3390     _ASYNCIO__LEAVE_TASK_METHODDEF
3391     {NULL, NULL}
3392 };
3393 
3394 static struct PyModuleDef _asynciomodule = {
3395     PyModuleDef_HEAD_INIT,      /* m_base */
3396     "_asyncio",                 /* m_name */
3397     module_doc,                 /* m_doc */
3398     -1,                         /* m_size */
3399     asyncio_methods,            /* m_methods */
3400     NULL,                       /* m_slots */
3401     NULL,                       /* m_traverse */
3402     NULL,                       /* m_clear */
3403     (freefunc)module_free       /* m_free */
3404 };
3405 
3406 
3407 PyMODINIT_FUNC
PyInit__asyncio(void)3408 PyInit__asyncio(void)
3409 {
3410     if (module_init() < 0) {
3411         return NULL;
3412     }
3413     if (PyType_Ready(&FutureIterType) < 0) {
3414         return NULL;
3415     }
3416     if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) {
3417         return NULL;
3418     }
3419     if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) {
3420         return NULL;
3421     }
3422 
3423     PyObject *m = PyModule_Create(&_asynciomodule);
3424     if (m == NULL) {
3425         return NULL;
3426     }
3427 
3428     /* FutureType and TaskType are made ready by PyModule_AddType() calls below. */
3429     if (PyModule_AddType(m, &FutureType) < 0) {
3430         Py_DECREF(m);
3431         return NULL;
3432     }
3433 
3434     if (PyModule_AddType(m, &TaskType) < 0) {
3435         Py_DECREF(m);
3436         return NULL;
3437     }
3438 
3439     Py_INCREF(all_tasks);
3440     if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) {
3441         Py_DECREF(all_tasks);
3442         Py_DECREF(m);
3443         return NULL;
3444     }
3445 
3446     Py_INCREF(current_tasks);
3447     if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) {
3448         Py_DECREF(current_tasks);
3449         Py_DECREF(m);
3450         return NULL;
3451     }
3452 
3453     return m;
3454 }
3455