getattr() woes

David M. Cooke cookedm+news at physics.mcmaster.ca
Wed Dec 29 06:07:45 CET 2004


aahz at pythoncraft.com (Aahz) writes:

> In article <87hdm5hnet.fsf at thomas.local>,
> Thomas Rast  <foo.bar at freesurf.ch.invalid> wrote:
>>
>>class dispatcher:
>>    # ...
>>    def __getattr__(self, attr):
>>        return getattr(self.socket, attr)
>>
>>>>> import asyncore
>>>>> class Peer(asyncore.dispatcher):
>>...     def _get_foo(self):
>>...         # caused by a bug, several stack levels deeper
>>...         raise AttributeError('hidden!')
>>...     foo = property(_get_foo)
>>...
>
> You're not supposed to use properties with classic classes.

Even if dispatcher was a new-style class, you still get the same
behaviour (or misbehaviour) -- Peer().foo still raises AttributeError
with the wrong message.

A simple workaround is to put a try ... except AttributeError block in
his _get_foo(), which would re-raise with a different error that
wouldn't be caught by getattr. You could even write a property
replacement for that:

>>> class HiddenAttributeError(Exception):
...     pass
>>> def robustprop(fget):
...     def wrapped_fget(self):
...         try:
...             return fget(self)
...         except AttributeError, e:
...             raise HiddenAttributeError(*e.args)
...     return property(fget=wrapped_fget)

Ideally, I think the better way is if getattr, when raising
AttributeError, somehow reused the old traceback (which would point
out the original problem). I don't know how to do that, though.

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca



More information about the Python-list mailing list