Issue1095
Created on 2008-08-04.09:51:09 by akruis, last changed 2008-08-21.03:24:35 by leosoto.
File name |
Uploaded |
Description |
Edit |
Remove |
testAttributeError.py
|
akruis,
2008-08-04.10:12:52
|
A test script, that shows the difference between CPython and Jython |
|
|
1095.diff
|
akruis,
2008-08-19.11:58:36
|
patch for this issue. against r5155 |
|
|
msg3392 (view) |
Author: Anselm Kruis (akruis) |
Date: 2008-08-04.10:12:52 |
|
Sorry, I accidentally hit the Return-key while creating the ticket.
Here is the description:
Jython catches AttributeErrors (and subclasses thereof) raised by
__getattr__(self, name) and replaces the exception by the default
AttributeError. CPython does not show this behaviour.
Running the attached test script with the latest 2.5a release of Jython
gives:
> ~/src/jython2.5a1+/jython testAttributeError.py
Caught exception is different from raised exception
Caught: class <type 'exceptions.AttributeError'> ''instance' object
has no attribute 'xyz''
Raised: class <class '__main__.DerivedAttributeError'> 'xyz'
On CPython, the output of the attached test script is:
Caught exception is raised exception
This problem is very similar to #1041. "AttributeError raised from
descriptors __get__ method are swallowed"
Why is this difference a problem:
I'm maintainer of an application, that uses jython as its embedded
scripting language. The API provided for users of this application shall
resemble CPython as much as possible and therefore hides some
implementation details using __getattr__ and similar methods. Errors on
attribute access usually raise an AttributeError and I'd prefer to stay
with that convention. However I need to pass some more information about
the real cause of the exception.
|
msg3396 (view) |
Author: Leonardo Soto (leosoto) |
Date: 2008-08-04.19:43:07 |
|
You are right, this is #1041 showing up in a different way. The good
news is that fixing that will fix this too.
|
msg3425 (view) |
Author: Leonardo Soto (leosoto) |
Date: 2008-08-11.23:28:17 |
|
Fixed in r5155
|
msg3436 (view) |
Author: Anselm Kruis (akruis) |
Date: 2008-08-19.09:54:24 |
|
I don't consider this bug fixed, because the attached script
"testAttributeError.py" still shows, that the exception raised by
__getattr__ gets swallowed.
|
msg3438 (view) |
Author: Anselm Kruis (akruis) |
Date: 2008-08-19.10:05:12 |
|
It might be noteworthy, that my test uses old-style classes. If I change
the test to use a new style class, it succeeds.
|
msg3439 (view) |
Author: Anselm Kruis (akruis) |
Date: 2008-08-19.11:58:36 |
|
The attached patch fixes this issue.
Some details: In my test case an old style class implements
__getattr__(self, name). An access of an otherwise undefined attribute
yields the following JAVA stack trace (just the interesting part):
at org.python.core.PyFunction.__call__(PyFunction.java:312)
at org.python.core.PyInstance.ifindfunction(PyInstance.java:238)
at org.python.core.PyInstance.__findattr__(PyInstance.java:217)
at org.python.core.PyInstance.__findattr_ex__(PyInstance.java:204)
at org.python.core.PyObject.__getattr__(PyObject.java:820)
at org.python.pycode._pyx0.f$0(testAttributeError.py)
Inspection of this code path shows:
- the call of a __findattr__-method, which indicates a problem,
because the __findattr__ methods never throw AttributeError
- org.python.core.PyInstance#ifindfunction(String) catches PyException
and returns null in case of an AttributeError. (In PyObject#__getattr__
this null return value yields an AttributeError.)
I looked at the clients of PyInstance#ifindfunction(String). The method
is only used within PyInstance. In every case, we see the same pattern
value=this.ifindfunction(name);
...
if (value==null)
noAttributeError(name);
Therefore it does not harm, to remove the try-catch clause from
ifindfunction. Of course we have to make sure, that the __findattr__
methods still return null instead of an AttributeError. Therefor I added
a new method PyInstance#__findattr_ex__(String name, boolean stopAtJava)
and changed PyInstance#__findattr__(String name, boolean stopAtJava) to
call the new method.
With the patch applied, the relevant parts of a stack trace look like this:
at org.python.core.PyFunction.__call__(PyFunction.java:312)
at org.python.core.PyInstance.ifindfunction(PyInstance.java:246)
at org.python.core.PyInstance.__findattr_ex__(PyInstance.java:226)
at org.python.core.PyInstance.__findattr_ex__(PyInstance.java:204)
at org.python.core.PyObject.__getattr__(PyObject.java:820)
at org.python.pycode._pyx0.f$0(testAttributeError.py)
No more __findattr__ methods. Looks good for me.
|
msg3441 (view) |
Author: Philip Jenvey (pjenvey) |
Date: 2008-08-19.22:24:22 |
|
reopening
|
msg3443 (view) |
Author: Leonardo Soto (leosoto) |
Date: 2008-08-21.03:24:34 |
|
Thanks! Patch applied on r5229, along with tests.
|
|
Date |
User |
Action |
Args |
2008-08-21 03:24:35 | leosoto | set | status: open -> closed resolution: accepted -> fixed messages:
+ msg3443 |
2008-08-19 22:24:23 | pjenvey | set | status: closed -> open resolution: fixed -> accepted messages:
+ msg3441 nosy:
+ pjenvey |
2008-08-19 11:58:38 | akruis | set | files:
+ 1095.diff messages:
+ msg3439 |
2008-08-19 10:05:12 | akruis | set | messages:
+ msg3438 |
2008-08-19 09:54:24 | akruis | set | messages:
+ msg3436 |
2008-08-11 23:28:18 | leosoto | set | status: open -> closed resolution: fixed messages:
+ msg3425 |
2008-08-04 19:43:08 | leosoto | set | assignee: leosoto messages:
+ msg3396 nosy:
+ leosoto |
2008-08-04 10:12:53 | akruis | set | files:
+ testAttributeError.py versions:
+ Jython 2.1, 2.2.2, 2.5alpha1 title: Attribute -> AttributeError raised from __getattr__ method are swallowed messages:
+ msg3392 components:
+ Core type: behaviour |
2008-08-04 09:51:09 | akruis | create | |
|