[SciPy-dev] How to handle exceptional cases in algorithms ? Exception vs Warning
Robert Kern
robert.kern at gmail.com
Mon Jun 4 15:21:50 EDT 2007
Anne Archibald wrote:
> Just a, uh, warning: I found that it was very difficult to make the
> warnings module do what it was documented to do in terms of throwing
> exceptions and warning the right number of times.
Can you give an example? I thought it was fairly straightforward. The only
niggle is interactive use. After the first time a warning is issued (and not
raised as an error), the warning, including its message and the location in the
file, is stored in a registry in the module containing the warn() call.
Consequently, if you run interactively, see a warnings, set a filter to raise an
exception instead of printing the warning, then try the bad function again, you
don't get an exception.
In [1]: !cat warntest.py
IPython system call: cat warntest.py
import warnings
class MyWarning(UserWarning):
pass
def does_warn():
warnings.warn("Stuff", MyWarning)
In [2]: import warntest, warnings
In [3]: warntest.does_warn()
warntest.py:7: MyWarning: Stuff
warnings.warn("Stuff", MyWarning)
In [4]: warntest.does_warn()
In [5]: warnings.simplefilter('error', warntest.MyWarning)
In [6]: warntest.does_warn()
In [7]: warntest.__warningregistry__
Out[7]: {('Stuff', <class 'warntest.MyWarning'>, 7): 1}
In [8]: del warntest.__warningregistry__
In [9]: warntest.does_warn()
---------------------------------------------------------------------------
<class 'warntest.MyWarning'> Traceback (most recent call last)
/Users/rkern/hg/warntest/<ipython console> in <module>()
/Users/rkern/hg/warntest/warntest.py in does_warn()
3 class MyWarning(UserWarning):
4 pass
5
6 def does_warn():
----> 7 warnings.warn("Stuff", MyWarning)
/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/warnings.py in
warn(message, category, stacklevel)
60 registry = globals.setdefault("__warningregistry__", {})
61 warn_explicit(message, category, filename, lineno, module, registry,
---> 62 globals)
63
64 def warn_explicit(message, category, filename, lineno,
/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/warnings.py in
warn_explicit(message, category, filename, lineno, module, registry, module_globals)
100
101 if action == "error":
--> 102 raise message
103 # Other actions
104 if action == "once":
<class 'warntest.MyWarning'>: Stuff
Now, I don't like this behavior, certainly. I would like the registry to be
checked only if there isn't an 'error' filter. Nonetheless, I think the warnings
module should be used. Attaching additional information to an object is a good
idea if you have an object to hang stuff on. However, I think this should be in
addition to issuing a warning with warnings.warn().
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the SciPy-Dev
mailing list