From 99b2d79602180c1df1383e6af4fd9bd3e7e36aad Mon Sep 17 00:00:00 2001 From: John Litborn <11260241+jakkdl@users.noreply.github.com> Date: Fri, 12 Dec 2025 16:15:44 +0100 Subject: [PATCH] don't crash if exceptiongroup has only hidden tb frames (#14025) * don't crash if exceptiongroup has only hidden tb frames (cherry picked from commit fa6a232d529b33f6388dc788d7613cf206c08130) --- changelog/13734.bugfix.rst | 1 + src/_pytest/_code/code.py | 8 +++++++- testing/code/test_excinfo.py | 12 ++++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 changelog/13734.bugfix.rst diff --git a/changelog/13734.bugfix.rst b/changelog/13734.bugfix.rst new file mode 100644 index 00000000000..de1d7368cd4 --- /dev/null +++ b/changelog/13734.bugfix.rst @@ -0,0 +1 @@ +Fixed crash when a test raises an exceptiongroup with ``__tracebackhide__ = True``. diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index add2a493ca7..4cf99a77340 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -1193,9 +1193,15 @@ def repr_excinfo(self, excinfo: ExceptionInfo[BaseException]) -> ExceptionChainR format_exception( type(excinfo.value), excinfo.value, - traceback[0]._rawentry, + traceback[0]._rawentry if traceback else None, ) ) + if not traceback: + reprtraceback.extraline = ( + "All traceback entries are hidden. " + "Pass `--full-trace` to see hidden and internal frames." + ) + else: reprtraceback = self.repr_traceback(excinfo_) reprcrash = excinfo_._getreprcrash() diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 476720f0bbe..70499fec893 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -1897,19 +1897,23 @@ def test_nested_multiple() -> None: @pytest.mark.parametrize("tbstyle", ("long", "short", "auto", "line", "native")) -def test_all_entries_hidden(pytester: Pytester, tbstyle: str) -> None: +@pytest.mark.parametrize("group", (True, False), ids=("group", "bare")) +def test_all_entries_hidden(pytester: Pytester, tbstyle: str, group: bool) -> None: """Regression test for #10903.""" pytester.makepyfile( - """ + f""" + import sys + if sys.version_info < (3, 11): + from exceptiongroup import ExceptionGroup def test(): __tracebackhide__ = True - 1 / 0 + raise {'ExceptionGroup("", [ValueError("bar")])' if group else 'ValueError("bar")'} """ ) result = pytester.runpytest("--tb", tbstyle) assert result.ret == 1 if tbstyle != "line": - result.stdout.fnmatch_lines(["*ZeroDivisionError: division by zero"]) + result.stdout.fnmatch_lines(["*ValueError: bar"]) if tbstyle not in ("line", "native"): result.stdout.fnmatch_lines(["All traceback entries are hidden.*"])