Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - showing 'once' warnings again (resetting all warning registries)

is there a way to reset the __warningregistry__ of all loaded functions at once?

I would like to force all warnings that are filtered with the 'once' filter to show again. I have found no way of doing this aside from calling <func>.__globals__['__warningregistry__'].clear() on every function that I have loaded (including those that are part of an imported module.)

So, what I want is something like a warnings.clear() function to do the following:

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

And I want this warnings.clear() function to also clear all warning registries, not just the current name-space.

Is this already existent? Perhaps I'm missing something obvious, or using the module incorrectly?

like image 434
Robert Muil Avatar asked Oct 17 '13 13:10

Robert Muil


2 Answers

That functionality doesn't appear to exist in Python directly.

However, I needed similar functionality for my own libraries' unittests, and worked up a context manager that backs up the warning registry state for the entire process, clears it, and then restores it after the context is done.

It's a little too long to post here, but I've submitted it as a potential starting point for solving python bug 21724, so you should be able to download and use it directly from http://bugs.python.org/file40031/reset_warning_registry.py

Usage is as follows:

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__()
like image 196
Eli Collins Avatar answered Nov 11 '22 15:11

Eli Collins


I don't believe this functionality exists, at least not in 2.7.6. I looked through the warnings.py and _warnings.c and I didn't find anything you could use to do this.

I was thinking perhaps you could wrap the module and override the warn() call to put globals()['__warningregistry__'] in a list, and add a new clear() function to loop it and reset the registry for all calls.

like image 33
woot Avatar answered Nov 11 '22 17:11

woot