8000 gh-95051: handle timeouts.timeout(0) and timeouts.timeout(-1) · python/cpython@dce6d74 · GitHub
[go: up one dir, main page]

Skip to content

Commit dce6d74

Browse files
committed
gh-95051: handle timeouts.timeout(0) and timeouts.timeout(-1)
1 parent b437894 commit dce6d74

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

Lib/asyncio/timeouts.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ def reschedule(self, when: Optional[float]) -> None:
5252
self._timeout_handler = None
5353
else:
5454
loop = events.get_running_loop()
55-
self._timeout_handler = loop.call_at(
56-
when,
57-
self._on_timeout,
58-
)
55+
if loop.time() >= when:
56+
self._timeout_handler = loop.call_soon(self._on_timeout)
57+
else:
58+
self._timeout_handler = loop.call_at(when, self._on_timeout)
5959

6060
def expired(self) -> bool:
6161
"""Is timeout expired during execution?"""
@@ -126,7 +126,13 @@ def timeout(delay: Optional[float]) -> Timeout:
126126
into TimeoutError.
127127
"""
128128
loop = events.get_running_loop()
129-
return Timeout(loop.time() + delay if delay is not None else None)
129+
if delay is None:
130+
return Timeout(None)
131+
132+
if delay <= 0:
133+
return Timeout(0)
134+
135+
return Timeout(loop.time() + delay)
130136

131137

132138
def timeout_at(when: Optional[float]) -> Timeout:

Lib/test/test_asyncio/test_timeouts.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,30 @@ async def test_timeout_zero(self):
105105
self.assertLess(t1-t0, 2)
106106
self.assertTrue(t0 <= cm.when() <= t1)
107107

108+
async def test_timeout_zero_sleep_zero(self):
109+
loop = asyncio.get_running_loop()
110+
t0 = loop.time()
111+
with self.assertRaises(TimeoutError):
112+
async with asyncio.timeout(0) as cm:
113+
await asyncio.sleep(0)
114+
t1 = loop.time()
115+
self.assertTrue(cm.expired())
116+
# 2 sec for slow CI boxes
117+
self.assertLess(t1-t0, 2)
118+
self.assertTrue(t0 <= cm.when() <= t1)
119+
120+
async def test_timeout_in_the_past_sleep_zero(self):
121+ 8592
loop = asyncio.get_running_loop()
122+
t0 = loop.time()
123+
with self.assertRaises(TimeoutError):
124+
async with asyncio.timeout(-11) as cm:
125+
await asyncio.sleep(0)
126+
t1 = loop.time()
127+
self.assertTrue(cm.expired())
128+
# 2 sec for slow CI boxes
129+
self.assertLess(t1-t0, 2)
130+
self.assertTrue(t0 <= cm.when() <= t1)
131+
108132
async def test_foreign_exception_passed(self):
109133
with self.assertRaises(KeyError):
110134
async with asyncio.timeout(0.01) as cm:

0 commit comments

Comments
 (0)
0