diff --git a/AUTHORS b/AUTHORS index 1d1af001595..0860485c9f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -261,6 +261,7 @@ Junhao Liao Jurko Gospodnetić Justice Ndou Justyna Janczyszyn +jwalith4418-Mj Kale Kundert Kamran Ahmad Kenny Y diff --git a/changelog/7692.bugfix.rst b/changelog/7692.bugfix.rst new file mode 100644 index 00000000000..192f24058a9 --- /dev/null +++ b/changelog/7692.bugfix.rst @@ -0,0 +1 @@ +Custom test items now respect ``__tracebackhide__`` when reporting failures, unless ``--full-trace`` is used. diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 2b510907122..19c1e98b490 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -424,7 +424,7 @@ def getparent(self, cls: type[_NodeType]) -> _NodeType | None: return None def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback: - return excinfo.traceback + return excinfo.traceback.filter(excinfo) def _repr_failure_py( self, diff --git a/testing/test_nodes.py b/testing/test_nodes.py index e976b9e6f11..5bf56794824 100644 --- a/testing/test_nodes.py +++ b/testing/test_nodes.py @@ -162,3 +162,43 @@ def test_show_wrong_path(private_dir): ) result = pytester.runpytest() result.stdout.fnmatch_lines([str(p) + ":*: AssertionError", "*1 failed in *"]) + + +@pytest.mark.parametrize("fulltrace", [False, True]) +@pytest.mark.parametrize( + "failure", ["raise ValueError('custom failure')", "pytest.fail('custom failure')"] +) +def test_custom_item_hidden_traceback( + pytester: Pytester, fulltrace: bool, failure: str +) -> None: + pytester.makeconftest( + f""" + import pytest + + def hidden_helper(): + __tracebackhide__ = True + {failure} + + class CustomItem(pytest.Item): + def runtest(self): + hidden_helper() + + class CustomFile(pytest.File): + def collect(self): + yield CustomItem.from_parent(self, name="custom") + + def pytest_collect_file(file_path, parent): + if file_path.suffix == ".custom": + return CustomFile.from_parent(parent, path=file_path) + """ + ) + pytester.makefile(".custom", test_custom="") + args = ["--tb=long"] + if fulltrace: + args.append("--full-trace") + result = pytester.runpytest(*args) + result.assert_outcomes(failed=1) + output = result.stdout.str() + assert "custom failure" in output + assert "def runtest(self):" in output + assert ("__tracebackhide__ = True" in output) == fulltrace