diff options
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r-- | Modules/_asynciomodule.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 4a1c91e..2151f20 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2621,6 +2621,20 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) Py_RETURN_NONE; } +static inline int +gen_status_from_result(PyObject **result) +{ + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + + assert(PyErr_Occurred()); + return PYGEN_ERROR; +} + static PyObject * task_step_impl(TaskObj *task, PyObject *exc) { @@ -2679,26 +2693,29 @@ task_step_impl(TaskObj *task, PyObject *exc) return NULL; } + int gen_status = PYGEN_ERROR; if (exc == NULL) { if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { - result = _PyGen_Send((PyGenObject*)coro, Py_None); + gen_status = PyGen_Send((PyGenObject*)coro, Py_None, &result); } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); + gen_status = gen_status_from_result(&result); } } else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); + gen_status = gen_status_from_result(&result); if (clear_exc) { /* We created 'exc' during this call */ Py_DECREF(exc); } } - if (result == NULL) { + if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) { PyObject *et, *ev, *tb; - if (_PyGen_FetchStopIterationValue(&o) == 0) { + if (result != NULL) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ @@ -2709,10 +2726,10 @@ task_step_impl(TaskObj *task, PyObject *exc) res = future_cancel((FutureObj*)task, task->task_cancel_msg); } else { - res = future_set_result((FutureObj*)task, o); + res = future_set_result((FutureObj*)task, result); } - Py_DECREF(o); + Py_DECREF(result); if (res == NULL) { return NULL; |