Match Trio's startup error exactly

Compare the complete canonical `Nursery.start()` protocol error
before re-surfacing ambient cancellation. Preserve child-owned
`RuntimeError` objects whose messages only resemble Trio's wording.

Cover the colliding prefix and assert the original error remains the
exception group's sole leaf.

Review: PR #479 (goodboy)
https://github.com/goodboy/tractor/pull/479

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
wkt/ai_skillz_run_tests_landing
Gud Boi 2026-08-12 15:45:23 -04:00
parent 203a0f7e1f
commit 1c7d0c7f3e
2 changed files with 13 additions and 9 deletions

View File

@ -224,10 +224,10 @@ def test_genuine_startup_rte_still_raised(
@pytest.mark.parametrize(
'rte_arg',
[
# a bare `'started' in args[0]` substring match
# would (wrongly) demote this one to a `Cancelled`
# under ambient cancellation.
# Broad substring matches would wrongly demote either
# child-owned error to `Cancelled` under cancellation.
'never got started!',
'child exited without calling user hook',
# non-`str` first-arg edge; must not `TypeError`
# inside the wrapper's msg-match guard.
1234,
@ -242,9 +242,12 @@ def test_childs_own_rte_never_demoted_to_cancel(
first arg), raised under ambient cancellation must NOT
be demoted to a `trio.Cancelled` by the exact-msg-match
guard inside `start_or_cancel()`; the real error must
always propagate to the caller unchanged.
always propagate to the caller as the sole exception-group
leaf, preserving object identity.
'''
child_rte = RuntimeError(rte_arg)
async def cancels_cs_then_raises(
task_status: TaskStatus[None] = (
trio.TASK_STATUS_IGNORED
@ -255,7 +258,7 @@ def test_childs_own_rte_never_demoted_to_cancel(
# deterministically dies with ITS error while the
# caller is under effective cancellation.
cs.cancel()
raise RuntimeError(rte_arg)
raise child_rte
cs = trio.CancelScope()
@ -270,9 +273,7 @@ def test_childs_own_rte_never_demoted_to_cancel(
with pytest.raises(ExceptionGroup) as excinfo:
trio.run(main)
rte = excinfo.value.exceptions[0]
assert isinstance(rte, RuntimeError)
assert rte.args[0] == rte_arg
assert excinfo.value.exceptions == (child_rte,)
def test_started_value_and_args_passthru():

View File

@ -349,7 +349,10 @@ async def start_or_cancel(
# demote it to a `Cancelled`, losing the real error. The
# `isinstance` guard also avoids a `TypeError` when
# `rte.args[0]` isn't a `str`.
'child exited without calling' in rte.args[0]
rte.args[0] == (
'child exited without calling '
'task_status.started()'
)
):
# re-raises the in-flight `trio.Cancelled` IFF we're
# under effective cancellation; else a cheap no-op and