Skip to content

Commit 8e92bf5

Browse files
authored
gh-155418: Fix TaskGroup hang when a task cancels it before suspending (#155421)
1 parent 287b7cf commit 8e92bf5

3 files changed

Lines changed: 16 additions & 0 deletions

File tree

Lib/asyncio/taskgroups.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ def create_task(self, coro, **kwargs):
239239
# the current task too early. gh-128550, gh-128588
240240
self._tasks.add(task)
241241
task.add_done_callback(self._on_task_done)
242+
# gh-155418: an eager task can cancel the group before joining _tasks
243+
if self._aborting and not task.done():
244+
task.cancel()
242245
try:
243246
return task
244247
finally:

Lib/test/test_asyncio/test_taskgroups.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,17 @@ async def test_taskgroup_cancel_before_create_task(self):
11871187
with self.assertRaises(RuntimeError):
11881188
tg.create_task(asyncio.sleep(1))
11891189

1190+
async def test_taskgroup_cancel_from_child_before_first_suspension(self):
1191+
# gh-155418: an eager task can cancel the group before joining _tasks
1192+
async def child(tg):
1193+
tg.cancel()
1194+
await asyncio.sleep(10)
1195+
self.fail("the child was not cancelled")
1196+
1197+
async with asyncio.TaskGroup() as tg:
1198+
task = tg.create_task(child(tg))
1199+
self.assertTrue(task.cancelled())
1200+
11901201
async def test_taskgroup_cancel_keeps_outer_cancellation(self):
11911202
# gh-155433: any cancellation from outside the group must propagate.
11921203
async def child():
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :class:`asyncio.TaskGroup` hang when a task created by
2+
:func:`asyncio.eager_task_factory` cancels the group before suspending.

0 commit comments

Comments
 (0)