diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-01-22 23:00:47 +0100 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-01-22 23:00:47 +0100 |
commit | 7d7cd62df6ed616494e66dee1b53cbcf2107bf1d (patch) | |
tree | 1d749933df159b7a774222ddb0e7540f0b813d7b | |
parent | 55fd28c121eae34e7a1f03ddbb9fa880a826a3fd (diff) | |
download | trollius-7d7cd62df6ed616494e66dee1b53cbcf2107bf1d.tar.gz |
wait_for() now cancels the future on timeout. Patch written by Gustavo
Carneiro.
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | asyncio/tasks.py | 6 | ||||
-rw-r--r-- | tests/test_tasks.py | 29 |
3 files changed, 19 insertions, 17 deletions
@@ -17,6 +17,7 @@ Contributors: - Eli Bendersky <eliben AT gmail.com> - Geert Jansen <geertj AT gmail.com> - Giampaolo Rodola' <g.rodola AT gmail.com> +- Gustavo Carneiro <gjcarneiro AT gmail.com> - Jeff Quast - Jonathan Slenders - Nikolay Kim <fafhrd91 AT gmail.com> diff --git a/asyncio/tasks.py b/asyncio/tasks.py index 42413dc..b52933f 100644 --- a/asyncio/tasks.py +++ b/asyncio/tasks.py @@ -382,8 +382,9 @@ def wait_for(fut, timeout, *, loop=None): Coroutine will be wrapped in Task. - Returns result of the Future or coroutine. Raises TimeoutError when - timeout occurs. + Returns result of the Future or coroutine. When a timeout occurs, + it cancels the task and raises TimeoutError. To avoid the task + cancellation, wrap it in shield(). Usage: @@ -405,6 +406,7 @@ def wait_for(fut, timeout, *, loop=None): return fut.result() else: fut.remove_done_callback(cb) + fut.cancel() raise futures.TimeoutError() finally: timeout_handle.cancel() diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 79a25d2..3d08ad8 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -355,30 +355,32 @@ class TaskTests(unittest.TestCase): when = yield 0 self.assertAlmostEqual(0.1, when) when = yield 0.1 - self.assertAlmostEqual(0.4, when) - yield 0.1 loop = test_utils.TestLoop(gen) self.addCleanup(loop.close) + foo_running = None + @tasks.coroutine def foo(): - yield from tasks.sleep(0.2, loop=loop) + nonlocal foo_running + foo_running = True + try: + yield from tasks.sleep(0.2, loop=loop) + finally: + foo_running = False return 'done' fut = tasks.Task(foo(), loop=loop) with self.assertRaises(futures.TimeoutError): loop.run_until_complete(tasks.wait_for(fut, 0.1, loop=loop)) - - self.assertFalse(fut.done()) + self.assertTrue(fut.done()) + # it should have been cancelled due to the timeout + self.assertTrue(fut.cancelled()) self.assertAlmostEqual(0.1, loop.time()) + self.assertEqual(foo_running, False) - # wait for result - res = loop.run_until_complete( - tasks.wait_for(fut, 0.3, loop=loop)) - self.assertEqual(res, 'done') - self.assertAlmostEqual(0.2, loop.time()) def test_wait_for_with_global_loop(self): @@ -406,11 +408,8 @@ class TaskTests(unittest.TestCase): events.set_event_loop(None) self.assertAlmostEqual(0.01, loop.time()) - self.assertFalse(fut.done()) - - # move forward to close generator - loop.advance_time(10) - loop.run_until_complete(fut) + self.assertTrue(fut.done()) + self.assertTrue(fut.cancelled()) def test_wait(self): |