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)) -- http://mail.python.org/mailman/listinfo/python-list