[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