except clause not catching IndexError

D

Derek Schuff

I'm sorry if this is a FAQ or on an easily-accesible "RTFM" style page, but
i couldnt find it.

I have some code like this:
for line in f:
toks = line.split()
try:
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
prod = int(toks[3], 16)
elif int(toks[2],16) == qaddrs+0x1002 and toks[0] == "200":
#consumer write
cons = int(toks[3], 16)
else:
continue
except IndexError: #happens if theres a partial line at the end of file
print "indexerror"
break

However, when I run it, it seems that I'm not catching the IndexError:
Traceback (most recent call last):
File "/home/dschuff/bin/speeds.py", line 202, in ?
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
IndexError: list index out of range

If i change the except IndexError to except Exception, it will catch it (but
i believe it's still an IndexError).
this is python 2.3 on Debian sarge.

any ideas?

thanks,
-derek
 
B

Ben Cartwright

Derek said:
I have some code like this:
for line in f:
toks = line.split()
try:
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
prod = int(toks[3], 16)
elif int(toks[2],16) == qaddrs+0x1002 and toks[0] == "200":
#consumer write
cons = int(toks[3], 16)
else:
continue
except IndexError: #happens if theres a partial line at the end of file
print "indexerror"
break

However, when I run it, it seems that I'm not catching the IndexError:
Traceback (most recent call last):
File "/home/dschuff/bin/speeds.py", line 202, in ?
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
IndexError: list index out of range

If i change the except IndexError to except Exception, it will catch it (but
i believe it's still an IndexError).
this is python 2.3 on Debian sarge.

any ideas?



Sounds like IndexError has been redefined somewhere, e.g.:
IndexError = 'something entirely different'
foo = []
try:
foo[42]
except IndexError: # will not catch the real IndexError; we're
shadowing it
pass

Try adding "print IndexError" right before your trouble spot, and see
if it outputs "exceptions.IndexError".

--Ben
 
S

Scott David Daniels

Derek said:
I have some code like this:
said:
However, when I run it, it seems that I'm not catching the IndexError:
Traceback (most recent call last):
File "/home/dschuff/bin/speeds.py", line 202, in ?
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
IndexError: list index out of range


This was good, the actual error; I suspect you overwrote IndexError.
The general principal is to boil down your code to the smallest code
that exhibits the problem. This is not just to aid us, since usually
at some point you delete a block of lines and the problem goes
magically away.
If i change the except IndexError to except Exception, it will catch it (but
i believe it's still an IndexError). This is python 2.3 on Debian sarge.
More points for identifying Python version and OS.
any ideas?
As above, but to test my theory:

....
except Exception, e:
print 'caught %r: %r (IndexError is %r)' % (
e, e.__class__, IndexError)

--Scott David Daniels
(e-mail address removed)
 
D

Derek Schuff

Erwin said:
Did you by any chance do something like:

except ValueError, IndexError:

at some point earlier in this function? That, when catching ValueError
assigns the resulting exception to IndexError (and so the following
except IndexError: wouldn't work as IndexError is no longer what you
think it is). The correct syntax for catching multiple exceptions is:

except (ValueError, IndexError), targetVariable:

You could verify this by doing a print repr(IndexError) before your
line 202, to see that it really is the IndexError builtin.

hey, nice catch. In fact I did exactly that. in my search for a solution for
this problem i discovered the catch-a-tuple-of-exceptions error, and in
fact fixed it, but didn't realize that it was related to the one I posted.
(the idea that exceptions can be redefined caught me off guard).

thanks (to both of you who responded),
-derek
 
E

Erwin S. Andreasen

Derek Schuff said:
I have some code like this:
[...]

except IndexError: #happens if theres a partial line at the end of file
print "indexerror"
break

However, when I run it, it seems that I'm not catching the IndexError:
Traceback (most recent call last):
File "/home/dschuff/bin/speeds.py", line 202, in ?
if int(toks[2],16) == qaddrs+0x1000 and toks[0] == "200": #producer
write
IndexError: list index out of range


Did you by any chance do something like:

except ValueError, IndexError:

at some point earlier in this function? That, when catching ValueError
assigns the resulting exception to IndexError (and so the following
except IndexError: wouldn't work as IndexError is no longer what you
think it is). The correct syntax for catching multiple exceptions is:

except (ValueError, IndexError), targetVariable:

You could verify this by doing a print repr(IndexError) before your
line 202, to see that it really is the IndexError builtin.
 
S

Steven D'Aprano

Erwin said:
Did you by any chance do something like:

except ValueError, IndexError:

at some point earlier in this function? That, when catching ValueError
assigns the resulting exception to IndexError (and so the following
except IndexError: wouldn't work as IndexError is no longer what you
think it is). The correct syntax for catching multiple exceptions is:

except (ValueError, IndexError), targetVariable:


You mean to say that "except X,Y:" gives different
results to "except (X,Y):"?

That can't be good.
.... L = []; print L[2]
.... except ValueError, IndexError:
.... print "Error!"
....
Traceback (most recent call last):
.... L = []; print L[2]
.... except (ValueError, IndexError):
.... print "Error!"
....
Error!


And here I was thinking that commas make tuples, not
brackets. What is happening here?
 
R

Roy Smith

Steven D'Aprano said:
And here I was thinking that commas make tuples, not
brackets. What is happening here?

What is happening is that the syntax for forming tuples is one of Python's
warts. Sometimes the comma is what makes a tuple:
<type 'tuple'>

Sometimes, it is the parens:
<type 'tuple'>

Sometimes the syntax is ambiguous and you need both. This happens anytime
you have a list of comma separated things, such as in the arguments to a
function:

a = foo (1, 2) # two integer arguments
b = foo ((a, 2)) # one tuple argument

The except clause of a try statement is one of those times.
 
S

Sion Arrowsmith

Steven D'Aprano said:
You mean to say that "except X,Y:" gives different
results to "except (X,Y):"?
[ ... ]
And here I was thinking that commas make tuples, not
brackets. What is happening here?

Similar kind of thing to what's happening here:
('Hello', 'world!')

And for that matter foo(a, b) v. foo((a, b)). Commas make
tuples, but they're also argument separators, and if you're
using a tuple as an argument you need the brackets to
indicate precedence.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top