Reputation: 3151
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
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
Reputation: 169264
You have to enclose the list of exceptions in parens/brackets:
except (KeyError, TypeError):
# ^ ^
val = "one"
Upvotes: 4