mirror of https://github.com/python/cpython
gh-95051: ensure that timeouts scheduled with `asyncio.Timeout` that have already expired are deliverered promptly (#95109)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
This commit is contained in:
parent
eb9c8a8bea
commit
0c6f898005
|
@ -625,6 +625,9 @@ Timeouts
|
|||
|
||||
If *when* is a float, it is set as the new deadline.
|
||||
|
||||
if *when* is in the past, the timeout will trigger on the next
|
||||
iteration of the event loop.
|
||||
|
||||
.. method:: expired() -> bool
|
||||
|
||||
Return whether the context manager has exceeded its deadline
|
||||
|
|
|
@ -52,10 +52,10 @@ class Timeout:
|
|||
self._timeout_handler = None
|
||||
else:
|
||||
loop = events.get_running_loop()
|
||||
self._timeout_handler = loop.call_at(
|
||||
when,
|
||||
self._on_timeout,
|
||||
)
|
||||
if when <= loop.time():
|
||||
self._timeout_handler = loop.call_soon(self._on_timeout)
|
||||
else:
|
||||
self._timeout_handler = loop.call_at(when, self._on_timeout)
|
||||
|
||||
def expired(self) -> bool:
|
||||
"""Is timeout expired during execution?"""
|
||||
|
|
|
@ -105,6 +105,30 @@ class TimeoutTests(unittest.IsolatedAsyncioTestCase):
|
|||
self.assertLess(t1-t0, 2)
|
||||
self.assertTrue(t0 <= cm.when() <= t1)
|
||||
|
||||
async def test_timeout_zero_sleep_zero(self):
|
||||
loop = asyncio.get_running_loop()
|
||||
t0 = loop.time()
|
||||
with self.assertRaises(TimeoutError):
|
||||
async with asyncio.timeout(0) as cm:
|
||||
await asyncio.sleep(0)
|
||||
t1 = loop.time()
|
||||
self.assertTrue(cm.expired())
|
||||
# 2 sec for slow CI boxes
|
||||
self.assertLess(t1-t0, 2)
|
||||
self.assertTrue(t0 <= cm.when() <= t1)
|
||||
|
||||
async def test_timeout_in_the_past_sleep_zero(self):
|
||||
loop = asyncio.get_running_loop()
|
||||
t0 = loop.time()
|
||||
with self.assertRaises(TimeoutError):
|
||||
async with asyncio.timeout(-11) as cm:
|
||||
await asyncio.sleep(0)
|
||||
t1 = loop.time()
|
||||
self.assertTrue(cm.expired())
|
||||
# 2 sec for slow CI boxes
|
||||
self.assertLess(t1-t0, 2)
|
||||
self.assertTrue(t0 >= cm.when() <= t1)
|
||||
|
||||
async def test_foreign_exception_passed(self):
|
||||
with self.assertRaises(KeyError):
|
||||
async with asyncio.timeout(0.01) as cm:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Ensure that timeouts scheduled with :class:`asyncio.Timeout` that have already expired are delivered promptly.
|
Loading…
Reference in New Issue