pytest-dev / pytest-dev/pytest

Shared `PytestWarning` instances in `deprecated.py` accumulate tracebacks under `-W error`

Open
#14,912 0 comments 0 reactions 1 assignee View on GitHub

@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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.