Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7edee0b
Integrate task groups from EdgeDb
gvanrossum Feb 10, 2022
f495375
Make test_taskgroups.py run and pass
gvanrossum Feb 10, 2022
a87275a
Rename taskgroup to taskgroups in the test code
gvanrossum Feb 10, 2022
4df0acc
Export TaskGroup from asyncio; remove __future__ import
gvanrossum Feb 10, 2022
56db921
Only keep the newest _is_base_error() and _task_cancel()
gvanrossum Feb 10, 2022
500581e
Get rid of MultiError in favor of ExceptionGroup
gvanrossum Feb 11, 2022
4843e94
Add TaskGroupError to __all__
gvanrossum Feb 11, 2022
63e712d
Avoid DeprecationWarning: There is no current event loop
gvanrossum Feb 11, 2022
d233dd1
Prevent warning "test altered the execution environment"
gvanrossum Feb 11, 2022
af574d5
Get rid of custom TaskGroupError
gvanrossum Feb 11, 2022
299f366
Update comments explaining why test 21 doesn't work
gvanrossum Feb 12, 2022
9de3c87
Add tests showing that 'plain' BaseExceptions work
gvanrossum Feb 12, 2022
0e1355d
Allow creating new tasks while __aexit__ is waiting
gvanrossum Feb 12, 2022
77ec0e4
Add an API to Task to manage 'cancel_requested' flag
gvanrossum Feb 14, 2022
17b64b5
Add tests for .cancelling() and .uncancel()
gvanrossum Feb 14, 2022
5e3f4b9
Merge remote-tracking branch 'origin/main' into taskgroups
gvanrossum Feb 14, 2022
0b9bccd
📜🤖 Added by blurb_it.
blurb-it[bot] Feb 14, 2022
137ebe6
Replace EdgeDb copyright with a simpler attribution
gvanrossum Feb 15, 2022
f693c1c
Use task.cancelling() in task repr instead of access to private attri…
asvetlov Feb 15, 2022
b83734c
Change the internal imports
gvanrossum Feb 15, 2022
de3d820
Avoid needing self.loop in test
gvanrossum Feb 15, 2022
9712241
Make test 14 more robust
gvanrossum Feb 15, 2022
b3d4d18
Update Lib/asyncio/taskgroups.py
1st1 Feb 15, 2022
c1e5d64
Update Lib/test/test_asyncio/test_taskgroups.py
1st1 Feb 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Allow creating new tasks while __aexit__ is waiting
We stop when there are no unfinished tasks,
and then no new tasks can be created.

(TODO: more thorough testing of edge cases?)
  • Loading branch information
gvanrossum committed Feb 12, 2022
commit 0e1355d55509d083ec911995ef2d7837ff888017
6 changes: 3 additions & 3 deletions Lib/asyncio/taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ async def __aexit__(self, et, exc, tb):
def create_task(self, coro):
if not self._entered:
raise RuntimeError(f"TaskGroup {self!r} has not been entered")
if self._exiting:
raise RuntimeError(f"TaskGroup {self!r} is awaiting in exit")
if self._exiting and self._unfinished_tasks == 0:
raise RuntimeError(f"TaskGroup {self!r} is finished")
task = self._loop.create_task(coro)
task.add_done_callback(self._on_task_done)
self._unfinished_tasks += 1
Expand Down Expand Up @@ -217,7 +217,7 @@ def _on_task_done(self, task):
self._unfinished_tasks -= 1
assert self._unfinished_tasks >= 0

if self._exiting and not self._unfinished_tasks:
if self._on_completed_fut is not None and not self._unfinished_tasks:
if not self._on_completed_fut.done():
self._on_completed_fut.set_result(True)

Expand Down
42 changes: 42 additions & 0 deletions Lib/test/test_asyncio/test_taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,3 +670,45 @@ async def do_job(delay):
self.assertLess(len(g._tasks), 5)
await asyncio.sleep(1.35)
self.assertEqual(len(g._tasks), 0)

async def test_taskgroup_24(self):

async def root(g):
await asyncio.sleep(0.1)
g.create_task(coro1(0.1))
g.create_task(coro1(0.2))

async def coro1(delay):
await asyncio.sleep(delay)

async def runner():
async with taskgroups.TaskGroup() as g:
g.create_task(root(g))

await runner()

async def test_taskgroup_25(self):
nhydras = 0

async def hydra(g):
nonlocal nhydras
nhydras += 1
await asyncio.sleep(0.01)
g.create_task(hydra(g))
g.create_task(hydra(g))

async def hercules():
while nhydras < 10:
await asyncio.sleep(0.015)
1 / 0

async def runner():
async with taskgroups.TaskGroup() as g:
g.create_task(hydra(g))
g.create_task(hercules())

with self.assertRaises(ExceptionGroup) as cm:
await runner()

self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError})
self.assertGreaterEqual(nhydras, 10)