Python Mystery Theatre -- Episode 1: Exceptions

Jack Diederich jack at performancedrivers.com
Sat Jul 12 05:19:05 EDT 2003


On Sat, Jul 12, 2003 at 06:56:52AM +0000, Raymond Hettinger wrote:

Since you included the answers I was really unsuprised by what happened,
but maybe I'm wrong as to the why (no other posts, docs, or searching read
for my explanations).

> ACT I ---------------------------------------
> >>> s = list('abc')
> >>> try:
> ...     result = s['a']
> ... except IndexError, TypeError:
> ...     print 'Not found'
> ...
> 
> Traceback (most recent call last):
>   File "<pyshell#11>", line 2, in -toplevel-
>     result = s['a']
> TypeError: list indices must be integers

A TypeError was thrown, but writing this as
except (IndexError,), type_error:
explains why it wasn't caught.

> ACT II --------------------------------------------
> >>> class MyMistake(Exception):
> ...     pass
> 
> >>> try:
> ...     raise MyMistake, 'try, try again'
> ... except MyMistake, msg:
> ...     print type(msg)
> ...
> 
> <type 'instance'>

type() of most any (new style?) object will print this

> ACT III --------------------------------------------
> >>> class Prohibited(Exception):
> ...     def __init__(self):
> ...         print 'This class of should never get initialized'
> ...
> >>> raise Prohibited()
> This class of should never get initialized
> 
> Traceback (most recent call last):
>   File "<pyshell#40>", line 1, in -toplevel-
>     raise Prohibited()
> Prohibited: <unprintable instance object>
> >>> raise Prohibited
> This class of should never get initialized
> 
> Traceback (most recent call last):
>   File "<pyshell#41>", line 1, in -toplevel-
>     raise Prohibited
> Prohibited: <unprintable instance object>

This one is new to me, FWIW I write two kinds of exceptions,
one that is just defined as MyGuy(Excption):pass and another
where I define both __init__ and __repr__ to print what I want.

> ACT IV -----------------------------------------------
> >>> module = 'Root'
> >>> try:
> ...     raise module + 'Error'
> ... except 'LeafError':
> ...     print 'Need leaves'
> ... except 'RootError':
> ...     print 'Need soil'
> ... except:
> ...     print 'Not sure what is needed'
> ...
> 
> Not sure what is needed

There is a reason string exceptions are deprecated ;)
the string 'RootError' is not a subclass of the string 'RootError'
and thus won't be caught.

> 
> ACT V -----------------------------------------------
> >>> try:
> ...     raise KeyError('Cannot find key')
> ... except LookupError, msg:
> ...     print 'Lookup:', msg
> ... except OverflowError, msg:
> ...     print 'Overflow:', msg
> ... except KeyError, msg:
> ...     print 'Key:', msg
> 
> 
> Lookup: 'Cannot find key'
> 

LookupError is the parent of KeyError and IndexError.  I generally
catch the more specific list/dict exceptions depending on what I'm
trying to access.


The fact that I'm very certain about my answers increases the likelyhood
that I'm in fact wrong ;)

-jack

[I orignally had a long thing about the weird exceptions thrown by mmap here,
but decided A: no one cared, B: a patch would be better than bitching.  But
really, how can a method with no arguments raise a ValueError?]





More information about the Python-list mailing list