By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,621 Members | 1,104 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,621 IT Pros & Developers. It's quick & easy.

How can an Exception pass over an "except" clause ?

P: n/a
I'm using the contract.py library, running Python 2.4.4.

Now I'm confronted with the following exception backtrace:
(...)
File "/usr/lib/python2.4/site-packages/contract.py", line 1265, in
_check_preconditions
p = f.__assert_pre
AttributeError: 'function' object has no attribute '__assert_pre'

For my surprise, I found that the code of contract.py around line 1265
looks like:

1264: try:
1265: p = f.__assert_pre
1266: except AttributeError:
1267: pass

I'd expect line 1267 to "swallow" the AttributeError siliently. But
the application stops with the above backtrace.
Someone familiar enough with the Python innards ? How can one manage
that an "except" seems to be ignored ?

Ruben

May 30 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Nebur wrote:
I'm using the contract.py library, running Python 2.4.4.

Now I'm confronted with the following exception backtrace:
(...)
File "/usr/lib/python2.4/site-packages/contract.py", line 1265, in
_check_preconditions
p = f.__assert_pre
AttributeError: 'function' object has no attribute '__assert_pre'

For my surprise, I found that the code of contract.py around line 1265
looks like:

1264: try:
1265: p = f.__assert_pre
1266: except AttributeError:
1267: pass

I'd expect line 1267 to "swallow" the AttributeError siliently. But
the application stops with the above backtrace.
Someone familiar enough with the Python innards ? How can one manage
that an "except" seems to be ignored ?

Ruben
The 'raise' in line 1271 re-raises the last error instead of the exception
in whose block it is called.

This:
try:
raise KeyError
except:
try:
raise IndexError
except: pass
raise

raises IndexError, not KeyError.

--

Regards,
Tijs
May 30 '07 #2

P: n/a
Nebur wrote:
I'm using the contract.py library, running Python 2.4.4.

Now I'm confronted with the following exception backtrace:
(...)
File "/usr/lib/python2.4/site-packages/contract.py", line 1265, in
_check_preconditions
p = f.__assert_pre
AttributeError: 'function' object has no attribute '__assert_pre'

For my surprise, I found that the code of contract.py around line 1265
looks like:

1264: try:
1265: p = f.__assert_pre
1266: except AttributeError:
1267: pass

I'd expect line 1267 to "swallow" the AttributeError siliently. But
the application stops with the above backtrace.
Someone familiar enough with the Python innards ? How can one manage
that an "except" seems to be ignored ?

Ruben

Under any normal circumstances, that code can't produce that error.
The attribute error will be swallowed by the except clause.

However by being *VERY* perverse, I was able to reproduce the above
error by overwriting AttributeError with some other exception class (say
SyntaxError):
AttributeError = SyntaxError
Then your code will be will produce a real AttributeError, but miss it
because (despite the spelling) it checks for a SyntaxError,

Question... I don't know what contract.py is, but could it be doing
something that *bad*?
You could check py printing AttributeError and see what it really is.
In my case it's:
>>print AttributeError
exceptions.SyntaxError
Gary Herron

P.S.: Anyone who does this kind of thing is a danger to society. May
their finger fall off before they get a chance to distribute such a program.
May 30 '07 #3

P: n/a
However by being *VERY* perverse, I was able to reproduce the above
error by overwriting AttributeError with some other exception class (say
SyntaxError):
AttributeError = SyntaxError
Then your code will be will produce a real AttributeError, but miss it
because (despite the spelling) it checks for a SyntaxError,
Yes ... this would be some kind of criminal joke
>
Question... I don't know what contract.py is, but could it be doing
something that *bad*?
No. I've searched the source for "AttributeError" and it appears only
in except clauses.
contracty.py is a library that adds Eiffel-like "design-by-
contract" (DBC) to Python. Precisely, I can add preconditions (and
postconditions) about the arguments into the methods docstring. These
are checked at runtime (and appear in the epydoc docu.) This is a
great thing I never want to miss anymore (and it was working fine for
some months now.)
(See http://www.wayforward.net/pycontract/ )
When the problem appears, contract.py is doing a pre-condition check.
You could check py printing AttributeError and see what it really is.
In my case it's:
>>print AttributeError
exceptions.SyntaxError

Gary Herron

P.S.: Anyone who does this kind of thing is a danger to society. May
their finger fall off before they get a chance to distribute such a program.
:-)

@Tijs: I think when re-raising, the backtrace will always point to the
line where it was re-raised but not to line 1265. (Or can we re-raise
an exception so that it preserves the backtrace of the "original"
exception?)

---
I'm speculating about there's a misleading backtrace. Maybe another
exception happens, but somehow using the obsolete exc_info of the last
exception (the AttributeError). I remember about some way to clear the
exc_info, maybe this must be added into contract.py? I'll find it out,
or a debugger session this night will help (I'll post again)
Ruben
May 30 '07 #4

P: n/a
>
@Tijs: I think when re-raising, the backtrace will always point to the
line where it was re-raised but not to line 1265. (Or can we re-raise
an exception so that it preserves the backtrace of the "original"
exception?)
@Tijs: Because of distrusting my own text above, I've checked re-
raising ... and indeed, you've been right. "raise" does _not_ produce
a new backtrace but uses the old one. Learned something new about
Python now... I think that clearifies all the "magic" behaviour.
Thank you,
Ruben

May 30 '07 #5

P: n/a
En Wed, 30 May 2007 15:30:43 -0300, Nebur <no****************@gmx.de>
escribió:
@Tijs: I think when re-raising, the backtrace will always point to the
line where it was re-raised but not to line 1265. (Or can we re-raise
an exception so that it preserves the backtrace of the "original"
exception?)
I think Tijs is right. raise (with no arguments) will raise the *last*
exception, not the one that was active when you entered the except clause;
it preserves the traceback.
Either replace the inner try/except using getattr, or save the full
exception details (including traceback) and use the 3-argument form of the
raise statement.
See http://docs.python.org/ref/raise.html

--
Gabriel Genellina

May 30 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.