-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
bpo-46752: Introduce task groups in asyncio #31270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
7edee0b
f495375
a87275a
4df0acc
56db921
500581e
4843e94
63e712d
d233dd1
af574d5
299f366
9de3c87
0e1355d
77ec0e4
17b64b5
5e3f4b9
0b9bccd
137ebe6
f693c1c
b83734c
de3d820
9712241
b3d4d18
c1e5d64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,7 @@ | |
|
|
||
| import asyncio | ||
|
|
||
| from asyncio import taskgroups as taskgroup | ||
| from asyncio import taskgroups | ||
| import unittest | ||
|
|
||
|
|
||
|
|
@@ -42,7 +42,7 @@ async def foo2(): | |
| await asyncio.sleep(0.2) | ||
| return 11 | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| t1 = g.create_task(foo1()) | ||
| t2 = g.create_task(foo2()) | ||
|
|
||
|
|
@@ -59,7 +59,7 @@ async def foo2(): | |
| await asyncio.sleep(0.2) | ||
| return 11 | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| t1 = g.create_task(foo1()) | ||
| await asyncio.sleep(0.15) | ||
| t2 = g.create_task(foo2()) | ||
|
|
@@ -77,7 +77,7 @@ async def foo2(): | |
| await asyncio.sleep(0.2) | ||
| return 11 | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| t1 = g.create_task(foo1()) | ||
| await asyncio.sleep(0.15) | ||
| # cancel t1 explicitly, i.e. everything should continue | ||
|
|
@@ -111,13 +111,13 @@ async def foo2(): | |
| async def runner(): | ||
| nonlocal NUM, t2 | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(foo1()) | ||
| t2 = g.create_task(foo2()) | ||
|
|
||
| NUM += 10 | ||
|
|
||
| with self.assertRaisesRegex(taskgroup.TaskGroupError, | ||
| with self.assertRaisesRegex(taskgroups.TaskGroupError, | ||
| r'1 sub errors: \(ZeroDivisionError\)'): | ||
| await self.loop.create_task(runner()) | ||
|
|
||
|
|
@@ -147,7 +147,7 @@ async def foo2(): | |
| async def runner(): | ||
| nonlocal NUM, runner_cancel | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(foo1()) | ||
| g.create_task(foo1()) | ||
| g.create_task(foo1()) | ||
|
|
@@ -163,7 +163,7 @@ async def runner(): | |
| # The 3 foo1 sub tasks can be racy when the host is busy - if the | ||
| # cancellation happens in the middle, we'll see partial sub errors here | ||
| with self.assertRaisesRegex( | ||
| taskgroup.TaskGroupError, | ||
| taskgroups.TaskGroupError, | ||
| r'(1|2|3) sub errors: \(ZeroDivisionError\)', | ||
| ): | ||
| await self.loop.create_task(runner()) | ||
|
gvanrossum marked this conversation as resolved.
Outdated
|
||
|
|
@@ -185,7 +185,7 @@ async def foo(): | |
| raise | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| for _ in range(5): | ||
| g.create_task(foo()) | ||
|
|
||
|
|
@@ -213,7 +213,7 @@ async def foo(): | |
|
|
||
| async def runner(): | ||
| nonlocal NUM | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| for _ in range(5): | ||
| g.create_task(foo()) | ||
|
|
||
|
|
@@ -240,7 +240,7 @@ async def foo(): | |
| 1 / 0 | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| for _ in range(5): | ||
| g.create_task(foo()) | ||
|
|
||
|
|
@@ -271,15 +271,15 @@ async def foo2(): | |
|
|
||
| async def runner(): | ||
| nonlocal t1, t2 | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| t1 = g.create_task(foo1()) | ||
| t2 = g.create_task(foo2()) | ||
| await asyncio.sleep(0.1) | ||
| 1 / 0 | ||
|
|
||
| try: | ||
| await runner() | ||
| except taskgroup.TaskGroupError as t: | ||
| except taskgroups.TaskGroupError as t: | ||
| self.assertEqual(t.get_error_types(), {ZeroDivisionError}) | ||
| else: | ||
| self.fail('TaskGroupError was not raised') | ||
|
|
@@ -301,14 +301,14 @@ async def foo2(): | |
|
|
||
| async def runner(): | ||
| nonlocal t1, t2 | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| t1 = g.create_task(foo1()) | ||
| t2 = g.create_task(foo2()) | ||
| 1 / 0 | ||
|
|
||
| try: | ||
| await runner() | ||
| except taskgroup.TaskGroupError as t: | ||
| except taskgroups.TaskGroupError as t: | ||
| self.assertEqual(t.get_error_types(), {ZeroDivisionError}) | ||
| else: | ||
| self.fail('TaskGroupError was not raised') | ||
|
|
@@ -323,8 +323,8 @@ async def foo(): | |
| 1 / 0 | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup(): | ||
| async with taskgroup.TaskGroup() as g2: | ||
| async with taskgroups.TaskGroup(): | ||
| async with taskgroups.TaskGroup() as g2: | ||
| for _ in range(5): | ||
| g2.create_task(foo()) | ||
|
|
||
|
|
@@ -348,10 +348,10 @@ async def foo(): | |
| 1 / 0 | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g1: | ||
| async with taskgroups.TaskGroup() as g1: | ||
| g1.create_task(asyncio.sleep(10)) | ||
|
|
||
| async with taskgroup.TaskGroup() as g2: | ||
| async with taskgroups.TaskGroup() as g2: | ||
| for _ in range(5): | ||
| g2.create_task(foo()) | ||
|
|
||
|
|
@@ -375,14 +375,14 @@ async def crash_after(t): | |
| raise ValueError(t) | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup(name='g1') as g1: | ||
| async with taskgroups.TaskGroup(name='g1') as g1: | ||
| g1.create_task(crash_after(0.1)) | ||
|
|
||
| async with taskgroup.TaskGroup(name='g2') as g2: | ||
| async with taskgroups.TaskGroup(name='g2') as g2: | ||
| g2.create_task(crash_after(0.2)) | ||
|
|
||
| r = self.loop.create_task(runner()) | ||
|
gvanrossum marked this conversation as resolved.
Outdated
|
||
| with self.assertRaisesRegex(taskgroup.TaskGroupError, r'1 sub errors'): | ||
| with self.assertRaisesRegex(taskgroups.TaskGroupError, r'1 sub errors'): | ||
| await r | ||
|
|
||
| async def test_taskgroup_14(self): | ||
|
|
@@ -392,14 +392,14 @@ async def crash_after(t): | |
| raise ValueError(t) | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup(name='g1') as g1: | ||
| async with taskgroups.TaskGroup(name='g1') as g1: | ||
| g1.create_task(crash_after(0.2)) | ||
|
|
||
| async with taskgroup.TaskGroup(name='g2') as g2: | ||
| async with taskgroups.TaskGroup(name='g2') as g2: | ||
| g2.create_task(crash_after(0.1)) | ||
|
Comment on lines
+392
to
+394
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code seems not robust; it can fail on a slow machine: https://github.com/python/cpython/runs/5201217606?check_suite_focus=true.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me fix that by making the longer sleep longer -- that sleep will be interrupted so it doesn't matter how long it is. Let me know if you think that's not the right way to fix this test. |
||
|
|
||
| r = self.loop.create_task(runner()) | ||
|
gvanrossum marked this conversation as resolved.
Outdated
|
||
| with self.assertRaisesRegex(taskgroup.TaskGroupError, r'1 sub errors'): | ||
| with self.assertRaisesRegex(taskgroups.TaskGroupError, r'1 sub errors'): | ||
| await r | ||
|
|
||
| async def test_taskgroup_15(self): | ||
|
|
@@ -409,7 +409,7 @@ async def crash_soon(): | |
| 1 / 0 | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup(name='g1') as g1: | ||
| async with taskgroups.TaskGroup(name='g1') as g1: | ||
| g1.create_task(crash_soon()) | ||
| try: | ||
| await asyncio.sleep(10) | ||
|
|
@@ -432,7 +432,7 @@ async def crash_soon(): | |
| 1 / 0 | ||
|
|
||
| async def nested_runner(): | ||
| async with taskgroup.TaskGroup(name='g1') as g1: | ||
| async with taskgroups.TaskGroup(name='g1') as g1: | ||
| g1.create_task(crash_soon()) | ||
| try: | ||
| await asyncio.sleep(10) | ||
|
|
@@ -457,7 +457,7 @@ async def test_taskgroup_17(self): | |
|
|
||
| async def runner(): | ||
| nonlocal NUM | ||
| async with taskgroup.TaskGroup(): | ||
| async with taskgroups.TaskGroup(): | ||
| try: | ||
| await asyncio.sleep(10) | ||
| except asyncio.CancelledError: | ||
|
|
@@ -479,7 +479,7 @@ async def test_taskgroup_18(self): | |
|
|
||
| async def runner(): | ||
| nonlocal NUM | ||
| async with taskgroup.TaskGroup(): | ||
| async with taskgroups.TaskGroup(): | ||
| try: | ||
| await asyncio.sleep(10) | ||
| except asyncio.CancelledError: | ||
|
|
@@ -496,7 +496,7 @@ async def runner(): | |
|
|
||
| try: | ||
| await r | ||
| except taskgroup.TaskGroupError as t: | ||
| except taskgroups.TaskGroupError as t: | ||
| self.assertEqual(t.get_error_types(), {MyExc}) | ||
| else: | ||
| self.fail('TaskGroupError was not raised') | ||
|
|
@@ -515,14 +515,14 @@ async def nested(): | |
| raise MyExc | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(crash_soon()) | ||
| await nested() | ||
|
|
||
| r = self.loop.create_task(runner()) | ||
|
gvanrossum marked this conversation as resolved.
Outdated
|
||
| try: | ||
| await r | ||
| except taskgroup.TaskGroupError as t: | ||
| except taskgroups.TaskGroupError as t: | ||
| self.assertEqual(t.get_error_types(), {MyExc, ZeroDivisionError}) | ||
| else: | ||
| self.fail('TasgGroupError was not raised') | ||
|
|
@@ -539,7 +539,7 @@ async def nested(): | |
| raise KeyboardInterrupt | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(crash_soon()) | ||
| await nested() | ||
|
|
||
|
|
@@ -561,7 +561,7 @@ async def nested(): | |
| raise TypeError | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(crash_soon()) | ||
| await nested() | ||
|
|
||
|
|
@@ -579,7 +579,7 @@ async def foo2(): | |
| return 11 | ||
|
|
||
| async def runner(): | ||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| g.create_task(foo1()) | ||
| g.create_task(foo2()) | ||
|
|
||
|
|
@@ -595,7 +595,7 @@ async def test_taskgroup_23(self): | |
| async def do_job(delay): | ||
| await asyncio.sleep(delay) | ||
|
|
||
| async with taskgroup.TaskGroup() as g: | ||
| async with taskgroups.TaskGroup() as g: | ||
| for count in range(10): | ||
| await asyncio.sleep(0.1) | ||
| g.create_task(do_job(0.3)) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.