Python - снова показывает "один раз" предупреждения (сброс всех предупреждающих реестров)

есть способ reset __warningregistry__ всех загруженных функций сразу?

Я хочу, чтобы все предупреждения, которые были отфильтрованы с помощью фильтра "один раз", отображались снова. Я не нашел способа сделать это, кроме вызова <func>.__globals__['__warningregistry__'].clear() для каждой загруженной функции (включая те, которые являются частью импортированного модуля.)

Итак, я хочу что-то вроде функции warnings.clear(), чтобы сделать следующее:

>>> import warnings
>>> warnings.warn('blah')
WARNING:root:blah ->UserWarning at ...
>>> warnings.warn('blah')
>>> warnings.clear()
>>> warnings.warn('blah')
WARNING:root:blah ->UserWarning at ...

И я хочу, чтобы эта функция warnings.clear() также очищала все реестры предупреждений, а не только текущее пространство имен.

Является ли это уже существующим? Возможно, я пропустил что-то очевидное или неправильно использовал модуль?

Ответ 1

Эта функция, как представляется, не существует в Python напрямую.

Тем не менее, мне нужна была аналогичная функциональность для unittests моих собственных библиотек, и работал менеджер контекста, который поддерживает состояние реестра предупреждения для всего процесса, очищает его, а затем восстанавливает его после завершения контекста.

Это слишком долго для публикации здесь, но я представил его как потенциальную отправную точку для решения ошибки python 21724, поэтому вы должны иметь возможность скачать и использовать его непосредственно из http://bugs.python.org/file40031/reset_warning_registry.py

Использование выглядит следующим образом:

from reset_warning_registry import reset_warning_registry

with reset_warning_registry():
    ... do things with clear registry ...

# alternately, to just clear the warnings w/o restoring
reset_warning_registry().__enter__()

Ответ 2

Я не считаю, что эта функциональность существует, по крайней мере, не в 2.7.6. Я просмотрел предупреждения .py и _warnings.c, и я не нашел ничего, что можно было бы использовать для этого.

Я думал, возможно, вы могли бы обернуть модуль и переопределить вызов warn(), чтобы поместить globals() ['__ warningregistry__'] в список и добавить новую функцию clear() для ее цикла и reset реестра для всех вызовов.