warnings filters for varying message
Peter Otten
__peter__ at web.de
Fri Jun 28 04:57:24 EDT 2013
John Reid wrote:
> Looking at the docs for warnings.simplefilter
> (http://docs.python.org/2/library/warnings.html) I think the following
> script should only produce one warning at each line as any message is
> matched by the simple filter
>
> import warnings
> warnings.simplefilter('default')
> for i in xrange(2):
> warnings.warn('Warning message') # This prints 1 warning
> warnings.warn("Warning %d" % i) # This prints 2 warnings
>
> What do I need to do to get the warnings module just to print one
> warning for the second warnings.warn line?
$ cat warn_once_orig.py
import warnings
for i in xrange(2):
warnings.warn('Warning message')
warnings.warn("Warning %d" % i)
$ python -i warn_once_orig.py
warn_once_orig.py:4: UserWarning: Warning message
warnings.warn('Warning message')
warn_once_orig.py:5: UserWarning: Warning 0
warnings.warn("Warning %d" % i)
warn_once_orig.py:5: UserWarning: Warning 1
warnings.warn("Warning %d" % i)
>>> __warningregistry__
{('Warning message', <type 'exceptions.UserWarning'>, 4): True, ('Warning
0', <type 'exceptions.UserWarning'>, 5): True, ('Warning 1', <type
'exceptions.UserWarning'>, 5): True}
As you can see the message is part of the key that determines the identity
of a warning. At first glance I see no official way to defeat that, so
here's a quick hack:
$ cat warn_once.py
import warnings
class WarningMessage(str):
def __hash__(self):
return 0
def __eq__(self, other):
return isinstance(other, str)
for i in xrange(2):
warnings.warn('Warning message')
warnings.warn(WarningMessage("Warning %d" % i))
$ python warn_once.py
warn_once.py:10: UserWarning: Warning message
warnings.warn('Warning message')
warn_once.py:11: UserWarning: Warning 0
warnings.warn(WarningMessage("Warning %d" % i))
More information about the Python-list
mailing list