Skip to content

Use of warnings.catch_warnings resets the global warnings registry #2690

@dairiki

Description

@dairiki

There is a long-standing bug in Python python/cpython#73858 whereby any use of warnings.catch_warnings causes all memory of which warnings have already been displayed to be lost. So warnings whose action is configured as "default" (meaning show once for each module/line-number) get displayed multiple (possibly many, many) times.

Note that use of catch_warnings resets memory of what warnings have been displayed globally — use of catch_warnings by werkzeug can cause redisplay of unrelated warnings from other modules.

PR #2608 (19d55c1) introduced a lot of new uses of catch_warnings.

I'm not sure what the clean way is to work-around the issue, but it would be nice not to break the "default" warning action so drastically.

Example: too-verbose.py:

from werkzeug.urls import url_parse

for _ in range(10):
    url_parse("x")

Running

python too-verbose.py

will elicit 10 url_parse deprecation warnings. (The default warnings filter specifies an action of "default" for DeprecationWarnings, which means that they should be displayed just once per location.)

Environment:

  • Python version: I've tested under 3.9 and 3.11. I think it affects all 3.x pythons.
  • Werkzeug version: 2.3.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions