|
17 | 17 | import time as time_module |
18 | 18 | from functools import wraps |
19 | 19 | from pathlib import Path |
| 20 | +from types import TracebackType |
20 | 21 |
|
21 | 22 | import pytest |
| 23 | +from _pytest._code.code import Traceback |
22 | 24 | from _pytest.monkeypatch import MonkeyPatch |
23 | 25 |
|
24 | 26 | from hypothesis import is_hypothesis_test, settings |
@@ -210,6 +212,28 @@ def _unfreezer(*_): |
210 | 212 | independent_random = random.Random() |
211 | 213 |
|
212 | 214 |
|
| 215 | +@pytest.hookimpl(hookwrapper=True) |
| 216 | +def pytest_runtest_makereport(item, call): |
| 217 | + # We run CI with --tb=native, which (unlike pytest's own styles) doesn't |
| 218 | + # filter out the dozens of pluggy/_pytest hook frames above the test, so |
| 219 | + # every failure is buried in noise. Re-apply pytest's filtering by |
| 220 | + # rebuilding the traceback from just the frames it would have kept. |
| 221 | + excinfo = call.excinfo |
| 222 | + if ( |
| 223 | + excinfo is not None |
| 224 | + and item.config.option.tbstyle == "native" |
| 225 | + and hasattr(item, "_traceback_filter") |
| 226 | + ): |
| 227 | + new_tb = None |
| 228 | + for entry in reversed(list(item._traceback_filter(excinfo))): |
| 229 | + raw = entry._rawentry |
| 230 | + new_tb = TracebackType(new_tb, raw.tb_frame, raw.tb_lasti, raw.tb_lineno) |
| 231 | + if new_tb is not None: |
| 232 | + excinfo.value.__traceback__ = new_tb |
| 233 | + excinfo.traceback = Traceback(new_tb) |
| 234 | + yield |
| 235 | + |
| 236 | + |
213 | 237 | @pytest.hookimpl(hookwrapper=True) |
214 | 238 | def pytest_runtest_call(item): |
215 | 239 | if item.config.getoption("--hypothesis-benchmark-shrinks"): |
|
0 commit comments