Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`faulthandler_timeout` stops covering a test once setup, call or a subtest fails (`pytest_exception_interact` cancels the timer)

Aperta Adatta ai principianti
#15,180 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@XXXXXQ-0206 ci sta già lavorando.

Dal 15/10/2026.

  • #15181 di @jipeng6036-del — chiusa senza merge
  • #15184 di @inchang-ing — chiusa senza merge
  • #15185 di @XXXXXQ-0206 — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
testing

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 list from 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_protocol arms faulthandler.dump_traceback_later() once per item and cancels it in finally.
  • src/_pytest/faulthandler.py:113-119: the plugin also implements pytest_exception_interact and calls faulthandler.cancel_dump_traceback_later() there.
  • src/_pytest/runner.py:257-258: call_and_report calls pytest_exception_interact for every setup, call or teardown exception that passes check_interactive_exception (runner.py:270-285). That covers every failure except a skip or an xfail, whether or not --pdb is given. src/_pytest/subtests.py:274-277 and src/_pytest/unittest.py:464-467 do 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_pdb calls pytest_enter_pdb (src/_pytest/debugging.py:275), both for --pdb post-mortem (debugging.py:400) and for breakpoint()/set_trace (debugging.py:282).
  • The plugin already cancels the timer in its pytest_enter_pdb hook (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_interact hookimpl from src/_pytest/faulthandler.py. Timer cancellation for the debugger stays with pytest_enter_pdb.
  • In testing/test_faulthandler.py, drop the "pytest_exception_interact" parameter from test_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 main at 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

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di pytest-dev/pytest

Tutte le issue di pytest-dev/pytest

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.