diff --git a/src/_pytest/main.py b/src/_pytest/main.py index d9ecd3974..e6256fae7 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -6,6 +6,7 @@ import functools import importlib import os import sys +import warnings from pathlib import Path from typing import AbstractSet from typing import Callable @@ -44,6 +45,7 @@ from _pytest.reports import CollectReport from _pytest.reports import TestReport from _pytest.runner import collect_one_node from _pytest.runner import SetupState +from _pytest.warning_types import PytestWarning def pytest_addoption(parser: Parser) -> None: @@ -584,6 +586,12 @@ class Session(nodes.Collector): def shouldstop(self, value: Union[bool, str]) -> None: """Prevent plugins from setting this to False once it has been set.""" if value is False and self._shouldstop: + warnings.warn( + PytestWarning( + "session.shouldstop cannot be unset after it has been set; ignoring." + ), + stacklevel=2, + ) return self._shouldstop = value @@ -595,6 +603,12 @@ class Session(nodes.Collector): def shouldfail(self, value: Union[bool, str]) -> None: """Prevent plugins from setting this to False once it has been set.""" if value is False and self._shouldfail: + warnings.warn( + PytestWarning( + "session.shouldfail cannot be unset after it has been set; ignoring." + ), + stacklevel=2, + ) return self._shouldfail = value diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 7ecc5bbeb..3e19f0de5 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -131,12 +131,10 @@ def runtestprotocol( show_test_item(item) if not item.config.getoption("setuponly", False): reports.append(call_and_report(item, "call", log)) - # If the session is about to fail or stop, teardown everything - this is # necessary to correctly report fixture teardown errors (see #11706) if item.session.shouldfail or item.session.shouldstop: nextitem = None - reports.append(call_and_report(item, "teardown", log, nextitem=nextitem)) # After all teardown hooks have been called # want funcargs and request info to go away. diff --git a/testing/test_session.py b/testing/test_session.py index 136e85eb6..1ac39f2ef 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -418,3 +418,27 @@ def test_rootdir_wrong_option_arg(pytester: Pytester) -> None: result.stderr.fnmatch_lines( ["*Directory *wrong_dir* not found. Check your '--rootdir' option.*"] ) + + +def test_shouldfail_is_sticky(pytester: Pytester) -> None: + """Test that session.shouldfail cannot be reset to False after being set.""" + pytester.makeconftest( + """ + def pytest_sessionfinish(session, exitstatus): + session.shouldfail = False + """ + ) + + pytester.makepyfile( + """ + import pytest + + def test_foo(): + pytest.fail("This is a failing test") + + def test_bar(): + pass + """ + ) + result = pytester.runpytest("--maxfail=1") + result.stderr.fnmatch_lines("*session.shouldfail cannot be unset*")