gh-157157: Make test_taskgroup_cancel_keeps_outer_cancellation deterministic by iamsharduld · Pull Request #157158 · python/cpython · GitHub
Skip to content

gh-157157: Make test_taskgroup_cancel_keeps_outer_cancellation deterministic - #157158

Merged
kumaraditya303 merged 2 commits into
python:mainfrom
iamsharduld:fix-taskgroup-cancel-test
Sep 11, 2026
Merged

gh-157157: Make test_taskgroup_cancel_keeps_outer_cancellation deterministic#157158
kumaraditya303 merged 2 commits into
python:mainfrom
iamsharduld:fix-taskgroup-cancel-test

Conversation

@iamsharduld

@iamsharduld iamsharduld commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes the timing dependence described in the issue: the test cancelled the parent task from outside after await asyncio.sleep(0.01), and lost the cancellation message whenever the loop stalled for more than 10 ms before the body task first ran (the mechanism, and a reproducer that stalls the loop with time.sleep(), are in the issue).

The test now synchronizes on two events instead of sleeping. The child signals from its finally block that the group is cancelling, which by then has cancelled the parent task and is waiting for the child, and waits there until the test releases it. Only then does the test cancel the parent task from outside. The ordering is fixed by the callback queue, not by time, so it holds on any build speed and for both task implementations.

Checked:

  • The rewritten test passes for TestTaskGroup and TestEagerTaskTaskGroup, 10 of 10 repeated runs, and the whole test_asyncio.test_taskgroups module passes.
  • With the asyncio.TaskGroup swallows cancellations coming from outside of it #155433 fix reverted locally, the rewritten test still fails in both classes (CancelledError not raised), so it keeps guarding the bug it was written for.
  • The event-based ordering was also verified in a standalone harness with the same 20 ms loop stall that makes the current test fail.

Since the original test was added by the gh-155433 fix, this likely wants the same backports.

…deterministic

The test cancelled the parent task from outside after a 10 ms sleep,
expecting the group to still be waiting for its child. If the event loop
stalled for longer than that before the body task first ran, the outer
cancel() landed while the parent's awaited future was already cancelled
by the group, and its message was dropped, failing the test on slow
builds such as the TSan CI job.

Synchronize on events instead: the child signals from its finally block
that the group is cancelling and waits to be released, and only then is
the parent task cancelled from outside.
Comment thread Misc/NEWS.d/next/Tests/2026-09-08-02-40-00.gh-issue-157157.5X2ypw.rst Outdated
@iamsharduld

Copy link
Copy Markdown
Contributor Author

@bedevere-app

bedevere-app Bot commented Sep 8, 2026

Copy link
Copy Markdown

@kumaraditya303
kumaraditya303 merged commit 1c641ff into python:main Sep 11, 2026
53 of 56 checks passed
clin1234 pushed a commit to clin1234/cpython that referenced this pull request Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip news tests Tests in the Lib/test dir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants