Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto Apto para principiantes
#15,180 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@XXXXXQ-0206 ya está trabajando en esto.

Desde el 15/10/2026.

  • #15181 de @jipeng6036-del — cerrado sin fusionar
  • #15184 de @inchang-ing — cerrado sin fusionar
  • #15185 de @XXXXXQ-0206 — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
testing

Línea de trabajo

El error está en el hookimpl pytest_exception_interact de src/_pytest/faulthandler.py (alrededor de las líneas 113-119), que cancela el temporizador de faulthandler en fallos ordinarios. Empieza leyendo ese hook junto a pytest_enter_pdb, que debe seguir siendo el único lugar que cancela el temporizador para el depurador. Está terminado cuando el ejemplo mínimo de tres archivos del issue vuelca un traceback a los 2 s y sale, --pdb sigue cancelando el temporizador, y se actualiza el parámetro test_cancel_timeout_on_hook en testing/test_faulthandler.py, con una nueva prueba de pytester para un test fallido cuyo teardown se cuelga.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

  • 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
Lenguaje dominante
Python
Estrellas
14.6k
Forks
3.5k
Merge medio
3 d 18 h
PR fusionados (30 d)
27

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de pytest-dev/pytest

Todos los issues de pytest-dev/pytest

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.