mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-95051: ensure that timeouts scheduled with asyncio.Timeout
that have already expired are deliverered promptly (GH-95109) (GH-95216)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
(cherry picked from commit 0c6f898005
)
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
This commit is contained in:
parent
2fb64a0687
commit
19d953682e
4 changed files with 32 additions and 4 deletions
|
@ -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?"""
|
||||
|
|
|
@ -106,6 +106,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…
Add table
Add a link
Reference in a new issue