Skip to content

Add cooperative signal timeouts - #1548

Open
tamird wants to merge 1 commit into
pytest-dev:mainfrom
tamird:tamird/pytest-timeout-integration
Open

Add cooperative signal timeouts#1548
tamird wants to merge 1 commit into
pytest-dev:mainfrom
tamird:tamird/pytest-timeout-integration

Conversation

@tamird

@tamird tamird commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

A signal timeout can interrupt asyncio while it schedules a task's next step, leaving a pending task with no continuation 1. Catching the resulting failure and cancelling that task cannot reliably recover it.

Add opt-in cooperative signal timeouts through the proposed pytest-timeout expiry hook 2. The signal handler records the supplied failure and queues cancellation without raising into the scheduler. The owned runner then reports the timeout with the interrupted await's traceback, while preserving process-control exceptions and external cancellation. Final runner shutdown has a separate interruption path that closes the loop and may leave resource cleanup incomplete.

Existing signal behavior remains the default. Cooperative cancellation cannot stop an indefinitely blocking callback or a task that refuses to finish; pytest-timeout's thread method remains the hard process-stop option. This consumer does not take over other async plugins, synchronous tests that call asyncio.run(), retry budgets, or background-task ownership.

This keeps runner integration separate from timer policy, as requested in the earlier timeout discussion 3. The dedicated integration environment pins the producer prerequisite; that pin should become a released test dependency once the hook is available. Related to #215.

Prepared with Codex assistance.

@codecov-commenter

codecov-commenter commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.00000% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.38%. Comparing base (70815a7) to head (58aed64).

Files with missing lines Patch % Lines
pytest_asyncio/_timeout.py 92.98% 3 Missing and 5 partials ⚠️
pytest_asyncio/plugin.py 81.81% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1548      +/-   ##
==========================================
+ Coverage   94.50%   95.38%   +0.87%     
==========================================
  Files           2        3       +1     
  Lines         510      628     +118     
  Branches       62       78      +16     
==========================================
+ Hits          482      599     +117     
+ Misses         22       19       -3     
- Partials        6       10       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tamird
tamird force-pushed the tamird/pytest-timeout-integration branch 2 times, most recently from d36b012 to c149e1f Compare August 20, 2026 01:07
A signal timeout can interrupt asyncio while it schedules a task's
next step, leaving the task pending without a continuation [1].
Catching the resulting pytest failure and cancelling that task cannot
reliably recover it.

Add opt-in cooperative delivery through pytest-timeout's proposed
expiry hook [2]. Queue cancellation without raising into the scheduler,
then report the supplied failure at the owned runner boundary. Preserve
external cancellation, process-control exceptions, and the interrupted
await's traceback. Stop final runner shutdown separately when it times
out; ordinary shared-runner invocations remain reusable.

Keep timer selection, deadlines, debugger handling, and diagnostics in
pytest-timeout. Existing signal behavior remains the default.
Cooperative cancellation cannot stop blocking or cancellation-resistant
code, so the thread method remains the hard process-stop option. Final
runner shutdown may leave resource cleanup incomplete.

Pin the producer prerequisite in a dedicated integration environment
until its hook is released. Collect coverage from the isolated pytest
processes and map installed-wheel paths back to the source tree.
Require Coverage.py 7.10.3 for its subprocess-directory fixes [3].

[1]: pytest-dev/pytest-timeout#113
[2]: pytest-dev/pytest-timeout#204
[3]: https://coverage.readthedocs.io/en/7.10.3/changes.html
@tamird
tamird force-pushed the tamird/pytest-timeout-integration branch from c149e1f to 58aed64 Compare August 20, 2026 01:53
@tamird
tamird marked this pull request as ready for review August 20, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants