Skip to content

Detect unclosed cancel scopes when a task exits - #3510

Open
Sakshamm-Goyal wants to merge 1 commit into
python-trio:mainfrom
Sakshamm-Goyal:agent/fix-unclosed-cancel-scope
Open

Detect unclosed cancel scopes when a task exits#3510
Sakshamm-Goyal wants to merge 1 commit into
python-trio:mainfrom
Sakshamm-Goyal:agent/fix-unclosed-cancel-scope

Conversation

@Sakshamm-Goyal

Copy link
Copy Markdown

Summary

Fixes #3329.

A task can enter a CancelScope, return without exiting it, and leave another task able to exit that scope. The existing task-exit checks catch abandoned scope trees and unclosed child nurseries, but not this still-attached scope.

Detect a task exiting with a cancellation status different from its parent nursery's status. Report a scope-stack corruption error, preserving the original exception as context when present, and clean up the unclosed scopes and their registered deadlines. Existing child-nursery recovery is unchanged.

Regression coverage includes nested scopes, cancellation, nursery.start() adoption, guest mode, original exception context and enclosing parent-scope preservation. A release note is included.

Validation

  • The issue's real two-task reproduction fails against unchanged main at a3d7cddeacef74c87f667e9f9e8615f2ab7ce894 because no corruption error is raised.
  • Current Python 3.10 installed-wheel suite, with slow tests and CI-style isolation/plugin setup: 881 passed, 24 skipped, 2 xfailed.
  • Complete core suite: 287 passed, 11 skipped, 1 xfailed.
  • Mypy checks over src/trio pass for Darwin, Linux and Windows targets.
  • All applicable configured pre-commit hooks pass, including generated-file regeneration, Black, Ruff, spelling and Sphinx lint.
  • Python 3.12 full-suite validation has a Jedi __notes__ failure also reproduced on unchanged upstream; Python 3.10's corresponding checks pass. No claim of full platform CI coverage.

Related work

This covers a remaining case after #3307: the exiting task has an unclosed scope but no unclosed child nursery. It does not change the cancelled-task adoption policy discussed in #2896.

AI assistance

This change and its tests were developed and validated with OpenAI Codex assistance.

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00000%. Comparing base (a3d7cdd) to head (abc0c31).

Additional details and impacted files
@@               Coverage Diff               @@
##                 main        #3510   +/-   ##
===============================================
  Coverage   100.00000%   100.00000%           
===============================================
  Files             128          128           
  Lines           19454        19515   +61     
  Branches         1321         1327    +6     
===============================================
+ Hits            19454        19515   +61     
Files with missing lines Coverage Δ
src/trio/_core/_run.py 100.00000% <100.00000%> (ø)
src/trio/_core/_tests/test_guest_mode.py 100.00000% <100.00000%> (ø)
src/trio/_core/_tests/test_run.py 100.00000% <100.00000%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

More robust CancelScope misnesting prevention

1 participant