Skip to content

Commit 3b776cf

Browse files
committed
gh-155433: Fix TaskGroup losing outside cancellation after cancel()
1 parent 998b890 commit 3b776cf

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

Lib/asyncio/taskgroups.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ async def _aexit(self, et, exc):
151151
# If there are no pending cancellations left,
152152
# don't propagate CancelledError.
153153
propagate_cancellation_error = None
154+
else:
155+
# gh-155433: the remaining cancellation is not ours, don't drop it
156+
propagate_cancellation_error = exceptions.CancelledError()
154157

155158
# Propagate CancelledError if there is one, except if there
156159
# are other errors -- those have priority.

Lib/test/test_asyncio/test_taskgroups.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,26 @@ async def test_taskgroup_cancel_before_create_task(self):
11541154
with self.assertRaises(RuntimeError):
11551155
tg.create_task(asyncio.sleep(1))
11561156

1157+
async def test_taskgroup_cancel_keeps_outer_cancellation(self):
1158+
# gh-155433: any cancellation from outside the group must propagate.
1159+
async def child():
1160+
try:
1161+
await asyncio.sleep(10)
1162+
finally:
1163+
await asyncio.sleep(0.1)
1164+
1165+
async def body():
1166+
async with asyncio.TaskGroup() as tg:
1167+
tg.create_task(child())
1168+
await asyncio.sleep(0)
1169+
tg.cancel()
1170+
1171+
task = asyncio.create_task(body())
1172+
await asyncio.sleep(0.01)
1173+
task.cancel()
1174+
with self.assertRaises(asyncio.CancelledError):
1175+
await task
1176+
11571177
async def test_taskgroup_cancel_before_exception(self):
11581178
async def raise_exc(parent_tg: asyncio.TaskGroup):
11591179
parent_tg.cancel()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :class:`asyncio.TaskGroup` losing outside cancellation after
2+
``cancel()``.

0 commit comments

Comments
 (0)