Skip to content

Use asyncio.timeout on Python 3.11+ - #568

Open
8rief wants to merge 1 commit into
django:mainfrom
8rief:fix/timeout-uncancel
Open

Use asyncio.timeout on Python 3.11+#568
8rief wants to merge 1 commit into
django:mainfrom
8rief:fix/timeout-uncancel

Conversation

@8rief

@8rief 8rief commented Jun 29, 2026

Copy link
Copy Markdown

Summary

  • use asyncio.timeout for ApplicationCommunicator on Python 3.11+
  • keep the existing vendored timeout unchanged as the Python 3.10 fallback
  • cover cancellation-count restoration after a handled receive_output timeout

Related to #504.

Verification

The regression test failed before the production change because the handled timeout left the current task's cancellation count at 1 instead of restoring it to 0.

  • pytest tests/test_testing.py -q
  • pytest -q — 98 passed, 1 xfailed on Python 3.12
  • mypy .
  • pre-commit run --files asgiref/testing.py tests/test_testing.py
  • Python 3.10 container — 95 passed, 2 skipped, 1 xfailed; mypy passed
  • Python 3.11 and 3.14 containers — focused tests passed
  • Python 3.14 container — 98 passed, 1 xfailed; mypy passed

@carltongibson

Copy link
Copy Markdown
Member

@graingert WDYT?

@carltongibson

Copy link
Copy Markdown
Member

We're dropping Python 3.10 very shortly. I wonder if the correct approach here isn't to switch testing.py to asyncio.timeout instead, and deprecate timeout.py here. (We might merge this anyway...)

@carltongibson

Copy link
Copy Markdown
Member

Needs a rebase.

@graingert

Copy link
Copy Markdown
Contributor

I'd be very tempted to use the built in asyncio.timeout where available and leave this timeout alone for 3.10

@8rief
8rief force-pushed the fix/timeout-uncancel branch from 2fb1ec0 to 983fa0f Compare July 13, 2026 20:06
@8rief 8rief changed the title Restore timeout cancellation state on Python 3.11+ Use asyncio.timeout on Python 3.11+ Jul 13, 2026
@8rief

8rief commented Jul 13, 2026

Copy link
Copy Markdown
Author

Rebased and revised this along the suggested compatibility boundary. ApplicationCommunicator now uses asyncio.timeout on Python 3.11+, while Python 3.10 keeps the existing vendored fallback unchanged.

I moved the regression coverage to ApplicationCommunicator.receive_output; it confirms that a handled timeout no longer leaves the caller task in a cancelling state. The full test suite and mypy pass on Python 3.10 and 3.14, with focused checks on Python 3.11 as well.

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.

3 participants