Skip to content

Commit 8d36cd5

Browse files
committed
pythongh-119121: Fix and test async.staggered.staggered_race
1 parent 697465f commit 8d36cd5

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

Lib/asyncio/staggered.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ async def staggered_race(coro_fns, delay, *, loop=None):
6969
exceptions = []
7070
running_tasks = []
7171

72-
async def run_one_coro(
73-
previous_failed: typing.Optional[locks.Event]) -> None:
72+
async def run_one_coro(previous_failed) -> None:
7473
# Wait for the previous task to finish, or for delay seconds
7574
if previous_failed is not None:
7675
with contextlib.suppress(exceptions_mod.TimeoutError):
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import asyncio
2+
import unittest
3+
from asyncio.staggered import staggered_race
4+
5+
6+
def tearDownModule():
7+
asyncio.set_event_loop_policy(None)
8+
9+
10+
class StaggeredTests(unittest.IsolatedAsyncioTestCase):
11+
async def test_empty(self):
12+
winner, index, excs = await staggered_race(
13+
[],
14+
delay=None,
15+
)
16+
17+
self.assertEqual(winner, None)
18+
self.assertEqual(index, None)
19+
self.assertEqual(excs, [])
20+
21+
async def test_one_successful(self):
22+
async def coro(index):
23+
return f'Res: {index}'
24+
25+
winner, index, excs = await staggered_race(
26+
[
27+
lambda: coro(0),
28+
lambda: coro(1),
29+
],
30+
delay=None,
31+
)
32+
33+
self.assertEqual(winner, 'Res: 0')
34+
self.assertEqual(index, 0)
35+
self.assertEqual(excs, [None])
36+
37+
async def test_first_error_second_successful(self):
38+
async def coro(index):
39+
if index == 0:
40+
raise ValueError(index)
41+
return f'Res: {index}'
42+
43+
winner, index, excs = await staggered_race(
44+
[
45+
lambda: coro(0),
46+
lambda: coro(1),
47+
],
48+
delay=None,
49+
)
50+
51+
self.assertEqual(winner, 'Res: 1')
52+
self.assertEqual(index, 1)
53+
self.assertEqual(len(excs), 2)
54+
self.assertIsInstance(excs[0], ValueError)
55+
self.assertEqual(excs[1], None)
56+
57+
async def test_first_timeout_second_successful(self):
58+
async def coro(index):
59+
if index == 0:
60+
await asyncio.sleep(10) # much bigger than delay
61+
return f'Res: {index}'
62+
63+
winner, index, excs = await staggered_race(
64+
[
65+
lambda: coro(0),
66+
lambda: coro(1),
67+
],
68+
delay=0.1,
69+
)
70+
71+
self.assertEqual(winner, 'Res: 1')
72+
self.assertEqual(index, 1)
73+
self.assertEqual(len(excs), 2)
74+
self.assertIsInstance(excs[0], asyncio.CancelledError)
75+
self.assertEqual(excs[1], None)
76+
77+
async def test_none_successful(self):
78+
async def coro(index):
79+
raise ValueError(index)
80+
81+
winner, index, excs = await staggered_race(
82+
[
83+
lambda: coro(0),
84+
lambda: coro(1),
85+
],
86+
delay=None,
87+
)
88+
89+
self.assertEqual(winner, None)
90+
self.assertEqual(index, None)
91+
self.assertEqual(len(excs), 2)
92+
self.assertIsInstance(excs[0], ValueError)
93+
self.assertIsInstance(excs[1], ValueError)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a NameError happening in ``asyncio.staggered.staggered_race``. This
2+
function is now tested.

0 commit comments

Comments
 (0)