Skip to content

Issue a fresh PytestWarning instance per warn() call - #15095

Closed
Dextheking1 wants to merge 1 commit into
pytest-dev:mainfrom
Dextheking1:fix/14912-pytestwarning-fresh-instance
Closed

Dextheking1 wants to merge 1 commit into
pytest-dev:mainfrom
Dextheking1:fix/14912-pytestwarning-fresh-instance

Conversation

@Dextheking1

@Dextheking1 Dextheking1 commented Sep 23, 2026 •

Copy link
Copy Markdown

Fixes #14912.

src/_pytest/deprecated.py stored deprecations as module-level PytestWarning
instances that call sites passed 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
grew the traceback of a process-lifetime global (measured 2 → 4 → 6 → 8 frames
over four raises). With two tests tripping the same deprecation, the second
report carried 20+ stale frames from the first run.

All 12 plain-instance constants are now UnformattedWarning, formatted into a
fresh instance at each warn site (the 4 existing UnformattedWarning constants
were already fine). The module docstring now documents the invariant.

Tests: added test_deprecation_constants_are_not_shared_instances (structural
guard over every constant in the module) and
test_deprecation_warning_traceback_does_not_accumulate_under_error (raises the
same deprecation 3x under -W error, asserts stable frame counts) in
testing/deprecated_test.py. Both fail on pristine code, pass with the fix.
testing/deprecated_test.py, testing/test_warnings.py,
testing/test_warning_types.py (105 passed, 4 skipped),
testing/test_pastebin.py + testing/test_monkeypatch.py (54 passed, 1 skipped)
all green locally.

Convert the module-level deprecation constants in _pytest.deprecated
from shared PytestWarning instances to UnformattedWarning, formatted
into a fresh instance at each warn site. Reusing the same instance
across warnings.warn() calls made CPython append to the instance's
existing __traceback__ on every raise under -W error, corrupting
failure reports with stale frames from previous raises. Fixes pytest-dev#14912.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants