classification
Title: descriptor protocol bug
Type: behavior Stage:
Components: Interpreter Core Versions: Python 2.6, Python 2.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gangesmaster, pitrou, thomas.lee (3)
Priority: high Keywords

Created on 2007-12-13 20:13 by gangesmaster, last changed 2008-12-09 15:20 by thomas.lee.

Files
File name Uploaded Description Edit Remove
demo.txt gangesmaster, 2007-12-13 20:13
Messages (5)
msg58581 - (view) Author: ganges master (gangesmaster) Date: 2007-12-13 20:13
it seems the code of PyObject_GenericGetAttr, which invokes the
descriptor protocol, silences any AttributeErrors raised by the
descriptor, for classes that also define __getattr__. it should
propagate up rather than being silently ignored.

the attached example is quite artificial, but it's a simplification of
real world code i had hard time debugging. turned out i misspelled an
attribute name inside the property getter function, which raised an
AttributeError as expected -- but the exception i got was quite
misleading, saying the instance has no attribute named so.

this bug only happens when the class defines a custom __getattr__. see
attached demo file for details.
msg61312 - (view) Author: Antoine Pitrou (pitrou) Date: 2008-01-20 17:29
I can confirm that with SVN trunk, and it's actually even worse because
it can return unexpected results without raising an exception at all:

>>> class Foo(object):
...   def __getattr__(self, name): return 42
...   @property
...   def bacon(self): return int.lalala
... 
>>> f = Foo()
>>> f.bacon
42
>>> Foo.bacon.__get__(f)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bacon
AttributeError: type object 'int' has no attribute 'lalala'
msg61321 - (view) Author: Antoine Pitrou (pitrou) Date: 2008-01-20 18:09
PyObject_GenericGetAttr is invoked from slot_tp_getattr_hook in
typeobject.c via tp_getattro. The problem is that, when tp_getattro
returns with an AttributeError, there is no way for slot_tp_getattr_hook
to know whether the error was raised by PyObject_GenericGetAttr itself
or by subsequent invocation of user code. Perhaps by adding an attribute
to the raised AttributeError?
msg76825 - (view) Author: ganges master (gangesmaster) Date: 2008-12-03 12:20
here's a short example of the bug

>>> class Foo(object):
...   def __getattr__(self, name): 
...     return 42
...   @property
...   def bacon(self): 
...     return int.lalala
...   @property
...   def eggs(self): 
...     return 17
... 
>>> f = Foo()
>>> f.bacon   # raises an AttributeError, and silently ignores it
42
>>> f.eggs
17
>>> 

are there any news in this front?
msg77424 - (view) Author: Thomas Lee (thomas.lee) Date: 2008-12-09 15:20
Related reading from a few years back:

Python/comp.lang.python/2005-05/msg03829.html">http://coding.derkeiler.com/Archive/Python/comp.lang.python/2005-05/msg03829.html
History
Date User Action Args
2008-12-09 15:20:54thomas.leesetnosy: + thomas.lee
messages: + msg77424
2008-12-03 12:20:40gangesmastersetmessages: + msg76825
2008-01-20 20:01:53christian.heimessetpriority: high
2008-01-20 18:09:29pitrousetmessages: + msg61321
2008-01-20 17:29:07pitrousetnosy: + pitrou
messages: + msg61312
severity: normal -> major
2007-12-13 20:13:37gangesmastercreate