Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Changelog
16.2 (unreleased)
-----------------

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


16.1 (2025-10-10)
Expand Down
6 changes: 3 additions & 3 deletions src/pytest_rerunfailures.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ def _remove_failed_setup_state_from_session(item):
"""
Clean up setup state.

Note: remove all failures from every node in _setupstate stack
and clean the stack itself
Note: remove only the current item, not higher-scoped items
"""
setup_state = item.session._setupstate
setup_state.stack = {}
if item in setup_state.stack:
del setup_state.stack[item]


def _get_rerun_filter_regex(item, regex_name):
Expand Down
34 changes: 34 additions & 0 deletions tests/test_pytest_rerunfailures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,40 @@ def test_2():
assert_outcomes(result, failed=8, passed=2, rerun=18, skipped=5, error=1)


def test_run_session_teardown_when_fixture_teardown_fails(testdir):
testdir.makepyfile(
"""
import pytest

@pytest.fixture(scope='session', autouse=True)
def session_fixture():
yield
print('session teardown')

@pytest.fixture(scope='module', autouse=True)
def module_fixture():
yield
print('module teardown')

@pytest.fixture
def broken_fixture():
yield
raise Exception("fixture teardown error")

def test_fail_in_fixture(broken_fixture):
pass

def test_ok():
pass
"""
)

result = testdir.runpytest("--reruns", "1", "-s")
result.stdout.fnmatch_lines("*session teardown*")
result.stdout.fnmatch_lines("*module teardown*")
assert_outcomes(result, passed=3, rerun=1, error=1)


def test_exception_matches_rerun_except_query(testdir):
testdir.makepyfile(
"""
Expand Down