Skip to content

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

Description

@graingert

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.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions