Drop global `pytest-timeout` cap from `pyproject.toml`
`timeout = 200` was firing via SIGALRM (the default `method='signal'`) which synchronously raises `Failed` in trio's main thread mid-`epoll.poll()`, abandoning trio's runner mid-flight and leaving `GLOBAL_RUN_CONTEXT` half- installed. EVERY subsequent `trio.run()` in the same pytest session then bails with `RuntimeError: Attempted to call run() from inside a run()`. Empirical impact: a session that hits a single 200s hang cascades into 30-40 false-positive failures across every downstream test file that uses `trio.run`. Recent UDS run saw 1 real timeout (`test_unregistered_err_still_relayed`) poison 38 sibling tests with cascade-fails — a debugging nightmare. Same architectural bug we already documented in `tests/test_advanced_streaming.py::test_dynamic_pub_sub` (see its module-level NOTE) — both `pytest-timeout` enforcement modes are incompatible with trio under fork- based spawn backends. Now scoped session-wide. For tests that legitimately need a wall-clock cap, the canonical pattern is `with trio.fail_after(N):` INSIDE the test — trio's own `Cancelled` machinery cleanly unwinds the actor nursery without disturbing global state. For CI: rely on job-level wall-clock timeouts (e.g. GitHub Actions `timeout-minutes`) to abort genuinely-stuck suites. `pyproject.toml` comment block spells this all out so a future contributor doesn't reach back for `timeout =` and re-introduce the bug. ALSO, bump `xonsh` to at least `0.23.0` release. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-codesubint_forkserver_backend
parent
f8178df0fd
commit
3c366cac13
|
|
@ -93,7 +93,7 @@ testing = [
|
|||
repl = [
|
||||
"pyperclip>=1.9.0",
|
||||
"prompt-toolkit>=3.0.50",
|
||||
"xonsh>=0.22.8",
|
||||
"xonsh>=0.23.0",
|
||||
"psutil>=7.0.0",
|
||||
]
|
||||
lint = [
|
||||
|
|
@ -134,7 +134,7 @@ sync_pause = {requires-python = ">=3.13, <3.14"}
|
|||
# xonsh = { git = 'https://github.com/anki-code/xonsh.git', branch = 'prompt_next_suggestion' }
|
||||
# ^ https://github.com/xonsh/xonsh/pull/6048
|
||||
# xonsh = { git = 'https://github.com/xonsh/xonsh.git', branch = 'main' }
|
||||
xonsh = { path = "../xonsh", editable = true }
|
||||
# xonsh = { path = "../xonsh", editable = true }
|
||||
|
||||
# [tool.uv.sources.pdbp]
|
||||
# XXX, in case we need to tmp patch again.
|
||||
|
|
@ -203,7 +203,35 @@ all_bullets = true
|
|||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = '6.0'
|
||||
timeout = 200 # per-test hard limit
|
||||
# NOTE: `pytest-timeout`'s global per-test cap is intentionally
|
||||
# NOT set — both of its enforcement methods break trio's
|
||||
# runtime under our fork-based spawn backends:
|
||||
#
|
||||
# - `method='signal'` (the default; SIGALRM) raises `Failed`
|
||||
# synchronously from the signal handler in trio's main
|
||||
# thread, which leaves `GLOBAL_RUN_CONTEXT` half-installed
|
||||
# ("Trio guest run got abandoned"). EVERY subsequent
|
||||
# `trio.run()` in the same pytest session then bails with
|
||||
# `RuntimeError: Attempted to call run() from inside a
|
||||
# run()` — full-session poison: a single 200s hang
|
||||
# cascades into 30+ false-positive failures across
|
||||
# downstream test files.
|
||||
#
|
||||
# - `method='thread'` calls `_thread.interrupt_main()` which
|
||||
# can let the resulting `KeyboardInterrupt` escape trio's
|
||||
# `KIManager` under fork-cascade teardown races, killing
|
||||
# the whole pytest session.
|
||||
#
|
||||
# For tests that legitimately need a wall-clock cap, use
|
||||
# `with trio.fail_after(N):` INSIDE the test — trio's own
|
||||
# Cancelled machinery handles the timeout cleanly through
|
||||
# the actor nursery without disturbing global state. See
|
||||
# `tests/test_advanced_streaming.py::test_dynamic_pub_sub`'s
|
||||
# module-level NOTE for the canonical pattern.
|
||||
#
|
||||
# CI environments should rely on job-level wall-clock
|
||||
# timeouts (e.g. GitHub Actions `timeout-minutes`) for an
|
||||
# escape hatch on genuinely-stuck suites.
|
||||
# https://docs.pytest.org/en/stable/reference/reference.html#configuration-options
|
||||
testpaths = [
|
||||
'tests'
|
||||
|
|
|
|||
Loading…
Reference in New Issue