Skip to content

Commit

Permalink
Fixed TaskGroup.start() cancellation on asyncio
Browse files Browse the repository at this point in the history
Fixes #517.
  • Loading branch information
agronholm committed Jul 26, 2023
1 parent 8a5bcf9 commit d55d358
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
- Fixed ``MemoryObjectReceiveStream.receive()`` causing the receiving task on asyncio to
remain in a cancelled state if the operation was cancelled after an item was queued to
be received by the task (but before the task could actually receive the item)
- Fixed ``TaskGroup.start()`` on asyncio not responding to cancellation from the outside
- Removed unnecessary extra waiting cycle in ``Event.wait()`` on asyncio in the case
where the event was not yet set

Expand Down
17 changes: 11 additions & 6 deletions src/anyio/_backends/_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,12 +751,17 @@ async def start(
# point between, the task group is cancelled and this method never proceeds to
# process the completed future. That's why we have to have a shielded cancel
# scope here.
with CancelScope(shield=True):
try:
return await future
except CancelledError:
task.cancel()
raise
try:
return await future
except CancelledError:
task.cancel()
with CancelScope(shield=True):
try:
await task
except CancelledError:
pass

raise


#
Expand Down
5 changes: 1 addition & 4 deletions tests/test_taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,8 @@ def task_fn(*, task_status: TaskStatus = TASK_STATUS_IGNORED) -> None:
await tg.start(task_fn) # type: ignore[arg-type]


async def test_start_cancel_after_error(anyio_backend_name: str) -> None:
async def test_start_cancel_after_error() -> None:
"""Regression test for #517."""
if anyio_backend_name == "asyncio":
pytest.xfail("Known issue with the asyncio backend")

sleep_completed = False

async def sleep_and_raise() -> None:
Expand Down

0 comments on commit d55d358

Please sign in to comment.