diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2017-05-11 12:56:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-11 12:56:42 (GMT) |
commit | 3dc7c52a9f4fb83be3e26e31e2c7cd9dc1cb41a2 (patch) | |
tree | 8b20f9ecf036824ee1e6fbd08b890f4024d7531b /Modules | |
parent | a4465a5bd08f232cf097893006118c82975c3402 (diff) | |
download | cpython-3dc7c52a9f4fb83be3e26e31e2c7cd9dc1cb41a2.zip cpython-3dc7c52a9f4fb83be3e26e31e2c7cd9dc1cb41a2.tar.gz cpython-3dc7c52a9f4fb83be3e26e31e2c7cd9dc1cb41a2.tar.bz2 |
bpo-30048: asyncio: fix Task.cancel() was ignored. (GH-1546)
when there are no more `await` or `yield (from)` before return in coroutine,
cancel was ignored.
example:
async def coro():
asyncio.Task.current_task().cancel()
return 42
...
res = await coro() # should raise CancelledError
(cherry picked from commit 991adca012f5e106c2d4040ce619c696ba6f9c46)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_asynciomodule.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index a77ff96..75327fa 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1984,6 +1984,16 @@ task_step_impl(TaskObj *task, PyObject *exc) if (_PyGen_FetchStopIterationValue(&o) == 0) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ + if (task->task_must_cancel) { + // Task is cancelled right before coro stops. + Py_DECREF(o); + task->task_must_cancel = 0; + et = asyncio_CancelledError; + Py_INCREF(et); + ev = NULL; + tb = NULL; + goto set_exception; + } PyObject *res = future_set_result((FutureObj*)task, o); Py_DECREF(o); if (res == NULL) { @@ -2001,6 +2011,8 @@ task_step_impl(TaskObj *task, PyObject *exc) /* Some other exception; pop it and call Task.set_exception() */ PyErr_Fetch(&et, &ev, &tb); + +set_exception: assert(et); if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { PyErr_NormalizeException(&et, &ev, &tb); |