Fix session-end gc in unraisableexception plugin to respect warning filters by coder-jatin-s · Pull Request #14273 · pytest-dev/pytest

Fixes ordering between the unraisableexception and warnings plugins so session-end gc.collect() runs while warning filters are still active.

Fix #14263

Previously, the unraisableexception plugin registered a config.add_cleanup() callback that runs several gc.collect() rounds at session end. Because config.add_cleanup() uses a LIFO ExitStack, and the warnings plugin registers its cleanup after unraisableexception in default_plugins, the order at session teardown was:

  1. warnings cleanup: tears down its catch_warnings context, so filterwarnings = error::ResourceWarning from pytest.ini stops applying.
  2. unraisableexception cleanup: runs gc.collect(), finalizing unclosed resources whose __del__ emits ResourceWarning.

Those ResourceWarnings were no longer affected by the configured warning filters and could be silently discarded instead of being turned into errors or reported via sys.unraisablehook.

Implementation

  • Added pytest_unconfigure in unraisableexception to:
    • Run gc_collect_harder(...) for the configured number of iterations.
    • Call collect_unraisable(config) to process any unraisable exceptions.
  • Simplified the cleanup callback to:
    • Only restore sys.unraisablehook to the previous hook.
    • Clear the unraisable_exceptions stash entry.

Because pytest_unconfigure runs before Config._cleanup_stack.close(),
the final gc.collect() calls now happen while the warnings plugin's filters
(from filterwarnings / -W) are still active.

Testing

  • Existing testing/test_unraisableexception.py tests.
  • Existing testing/test_warnings.py tests.
  • Manual check that filterwarnings = error::ResourceWarning now causes
    leaked resources finalized at session end to be treated as errors.