Skip to content

Commit d9ef70e

Browse files
Preserve session and module teardown when fixture teardown fails (#319)
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
1 parent a22edc3 commit d9ef70e

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

CHANGES.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Changelog
44
16.2 (unreleased)
55
-----------------
66

7-
- Nothing changed yet.
7+
- Fix missing teardown for session and module scoped fixtures when fixture teardown fails.
8+
Fixes `#314 <https://github.com/pytest-dev/pytest-rerunfailures/issues/314>`_.
89

910

1011
16.1 (2025-10-10)

src/pytest_rerunfailures.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,11 @@ def _remove_failed_setup_state_from_session(item):
250250
"""
251251
Clean up setup state.
252252
253-
Note: remove all failures from every node in _setupstate stack
254-
and clean the stack itself
253+
Note: remove only the current item, not higher-scoped items
255254
"""
256255
setup_state = item.session._setupstate
257-
setup_state.stack = {}
256+
if item in setup_state.stack:
257+
del setup_state.stack[item]
258258

259259

260260
def _get_rerun_filter_regex(item, regex_name):

tests/test_pytest_rerunfailures.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,40 @@ def test_2():
11701170
assert_outcomes(result, failed=8, passed=2, rerun=18, skipped=5, error=1)
11711171

11721172

1173+
def test_run_session_teardown_when_fixture_teardown_fails(testdir):
1174+
testdir.makepyfile(
1175+
"""
1176+
import pytest
1177+
1178+
@pytest.fixture(scope='session', autouse=True)
1179+
def session_fixture():
1180+
yield
1181+
print('session teardown')
1182+
1183+
@pytest.fixture(scope='module', autouse=True)
1184+
def module_fixture():
1185+
yield
1186+
print('module teardown')
1187+
1188+
@pytest.fixture
1189+
def broken_fixture():
1190+
yield
1191+
raise Exception("fixture teardown error")
1192+
1193+
def test_fail_in_fixture(broken_fixture):
1194+
pass
1195+
1196+
def test_ok():
1197+
pass
1198+
"""
1199+
)
1200+
1201+
result = testdir.runpytest("--reruns", "1", "-s")
1202+
result.stdout.fnmatch_lines("*session teardown*")
1203+
result.stdout.fnmatch_lines("*module teardown*")
1204+
assert_outcomes(result, passed=3, rerun=1, error=1)
1205+
1206+
11731207
def test_exception_matches_rerun_except_query(testdir):
11741208
testdir.makepyfile(
11751209
"""

0 commit comments

Comments
 (0)