Skip to content
8 changes: 4 additions & 4 deletions Lib/asyncio/timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ def reschedule(self, when: Optional[float]) -> None:
self._timeout_handler = None
else:
loop = events.get_running_loop()
self._timeout_handler = loop.call_at(
when,
self._on_timeout,
)
if loop.time() >= when:
Comment thread
graingert marked this conversation as resolved.
Resolved
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?"""
Expand Down
24 changes: 24 additions & 0 deletions Lib/test/test_asyncio/test_timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,30 @@ async def test_timeout_zero(self):
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)
Comment thread
graingert marked this conversation as resolved.
Resolved

async def test_foreign_exception_passed(self):
with self.assertRaises(KeyError):
async with asyncio.timeout(0.01) as cm:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
special case asyncio.timeout(0) and timeouts in the past
Comment thread
graingert marked this conversation as resolved.
Resolved