]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-119121: Fix and test `async.staggered.staggered_race` (#119173)
authorNikita Sobolev <mail@sobolevn.me>
Mon, 20 May 2024 11:06:50 +0000 (14:06 +0300)
committerGitHub <noreply@github.com>
Mon, 20 May 2024 11:06:50 +0000 (14:06 +0300)
Lib/asyncio/staggered.py
Lib/test/test_asyncio/test_staggered.py [new file with mode: 0644]
Misc/NEWS.d/next/Library/2024-05-19-13-05-59.gh-issue-119121.P1gnh1.rst [new file with mode: 0644]

index e180cde0243b15433ec0f44d70b1a71d4b87f470..c3a7441a7b091d3ac9967488828dc814948ad935 100644 (file)
@@ -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 (file)
index 0000000..e6e32f7
--- /dev/null
@@ -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 (file)
index 0000000..fd562ea
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a NameError happening in ``asyncio.staggered.staggered_race``. This
+function is now tested.