Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 2 additions & 1 deletion Lib/asyncio/taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ async def __aexit__(self, et, exc, tb):
if self._base_error is not None:
raise self._base_error

if propagate_cancellation_error is not None:
if (propagate_cancellation_error is not None and
Copy link
Copy Markdown
Contributor

@graingert graingert Aug 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this now suppress the TimeoutError when used with async with timeout():?

I'll try and make a repro

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the condition is true in fewer cases than the original code (where it was just if propagate_cancellation_error is not None:) I don't see how it could suppress something that wouldn't be suppressed previously. But I'm not sure what you're thinking of, so please make a repro.

(self._parent_cancel_requested or not self._errors)):
# The wrapping task was cancelled; since we're done with
# closing all child tasks, just propagate the cancellation
# request now.
Expand Down
48 changes: 26 additions & 22 deletions Lib/test/test_asyncio/test_taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,29 +229,29 @@ async def runner():

self.assertEqual(NUM, 15)

async def test_cancellation_in_body(self):
async def test_taskgroup_08(self):

async def foo():
await asyncio.sleep(0.1)
1 / 0
try:
await asyncio.sleep(10)
finally:
1 / 0

async def runner():
async with taskgroups.TaskGroup() as g:
for _ in range(5):
g.create_task(foo())

try:
await asyncio.sleep(10)
except asyncio.CancelledError:
raise
await asyncio.sleep(10)

r = asyncio.create_task(runner())
await asyncio.sleep(0.1)

self.assertFalse(r.done())
r.cancel()
with self.assertRaises(asyncio.CancelledError) as cm:
with self.assertRaises(ExceptionGroup) as cm:
await r
self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError})

async def test_taskgroup_09(self):

Expand Down Expand Up @@ -315,33 +315,37 @@ async def runner():
async def test_taskgroup_11(self):

async def foo():
await asyncio.sleep(0.1)
1 / 0
try:
await asyncio.sleep(10)
finally:
1 / 0

async def runner():
async with taskgroups.TaskGroup():
async with taskgroups.TaskGroup() as g2:
for _ in range(5):
g2.create_task(foo())

try:
await asyncio.sleep(10)
except asyncio.CancelledError:
raise
await asyncio.sleep(10)

r = asyncio.create_task(runner())
await asyncio.sleep(0.1)

self.assertFalse(r.done())
r.cancel()
with self.assertRaises(asyncio.CancelledError):
with self.assertRaises(ExceptionGroup) as cm:
await r

self.assertEqual(get_error_types(cm.exception), {ExceptionGroup})
self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError})

async def test_taskgroup_12(self):

async def foo():
await asyncio.sleep(0.1)
1 / 0
try:
await asyncio.sleep(10)
finally:
1 / 0

async def runner():
async with taskgroups.TaskGroup() as g1:
Expand All @@ -351,19 +355,19 @@ async def runner():
for _ in range(5):
g2.create_task(foo())

try:
await asyncio.sleep(10)
except asyncio.CancelledError:
raise
await asyncio.sleep(10)

r = asyncio.create_task(runner())
await asyncio.sleep(0.1)

self.assertFalse(r.done())
r.cancel()
with self.assertRaises(asyncio.CancelledError):
with self.assertRaises(ExceptionGroup) as cm:
await r

self.assertEqual(get_error_types(cm.exception), {ExceptionGroup})
self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError})

async def test_taskgroup_13(self):

async def crash_after(t):
Expand Down