Skip to content

Commit

Permalink
Fixed exception swallowing in a timed out cancel scope
Browse files Browse the repository at this point in the history
Fixes #54.
  • Loading branch information
agronholm committed May 6, 2019
1 parent 02cdc78 commit 264c10f
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 2 deletions.
3 changes: 2 additions & 1 deletion anyio/_backends/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
self._tasks.remove(host_task)
_task_states[host_task].cancel_scope = self._parent_scope

if isinstance(exc_val, (asyncio.CancelledError, CancelledError)):
exceptions = exc_val.exceptions if isinstance(exc_val, ExceptionGroup) else [exc_val]
if all(isinstance(exc, (asyncio.CancelledError, CancelledError)) for exc in exceptions):
if self._timeout_expired:
return True
elif self._parent_scope is None or not self._parent_scope.cancel_called:
Expand Down
3 changes: 2 additions & 1 deletion anyio/_backends/curio.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
self._tasks.remove(host_task)
_task_states[host_task].cancel_scope = self._parent_scope

if isinstance(exc_val, (curio.TaskCancelled, CancelledError)):
exceptions = exc_val.exceptions if isinstance(exc_val, ExceptionGroup) else [exc_val]
if all(isinstance(exc, (curio.TaskCancelled, CancelledError)) for exc in exceptions):
if self._timeout_expired:
return True
elif self._parent_scope is None or not self._parent_scope.cancel_called:
Expand Down
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ This library adheres to `Semantic Versioning <http://semver.org/>`_.
asyncio and curio
- Fixed task cancellation not happening right away on asyncio and curio when a cancel scope is
entered when the deadline has already passed
- Fixed exception group containing only cancellation exceptions not being swallowed by a timed out
cancel scope on asyncio and curio
- Added the ``current_time()`` function

**1.0.0rc1**
Expand Down
9 changes: 9 additions & 0 deletions tests/test_taskgroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,12 @@ async def test_deadline_reached_on_start():
async with move_on_after(0):
await sleep(0)
pytest.fail('Execution should not reach this point')


@pytest.mark.anyio
async def test_timeout_error_with_multiple_cancellations():
with pytest.raises(TimeoutError):
async with fail_after(0.1):
async with create_task_group() as tg:
await tg.spawn(sleep, 2)
await sleep(2)

0 comments on commit 264c10f

Please sign in to comment.