Extending Python: exception handling

Skip Montanaro skip at mojam.com
Tue Aug 24 19:07:21 CEST 1999


I wrote:

    >It makes a reasonable substitute for the lack of labelled break
    >statements on certain occasions.
    >
    >    class BreakLabel: pass
    >    try:
    >	    for i in ...:
    >	       for j in ...:
    >		   exit_cond = do_some_work()
    >	 	   if exit_cond: raise BreakLabel
    >    except BreakLabel:
    >	    pass

to which John replied:

    Two questions:

	    1) would you always use a user defined exception?
	    2) What if you had labelled breaks?

    Reason: suppose I implement labelled statements in Viper,
    and suppose I assume that system exceptions (Attribute
    errors, etc) are program faults -- would all your code work?

1. Since I'm not catching errors and I might want to have multiple "break
   labels", yes I would always use a user-defined exception.

2. If I had labelled breaks I'd use 'em.  I'm obviously overloading
   exceptions because I don't have break labels.  I find the above a bit
   clearer than keeping track of where I'm going with extra state variables
   however.

Yes, my code would work.  I try to use the system's builtin exceptions as
they were intended - to catch problems.

Later on, John wrote:

	    try:
		    y = sqrt(x)
	    except:
		    y = x.sqrt()

    Here, the programmer is assuming that if the builtin sqrt function
    defined for floats fails, the object might be a class emulating numbers,
    and try to call a sqrt method.  But the Viper compiler might _know_ that
    x is a class instance and that the builtin function 'sqrt' only applies
    to floats, and report an error.

    Even worse, it might _deduce_ that x must be a float, and then get
    confused seeing x.sqrt(), which might require that x is an instance
    (depending on whether sqrt is a method of floats or not).

Then you're programming in a language other than Python.  If you can
reasonably determine that x is an instance and not a float, I'd expect the
compiler to generate the equivalent of simply

    y = x.sqrt()

if you know that executing the try block will always fail.

If you can deduce it's a float I'd expect it to generate the equivalent of
the above try/except statement, since the programmer didn't qualify the
except clause.  You could get either an AttributeError or an OverflowError
from sqrt.  If it had been:

    try:
	y = sqrt(x)
    except AttributeError:
	y = x.sqrt()

then you could generate just

    y = sqrt(x)

when x is a float, because an AttributeError can't occur.  (Python currently
raises an AttributeError if an instance doesn't have a __float__ method.)

Further down:

    The basic problem is that in the presence of dynamic typing and
    exception handling, type inference is hard, especially because handlers
    for exceptions can be lexically isolated from the point the exception is
    raised: with a _complete_ flow analysis, the type inference system
    wouldn't work in all cases. [and maybe not even then]

Yup.  You aren't going to be able to do much other than perhaps spit out a
warning to the programmer that no optimization is being performed because
the except clause is unqualified.

Skip Montanaro | http://www.mojam.com/
skip at mojam.com | http://www.musi-cal.com/~skip/
847-971-7098   | Python: Programming the way Guido indented...




More information about the Python-list mailing list