@property decorator doesn't raise exceptions

Rafe rafesacks at gmail.com
Sat Oct 25 15:53:23 EDT 2008


On Oct 24, 9:58 am, Peter Otten <__pete... at web.de> wrote:
> Rafe wrote:
> > On Oct 24, 2:21 am, Christian Heimes <li... at cheimes.de> wrote:
> >> Rafewrote:
> >> > Hi,
>
> >> > I've encountered a problem which is making debugging less obvious than
> >> > it should be. The @property decorator doesn't always raise exceptions.
> >> > It seems like it is bound to the class but ignored when called. I can
> >> > see the attribute using dir(self.__class__) on an instance, but when
> >> > called, python enters __getattr__. If I correct the bug, the attribute
> >> > calls work as expected and do not call __getattr__.
>
> >> > I can't seem to make a simple repro. Can anyone offer any clues as to
> >> > what might cause this so I can try to prove it?
>
> >> You must subclass from "object" to get a new style class. properties
> >> don't work correctly on old style classes.
>
> >> Christian
>
> > All classes are a sub-class of object. Any other ideas?
>
> Hard to tell when you don't give any code.
>
> >>> class A(object):
>
> ...     @property
> ...     def attribute(self):
> ...             raise AttributeError
> ...     def __getattr__(self, name):
> ...             return "nobody expects the spanish inquisition"
> ...>>> A().attribute
>
> 'nobody expects the spanish inquisition'
>
> Do you mean something like this? I don't think the __getattr__() call can be
> avoided here.
>
> Peter

You nailed it Peter! I thought __getattr__ was a symptom, not the
cause of the misleading errors. Here is the repro (pretty much
regurgitated):

The expected behavior...

>>> class A(object):
...     @property
...     def attribute(self):
...         raise AttributeError("Correct Error.")
>>> A().attribute
Traceback (most recent call last):
  File "<console>", line 0, in <module>
  File "<console>", line 0, in attribute
AttributeError: Correct Error.


The unexpected and misleading exception...

>>> class A(object):
...     @property
...     def attribute(self):
...         raise AttributeError("Correct Error.")
...     def __getattr__(self, name):
...         cls_name = self.__class__.__name__
...         msg = "%s has no attribute '%s'." % (cls_name, name)
...         raise AttributeError(msg)
Traceback (most recent call last):
  File "<console>", line 0, in <module>
  File "<console>", line 0, in __getattr__
AttributeError: A has no attribute 'attribute'.


The docs state:
"Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self). name is the attribute name. This method
should return the (computed) attribute value or raise an
AttributeError exception."

Can anyone explain why this is happening? I can hack a work-around,
but even then I could use some tips on how to raise the 'real'
exception so debugging isn't guesswork.


Cheers,

- Rafe



More information about the Python-list mailing list