pytest-dev / pytest-dev/pytest
Shared `PytestWarning` instances in `deprecated.py` accumulate tracebacks under `-W error`
@RonnyPfannschmidt is already working on this.
Since Aug 19, 2026.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
src/_pytest/deprecated.py stores 11 deprecations as module-level instances (PRIVATE, CALLSPEC2_RENAMED, YIELD_FIXTURE, …) that call sites pass straight to warnings.warn(). When warnings are errors, warn raises that exact object, and CPython appends to an exception's existing __traceback__ instead of resetting it — so each raise grows the traceback of a process-lifetime global (measured 2 → 4 → 6 → 8 frames over four raises). Failure reports get corrupted: with two tests tripping the same deprecation, the second one's traceback carries 20+ stale frames from the first run and ends pointing at the other test's source line. The frames also pin their locals forever, and concurrent raises mutate shared __traceback__/__context__. The four UnformattedWarning constants are fine, since .format() returns a fresh instance. Fix: build a fresh instance per warn() — fold the 11 into UnformattedWarning (its format() works with no kwargs) or store text and pass warnings.warn(TEXT, Category) — and update the module docstring, which currently mandates the instance form.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.