Skip to content

Commit 5e94ded

Browse files
authored
bpo-30048: asyncio: fix Task.cancel() was ignored. (GH-1547)
* bpo-30048: asyncio: fix Task.cancel() was ignored. (GH-1097) 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 991adca) * fix test
1 parent dab10f4 commit 5e94ded

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

Lib/asyncio/tasks.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,12 @@ def _step(self, exc=None):
240240
else:
241241
result = coro.throw(exc)
242242
except StopIteration as exc:
243-
self.set_result(exc.value)
243+
if self._must_cancel:
244+
# Task is cancelled right before coro stops.
245+
self._must_cancel = False
246+
self.set_exception(futures.CancelledError())
247+
else:
248+
self.set_result(exc.value)
244249
except futures.CancelledError:
245250
super().cancel() # I.e., Future.cancel(self).
246251
except Exception as exc:

Lib/test/test_asyncio/test_tasks.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,24 @@ def task():
573573
self.assertFalse(t._must_cancel) # White-box test.
574574
self.assertFalse(t.cancel())
575575

576+
def test_cancel_at_end(self):
577+
"""coroutine end right after task is cancelled"""
578+
loop = asyncio.new_event_loop()
579+
self.set_event_loop(loop)
580+
581+
@asyncio.coroutine
582+
def task():
583+
t.cancel()
584+
self.assertTrue(t._must_cancel) # White-box test.
585+
return 12
586+
587+
t = asyncio.Task(task(), loop=loop)
588+
self.assertRaises(
589+
asyncio.CancelledError, loop.run_until_complete, t)
590+
self.assertTrue(t.done())
591+
self.assertFalse(t._must_cancel) # White-box test.
592+
self.assertFalse(t.cancel())
593+
576594
def test_stop_while_run_in_complete(self):
577595

578596
def gen():

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Extension Modules
4949
Library
5050
-------
5151

52+
- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is
53+
running coroutine and the coroutine returned without any more ``await``.
54+
5255
- bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma Lin.
5356

5457
- Revert bpo-26293 for zipfile breakage. See also bpo-29094.

0 commit comments

Comments
 (0)