Skip to content

Commit 4f807ca

Browse files
rewrite wait_for to use timeouts.timeout
1 parent 8367ca1 commit 4f807ca

File tree

2 files changed

+8
-73
lines changed

2 files changed

+8
-73
lines changed

Lib/asyncio/tasks.py

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from . import events
2525
from . import exceptions
2626
from . import futures
27+
from . import timeouts
2728
from .coroutines import _is_coroutine
2829

2930
# Helper to generate new task names
@@ -439,63 +440,23 @@ async def wait_for(fut, timeout):
439440
440441
This function is a coroutine.
441442
"""
442-
loop = events.get_running_loop()
443-
444443
if timeout is None:
445444
return await fut
446445

447446
if timeout <= 0:
448-
fut = ensure_future(fut, loop=loop)
447+
fut = ensure_future(fut)
449448

450449
if fut.done():
451450
return fut.result()
452451

453-
await _cancel_and_wait(fut, loop=loop)
452+
await _cancel_and_wait(fut)
454453
try:
455454
return fut.result()
456455
except exceptions.CancelledError as exc:
457-
raise exceptions.TimeoutError() from exc
458-
459-
waiter = loop.create_future()
460-
timeout_handle = loop.call_later(timeout, _release_waiter, waiter)
461-
cb = functools.partial(_release_waiter, waiter)
462-
463-
fut = ensure_future(fut, loop=loop)
464-
fut.add_done_callback(cb)
465-
466-
try:
467-
# wait until the future completes or the timeout
468-
try:
469-
await waiter
470-
except exceptions.CancelledError:
471-
if fut.done():
472-
return fut.result()
473-
else:
474-
fut.remove_done_callback(cb)
475-
# We must ensure that the task is not running
476-
# after wait_for() returns.
477-
# See https://bugs.python.org/issue32751
478-
await _cancel_and_wait(fut, loop=loop)
479-
raise
480-
481-
if fut.done():
482-
return fut.result()
483-
else:
484-
fut.remove_done_callback(cb)
485-
# We must ensure that the task is not running
486-
# after wait_for() returns.
487-
# See https://bugs.python.org/issue32751
488-
await _cancel_and_wait(fut, loop=loop)
489-
# In case task cancellation failed with some
490-
# exception, we should re-raise it
491-
# See https://bugs.python.org/issue40607
492-
try:
493-
return fut.result()
494-
except exceptions.CancelledError as exc:
495-
raise exceptions.TimeoutError() from exc
496-
finally:
497-
timeout_handle.cancel()
456+
raise TimeoutError from exc
498457

458+
async with timeouts.timeout(timeout):
459+
return await fut
499460

500461
async def _wait(fs, timeout, return_when, loop):
501462
"""Internal helper for wait().
@@ -541,9 +502,10 @@ def _on_completion(f):
541502
return done, pending
542503

543504

544-
async def _cancel_and_wait(fut, loop):
505+
async def _cancel_and_wait(fut):
545506
"""Cancel the *fut* future or task and wait until it completes."""
546507

508+
loop = events.get_running_loop()
547509
waiter = loop.create_future()
548510
cb = functools.partial(_release_waiter, waiter)
549511
fut.add_done_callback(cb)

Lib/test/test_asyncio/test_waitfor.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -237,33 +237,6 @@ async def inner():
237237
with self.assertRaises(FooException):
238238
await foo()
239239

240-
async def test_wait_for_self_cancellation(self):
241-
async def inner():
242-
try:
243-
await asyncio.sleep(0.3)
244-
except asyncio.CancelledError:
245-
try:
246-
await asyncio.sleep(0.3)
247-
except asyncio.CancelledError:
248-
await asyncio.sleep(0.3)
249-
250-
return 42
251-
252-
inner_task = asyncio.create_task(inner())
253-
254-
wait = asyncio.wait_for(inner_task, timeout=0.1)
255-
256-
# Test that wait_for itself is properly cancellable
257-
# even when the initial task holds up the initial cancellation.
258-
task = asyncio.create_task(wait)
259-
await asyncio.sleep(0.2)
260-
task.cancel()
261-
262-
with self.assertRaises(asyncio.CancelledError):
263-
await task
264-
265-
self.assertEqual(await inner_task, 42)
266-
267240
async def _test_cancel_wait_for(self, timeout):
268241
loop = asyncio.get_running_loop()
269242

0 commit comments

Comments
 (0)