Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Also consider cancel counts for swallowing CancelledError on asyncio #606

Merged
merged 2 commits into from
Aug 26, 2023

Conversation

agronholm
Copy link
Owner

This fixes cases on Python 3.11+ where a third party library catches a CancelledError and raises another one without including the original message. At least asyncpg is known to do this.

@agronholm agronholm requested a review from graingert August 26, 2023 08:31
self._host_task.uncancel()
while self._cancel_calls:
self._cancel_calls -= 1
if not self._host_task.uncancel() and not self._cancel_calls:
Copy link
Collaborator

@graingert graingert Aug 26, 2023

Choose a reason for hiding this comment

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

I think cancel scopes need to store the current task.cancelling() value and compare to that rather than 0 like asyncio.timeout does in 3.11.4

Copy link
Collaborator

Choose a reason for hiding this comment

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

try:
    asyncio.current_task.cancel()
    await anyio.sleep(1)
except CancelledError:
        try:
            with CancelScope() as scope:
                scope.cancel()
                try:
                    await anyio.sleep(0)
                except asyncio.CancelledError:
                    raise asyncio.CancelledError
        except asyncio.CancelledError:
            pytest.fail("Should have swallowed the CancelledError")

Copy link
Collaborator

Choose a reason for hiding this comment

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

self._host_task.uncancel()
while self._cancel_calls:
self._cancel_calls -= 1
if not self._host_task.uncancel() and not self._cancel_calls:
Copy link
Collaborator

Choose a reason for hiding this comment

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

try:
    asyncio.current_task.cancel()
    await anyio.sleep(1)
except CancelledError:
        try:
            with CancelScope() as scope:
                scope.cancel()
                try:
                    await anyio.sleep(0)
                except asyncio.CancelledError:
                    raise asyncio.CancelledError
        except asyncio.CancelledError:
            pytest.fail("Should have swallowed the CancelledError")

@agronholm
Copy link
Owner Author

Updated the code and the test.

@agronholm agronholm merged commit c054923 into master Aug 26, 2023
@agronholm agronholm deleted the uncancel-swallow branch August 26, 2023 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants