summaryrefslogtreecommitdiffstats
path: root/Modules/_asynciomodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r--Modules/_asynciomodule.c27
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;