@property decorator doesn't raise exceptions

Rafe rafesacks at gmail.com
Wed Oct 29 04:22:56 EDT 2008


On Oct 27, 2:47 pm, Peter Otten <__pete... at web.de> wrote:
> Rafewrote:
> > Can anyone explain why this is happening?
>
> When an attribute error is raised that is an indication that the requested
> attribute doesn't exist, and __getattr__() must be called as a fallback.
>
> > 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.
>
> Look at the problem again, maybe you can find a solution without
> __getattr__() and use only properties.
>
> Otherwise you have to wrap your getter with something like
>
> try:
>     ...
> except AttributeError:
>     raise BuggyProperty, None, original_traceback
>
> If you put that functionality into a decorator you get:
>
> import sys
>
> class BuggyProperty(Exception):
>     pass
>
> def safe_getter(get):
>     def safe_get(self):
>         try:
>             return get(self)
>         except AttributeError:
>             t, e, tb = sys.exc_info()
>             raise BuggyProperty("AttributeError in getter %s(); "
>                             "giving original traceback"
>                             % get.__name__), None, tb
>     return property(safe_get)
>
> class A(object):
>     @safe_getter
>     def attr(self):
>         return self.m(3)
>
>     def m(self, n):
>         if n > 0:
>             return self.m(n-1)
>         raise AttributeError("it's a bug")
>
>     def __getattr__(self, name):
>         return "<%s>" % name
>
> A().attr
>
> Peter


Thanks for the idea Peter. What confuses me is why this only happens
to @Property (and I assume other decorator related bindings?). Does it
have something to do with the way the class gets built? 'Normal'
attributes will raise AttributeErrors as expected, without triggering
__getattr__(). Considering this is a built-in decorator, it would be
nice if this behavior was fixed if possible.

Unfortunately, I need __getattr__() because my class is a wrapper (it
is delegating calls to another object when attributes aren't found in
the class). As a hack, I am testing the passed attr name against the
instance, class and super-class attributes. If there is a match, I
assume it is an error and raise an exception which points the
developer in the right direction. It isn't ideal, but it helps.

You're code is better, as it displays the 'real' traceback, but I need
to know more about the effects of using an exception which is not an
AttrbiuteError. Which brings me to my next question...

In case it isn't obvious, I'm fairly new to Python (and this level of
programming in general). I've been wondering about the optimal use of
custom exceptions. Up until now, I've been sticking to the built-in
exceptions, which seem to work in 90% of situations. Are you aware of
any resources which talk about this aspect of programming (more about
theory than code)?


Thanks again,

- Rafe



More information about the Python-list mailing list