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 991adca012)
This commit is contained in:
INADA Naoki 2017-05-11 21:56:42 +09:00 committed by GitHub
parent a4465a5bd0
commit 3dc7c52a9f
4 changed files with 39 additions and 1 deletions

View file

@ -180,7 +180,12 @@ class Task(futures.Future):
else:
result = coro.throw(exc)
except StopIteration as exc:
self.set_result(exc.value)
if self._must_cancel:
# Task is cancelled right before coro stops.
self._must_cancel = False
self.set_exception(futures.CancelledError())
else:
self.set_result(exc.value)
except futures.CancelledError:
super().cancel() # I.e., Future.cancel(self).
except Exception as exc: