From f4897e825b0a418861f8abaccd14cddcd59e748a Mon Sep 17 00:00:00 2001 From: ace2016 <23010364+ace2016@users.noreply.github.com> Date: Fri, 24 Jul 2026 23:22:36 +0100 Subject: [PATCH] Avoid traceback formatting for xfail(run=False) Co-authored-by: Codex --- AUTHORS | 1 + changelog/9436.improvement.rst | 1 + src/_pytest/skipping.py | 4 ++-- testing/test_skipping.py | 27 +++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 changelog/9436.improvement.rst diff --git a/AUTHORS b/AUTHORS index 229e4315078..8d9d001bd1d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,6 +7,7 @@ Aaron Coleman Abdeali JK Abdelrahman Elbehery Abhijeet Kasurde +ace2016 Adam Johnson Adam Stewart Adam Uhlir diff --git a/changelog/9436.improvement.rst b/changelog/9436.improvement.rst new file mode 100644 index 00000000000..906edd9775c --- /dev/null +++ b/changelog/9436.improvement.rst @@ -0,0 +1 @@ +Avoided formatting tracebacks for tests marked with ``xfail(run=False)``. diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index f7a4c4c04e3..aa97e3b7dc6 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -252,7 +252,7 @@ def pytest_runtest_setup(item: Item) -> None: item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) if xfailed and not item.config.option.runxfail and not xfailed.run: - xfail("[NOTRUN] " + xfailed.reason) + raise xfail.Exception("[NOTRUN] " + xfailed.reason, pytrace=False) @hookimpl(wrapper=True) @@ -262,7 +262,7 @@ def pytest_runtest_call(item: Item) -> Generator[None]: item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) if xfailed and not item.config.option.runxfail and not xfailed.run: - xfail("[NOTRUN] " + xfailed.reason) + raise xfail.Exception("[NOTRUN] " + xfailed.reason, pytrace=False) try: return (yield) diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 5bb641aed3c..9335f6db58c 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -3,6 +3,7 @@ import textwrap +from _pytest._code import ExceptionInfo from _pytest.pytester import Pytester from _pytest.runner import runtestprotocol from _pytest.skipping import evaluate_skip_marks @@ -453,6 +454,32 @@ def test_this_false(): ] ) + def test_xfail_not_run_does_not_format_traceback( + self, pytester: Pytester, monkeypatch: pytest.MonkeyPatch + ) -> None: + item = pytester.getitem( + """ + import pytest + + @pytest.mark.xfail(run=False, reason="noway") + def test_func(): + assert 0 + """ + ) + getrepr = ExceptionInfo.getrepr + styles = [] + + def spy_getrepr(self, *args, **kwargs): + styles.append(kwargs["style"]) + return getrepr(self, *args, **kwargs) + + monkeypatch.setattr(ExceptionInfo, "getrepr", spy_getrepr) + + reports = runtestprotocol(item, log=False) + + assert reports[0].skipped + assert styles == ["value"] + def test_xfail_not_run_no_setup_run(self, pytester: Pytester) -> None: p = pytester.makepyfile( test_one="""