Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: can't catch an IndexError

Disclaimer: this looks like a duplicate, but finding an answer to this particular problem was more than trivial - I hope others will find this question/answer with more ease!

When I run the following code, it fails to catch the second IndexError, raising it instead:

try:
  raise ValueError
except ValueError,IndexError:
  pass
l = [1,2,3]
try:
  l[4]
except IndexError:
  print "an index error!"

results in

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-24-61bcf6d2b9af> in <module>()
      6       pass
      7 try:
----> 8       l[4]
      9 except IndexError:
     10       print "an index error!"

IndexError: list index out of range
like image 586
drevicko Avatar asked Jun 15 '14 13:06

drevicko


Video Answer


1 Answers

The problem was bad use of except ... syntax. The line:

except ValueError,IndexError:

should be

except (ValueError,IndexError):

Explanation: If you want to inspect the exception that was thrown, the syntax is except <exception-class>,e where variable e is assigned an instance of <exception-class>. Here's what happens in the failing code:

  1. open("afile",'x') throws a ValueError as 'x' isn't a valid file mode string.
  2. except ValueError,IndexError assigns the thrown ValueError instance to a new variable called IndexError.
  3. This new variable overrides the builtin IndexError class.
  4. l[4] raises an actual IndexError exception.
  5. The except clause is checked for this exception type, but only an instance of ValueError (which happens to have the name IndexError) is found, so the exception is not caught.

If you are running an interactive python session, you can del IndexError to uncover the builtin and allow you to catch IndexError's again.

like image 152
drevicko Avatar answered Oct 12 '22 22:10

drevicko