`faulthandler_timeout` stops covering a test once setup, call or a subtest fails (`pytest_exception_interact` cancels the timer)
I maintainer di solito rispondono entro 1 giorno
@XXXXXQ-0206 ci sta già lavorando.
Dal 15/10/2026.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
Direzione di ricerca
Il bug si trova nell'hookimpl pytest_exception_interact in src/_pytest/faulthandler.py (intorno alle righe 113-119), che annulla il timer di faulthandler sui normali fallimenti. Inizia leggendo quell'hook accanto a pytest_enter_pdb, che dovrebbe restare l'unico punto che annulla il timer per il debugger. È completato quando l'esempio minimo in tre file della issue scarica un traceback a 2 s ed esce, --pdb continua ad annullare il timer, e il parametro test_cancel_timeout_on_hook in testing/test_faulthandler.py è aggiornato, con un nuovo test pytester per un test fallito il cui teardown si blocca.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
- a detailed description of the bug or problem you are having
- output of
pip listfrom the virtual environment you are using - pytest and operating system versions
- minimal example if possible
Description
The docs say faulthandler_timeout "Dumps the tracebacks of all threads if a test takes longer than X seconds to run (including fixture setup and teardown)". In practice the timer is cancelled at the first failure in a test. Everything after that failure runs with no timeout: the fixture teardown and, with subtests, the rest of the test body. So when a fixture teardown hangs after a failed test, no traceback is printed. With faulthandler_exit_on_timeout = true the process also does not exit, although exiting on a hang in CI is the reason that option exists.
Cause (line numbers are from 9.1.1 and are unchanged on main):
src/_pytest/faulthandler.py:88-100:pytest_runtest_protocolarmsfaulthandler.dump_traceback_later()once per item and cancels it infinally.src/_pytest/faulthandler.py:113-119: the plugin also implementspytest_exception_interactand callsfaulthandler.cancel_dump_traceback_later()there.src/_pytest/runner.py:257-258:call_and_reportcallspytest_exception_interactfor every setup, call or teardown exception that passescheck_interactive_exception(runner.py:270-285). That covers every failure except a skip or an xfail, whether or not--pdbis given.src/_pytest/subtests.py:274-277andsrc/_pytest/unittest.py:464-467do the same for each failing subtest.
As a result, a hookimpl meant for the debugger also runs on every ordinary failure.
The debugger case does not need this hookimpl:
pytestPDB._init_pdbcallspytest_enter_pdb(src/_pytest/debugging.py:275), both for--pdbpost-mortem (debugging.py:400) and forbreakpoint()/set_trace(debugging.py:282).- The plugin already cancels the timer in its
pytest_enter_pdbhook (faulthandler.py:105-110).
The hookimpl came from pytest-faulthandler (pytest-dev/pytest-faulthandler#14, #15), which copied it from pytest-timeout, and it moved into core with #5441. pytest-timeout had the same bug (pytest-dev/pytest-timeout#196). It was fixed by deleting the pytest_exception_interact hookimpl and relying on pytest_enter_pdb (pytest-dev/pytest-timeout#197, released in 2.5).
Minimal example
pytest.ini:
[pytest]
faulthandler_timeout = 2
test_teardown_hang.py:
import time
import pytest
@pytest.fixture
def slow_teardown():
yield
time.sleep(6)
def test_fails_then_teardown_hangs(slow_teardown):
assert False
def test_passes_then_teardown_hangs(slow_teardown):
pass
test_setup_raises.py:
import time
import pytest
@pytest.fixture
def slow_teardown():
yield
time.sleep(6)
@pytest.fixture
def broken_setup(slow_teardown):
raise RuntimeError("setup failed")
def test_setup_raises_then_teardown_hangs(broken_setup):
pass
test_subtest_then_hang.py:
import time
def test_failing_subtest_then_body_hangs(subtests):
with subtests.test("first"):
assert False
time.sleep(6)
Each file was run on its own with pytest -p no:cacheprovider -q -o faulthandler_exit_on_timeout=true <target>:
| target | traceback dump | wall time |
|---|---|---|
test_passes_then_teardown_hangs |
yes, at 2 s, then exit | 2.2 s |
test_fails_then_teardown_hangs |
none | 6.2 s |
test_setup_raises.py |
none | 6.3 s |
test_subtest_then_hang.py |
none | 6.3 s |
The output of test_fails_then_teardown_hangs is just the failure. No Timeout (0:00:02)! appears, although the teardown ran for 6 s:
F [100%]
=================================== FAILURES ===================================
________________________ test_fails_then_teardown_hangs ________________________
...
E assert False
=========================== short test summary info ============================
FAILED test_teardown_hang.py::test_fails_then_teardown_hangs - assert False
1 failed in 6.01s
Expected: every row dumps the traceback at 2 s, which shows the sleeping frame in slow_teardown or in the test body, and then exits.
I deleted only the pytest_exception_interact hookimpl from src/_pytest/faulthandler.py and changed nothing else. With that change, all four rows dump at 2 s and exit at about 2.1 s. --pdb still cancels the timer: running test_fails_then_teardown_hangs with --pdb and waiting 3 s at the post-mortem prompt (past the 2 s timeout) before c produced no dump, the same as unpatched 9.1.1.
Suggested fix
- Delete the
pytest_exception_interacthookimpl fromsrc/_pytest/faulthandler.py. Timer cancellation for the debugger stays withpytest_enter_pdb. - In
testing/test_faulthandler.py, drop the"pytest_exception_interact"parameter fromtest_cancel_timeout_on_hook. - Add a pytester test in which a failing test's fixture teardown sleeps past
faulthandler_timeout, and assert*Timeout*on stderr.
Versions
- pytest 9.1.1. The same code is on
mainat c9c19f8 and has been since 5.0.0. - Python 3.14.8
- Ubuntu 26.04.1 LTS, Linux 7.0.0, x86_64
$ pip list
Package Version
--------- -------
iniconfig 2.3.1
packaging 26.3
pluggy 1.6.0
pygments 2.21.0
pytest 9.1.1
- Lingua principale
- Python
- Stelle
- 14.6k
- Fork
- 3.5k
- Merge medio
- 3g 18h
- PR unite (30g)
- 27
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di pytest-dev/pytest
-
Docs build fails with Pluggy 1.7.0 on an unresolved private DistFacade referenceForse già presa @Lothnic l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
pytest-dev/pytest#15190 ·
I maintainer di solito rispondono entro 1 giorno
-
Assertion diff doesn't pretty-print the built-in frozen dict (Python 3.15)Forse già presa @HakeemTheEmperor l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pytest-dev/pytest#15172 ·
I maintainer di solito rispondono entro 1 giorno
-
monkeypatch.setattr fails to undo on objects with a custom __setattr__ (regression from #14969)Forse già presa @hardikkaurani l’ha presa 21 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pytest-dev/pytest#15099 · 6 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Allow dotted test filenames (`*.test.py`) via one-line change to `compute_module_name`Forse di nuovo libera @siddy-stack l’ha presa 59 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
pytest-dev/pytest#14514 · 6 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Expose CaptureManager as public APIForse di nuovo libera @harsh21234i l’ha presa 197 giorni fa e non c’è nessuna pull request aperta. Apertatype: enhancement type: feature-branch
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
pytest-dev/pytest#14186 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di pytest-dev/pytest
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
huggingface/sentence-transformers#4186 ·
I maintainer di solito rispondono entro 5 giorni
-
documentation good first issue
Difficoltà 2/5 Mezza giornata Idoneità per principianti 72/100
sujithputta02/Esapay#13 ·
-
bot-triaged module: correctness (silent) module: mps module: NaNs and Infs triage review
Difficoltà 2/5 Mezza giornata Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
README: CI link/badge checkAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
SCIInstitute/SCIRun#2842 ·
I maintainer di solito rispondono entro 3 giorni