https://github.com/python/cpython/commit/16b46ebd2b0025aa461fdfc95fbf98a4f04b49e6
commit: 16b46ebd2b0025aa461fdfc95fbf98a4f04b49e6
branch: main
author: Nikita Sobolev <[email protected]>
committer: sobolevn <[email protected]>
date: 2024-05-20T14:06:50+03:00
summary:
gh-119121: Fix and test `async.staggered.staggered_race` (#119173)
files:
A Lib/test/test_asyncio/test_staggered.py
A Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst
M Lib/asyncio/staggered.py
diff --git a/Lib/asyncio/staggered.py b/Lib/asyncio/staggered.py
index e180cde0243b15..c3a7441a7b091d 100644
--- a/Lib/asyncio/staggered.py
+++ b/Lib/asyncio/staggered.py
@@ -69,8 +69,7 @@ async def staggered_race(coro_fns, delay, *, loop=None):
exceptions = []
running_tasks = []
- async def run_one_coro(
- previous_failed: typing.Optional[locks.Event]) -> None:
+ async def run_one_coro(previous_failed) -> None:
# Wait for the previous task to finish, or for delay seconds
if previous_failed is not None:
with contextlib.suppress(exceptions_mod.TimeoutError):
diff --git a/Lib/test/test_asyncio/test_staggered.py
b/Lib/test/test_asyncio/test_staggered.py
new file mode 100644
index 00000000000000..e6e32f7dbbbcba
--- /dev/null
+++ b/Lib/test/test_asyncio/test_staggered.py
@@ -0,0 +1,97 @@
+import asyncio
+import unittest
+from asyncio.staggered import staggered_race
+
+from test import support
+
+support.requires_working_socket(module=True)
+
+
+def tearDownModule():
+ asyncio.set_event_loop_policy(None)
+
+
+class StaggeredTests(unittest.IsolatedAsyncioTestCase):
+ async def test_empty(self):
+ winner, index, excs = await staggered_race(
+ [],
+ delay=None,
+ )
+
+ self.assertIs(winner, None)
+ self.assertIs(index, None)
+ self.assertEqual(excs, [])
+
+ async def test_one_successful(self):
+ async def coro(index):
+ return f'Res: {index}'
+
+ winner, index, excs = await staggered_race(
+ [
+ lambda: coro(0),
+ lambda: coro(1),
+ ],
+ delay=None,
+ )
+
+ self.assertEqual(winner, 'Res: 0')
+ self.assertEqual(index, 0)
+ self.assertEqual(excs, [None])
+
+ async def test_first_error_second_successful(self):
+ async def coro(index):
+ if index == 0:
+ raise ValueError(index)
+ return f'Res: {index}'
+
+ winner, index, excs = await staggered_race(
+ [
+ lambda: coro(0),
+ lambda: coro(1),
+ ],
+ delay=None,
+ )
+
+ self.assertEqual(winner, 'Res: 1')
+ self.assertEqual(index, 1)
+ self.assertEqual(len(excs), 2)
+ self.assertIsInstance(excs[0], ValueError)
+ self.assertIs(excs[1], None)
+
+ async def test_first_timeout_second_successful(self):
+ async def coro(index):
+ if index == 0:
+ await asyncio.sleep(10) # much bigger than delay
+ return f'Res: {index}'
+
+ winner, index, excs = await staggered_race(
+ [
+ lambda: coro(0),
+ lambda: coro(1),
+ ],
+ delay=0.1,
+ )
+
+ self.assertEqual(winner, 'Res: 1')
+ self.assertEqual(index, 1)
+ self.assertEqual(len(excs), 2)
+ self.assertIsInstance(excs[0], asyncio.CancelledError)
+ self.assertIs(excs[1], None)
+
+ async def test_none_successful(self):
+ async def coro(index):
+ raise ValueError(index)
+
+ winner, index, excs = await staggered_race(
+ [
+ lambda: coro(0),
+ lambda: coro(1),
+ ],
+ delay=None,
+ )
+
+ self.assertIs(winner, None)
+ self.assertIs(index, None)
+ self.assertEqual(len(excs), 2)
+ self.assertIsInstance(excs[0], ValueError)
+ self.assertIsInstance(excs[1], ValueError)
diff --git
a/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst
b/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst
new file mode 100644
index 00000000000000..fd562ea4f73317
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst
@@ -0,0 +1,2 @@
+Fix a NameError happening in ``asyncio.staggered.staggered_race``. This
+function is now tested.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]