Commit 922bc2ca authored by Victor Stinner's avatar Victor Stinner

Closes #23219: cancelling asyncio.wait_for() now cancels the task

parent ab8848bc
...@@ -347,10 +347,9 @@ def wait_for(fut, timeout, *, loop=None): ...@@ -347,10 +347,9 @@ def wait_for(fut, timeout, *, loop=None):
it cancels the task and raises TimeoutError. To avoid the task it cancels the task and raises TimeoutError. To avoid the task
cancellation, wrap it in shield(). cancellation, wrap it in shield().
Usage: If the wait is cancelled, the task is also cancelled.
result = yield from asyncio.wait_for(fut, 10.0)
This function is a coroutine.
""" """
if loop is None: if loop is None:
loop = events.get_event_loop() loop = events.get_event_loop()
...@@ -367,7 +366,12 @@ def wait_for(fut, timeout, *, loop=None): ...@@ -367,7 +366,12 @@ def wait_for(fut, timeout, *, loop=None):
try: try:
# wait until the future completes or the timeout # wait until the future completes or the timeout
yield from waiter try:
yield from waiter
except futures.CancelledError:
fut.remove_done_callback(cb)
fut.cancel()
raise
if fut.done(): if fut.done():
return fut.result() return fut.result()
......
...@@ -1705,6 +1705,33 @@ class TaskTests(test_utils.TestCase): ...@@ -1705,6 +1705,33 @@ class TaskTests(test_utils.TestCase):
'test_task_source_traceback')) 'test_task_source_traceback'))
self.loop.run_until_complete(task) self.loop.run_until_complete(task)
def _test_cancel_wait_for(self, timeout):
loop = asyncio.new_event_loop()
self.addCleanup(loop.close)
@asyncio.coroutine
def blocking_coroutine():
fut = asyncio.Future(loop=loop)
# Block: fut result is never set
yield from fut
task = loop.create_task(blocking_coroutine())
wait = loop.create_task(asyncio.wait_for(task, timeout, loop=loop))
loop.call_soon(wait.cancel)
self.assertRaises(asyncio.CancelledError,
loop.run_until_complete, wait)
# Python issue #23219: cancelling the wait must also cancel the task
self.assertTrue(task.cancelled())
def test_cancel_blocking_wait_for(self):
self._test_cancel_wait_for(None)
def test_cancel_wait_for(self):
self._test_cancel_wait_for(60.0)
class GatherTestsBase: class GatherTestsBase:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment