rodee
rodee

Reputation: 3151

TypeError exception not being caught

Why is this TypeError not being caught by exception ?

>>> op=None
>>> try:
...     val = op['one']
... except KeyError, TypeError:
...     val = "one"
... 
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'
>>> 

Upvotes: 2

Views: 1134

Answers (2)

jpaugh
jpaugh

Reputation: 7035

Python 2 does not allow specifying multiple exceptions in the same except clause this way. You might expect the , to create a tuple of Exceptions (which would be valid, as bernie demonstrates), but that's not what happens.

Looking at the language spec, we have

"except" [expression [("as" | ",") identifier]] ":"

where the comma is interchangeable with as.

In other words, the following two except clauses are equivalent

except KeyError, e:
    print "We got a key error!"
except KeyError as e:
    print "We got a key error!"

This catches a KeyError, and gives it a name of e. So, in your code, you're catching a KeyError and giving it a name of TypeError.


To overcome this ambiguity in Python's grammar, and specify multiple exceptions (kudos to Artyr and Downshift for explaining this), you must use parentheses to force it to be interpreted as a single expression (to be interpreted as a tuple of exceptions), rather than AS expression COMMA identifier.

except (KeyError, TypeError), e:
    pass
except (KeyError, TypeError) as e:
    pass

Again, the above two expressions are equivalent, and assign the caught exception to the variable e. Notably, the form with a comma was removed in Python 3, making the language grammar a bit less confusing!

"except" [expression ["as" identifier]] ":"

Upvotes: 0

mechanical_meat
mechanical_meat

Reputation: 169264

You have to enclose the list of exceptions in parens/brackets:

except (KeyError, TypeError):
    #  ^                   ^
    val = "one"

Upvotes: 4

Related Questions