diff --git a/changelog/13917.bugfix.rst b/changelog/13917.bugfix.rst new file mode 100644 index 00000000000..d2cf90c2894 --- /dev/null +++ b/changelog/13917.bugfix.rst @@ -0,0 +1 @@ +:class:`unittest.SkipTest` is no longer considered an interactive exception, i.e. :hook:`pytest_exception_interact` is no longer called for it. diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index de1b2688f76..2ee540cc996 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -11,7 +11,6 @@ import sys import types from typing import Any -import unittest from _pytest import outcomes from _pytest._code import ExceptionInfo @@ -295,9 +294,7 @@ def pytest_exception_interact( sys.stdout.write(out) sys.stdout.write(err) assert call.excinfo is not None - - if not isinstance(call.excinfo.value, unittest.SkipTest): - _enter_pdb(node, call.excinfo, report) + _enter_pdb(node, call.excinfo, report) def pytest_internalerror(self, excinfo: ExceptionInfo[BaseException]) -> None: exc_or_tb = _postmortem_exc_or_tb(excinfo) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 9c20ff9e638..d1090aace89 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -271,7 +271,10 @@ def check_interactive_exception(call: CallInfo[object], report: BaseReport) -> b if hasattr(report, "wasxfail"): # Exception was expected. return False - if isinstance(call.excinfo.value, Skipped | bdb.BdbQuit): + unittest = sys.modules.get("unittest") + if isinstance(call.excinfo.value, Skipped | bdb.BdbQuit) or ( + unittest is not None and isinstance(call.excinfo.value, unittest.SkipTest) + ): # Special control flow exception. return False return True