An @property replacement that reports AttributeErrors as PropertyFailedErrors

Bug #102160 reported by Andrew Bennetts
4
Affects Status Importance Assigned to Milestone
Launchpad itself
Triaged
Low
Unassigned

Bug Description

Properties defined with "@property" that raise AttributeError can be confusing. For instance, if a view has an @property that has a bug and raises an AttributeError, then OOPS will give the impression that the attribute is missing entirely, leading the developer to look for typos in the template, or the wrong view being registered etc, rather than looking in the right place. And even when the developer does figure out to look in the right place, they won't know which part of the property function raised AttributeError.

We could write an alternative property decorator like this:

class errorhandlingproperty(object):
    def __init__(self, fget):
        self.fget = fget
    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        try:
            return self.fget(obj)
        except AttributeError, e:
            raise PropertyFailedError(e)

(Compare with the pure-python reference defintion of Property at http://users.rcn.com/python/download/Descriptor.htm#properties)

This would ensure that the different cases of "attribute does not exist" and "property failed to work" are reported differently.

Revision history for this message
James Henstridge (jamesh) wrote :

From the point of view of "finding where the error occurred, won't this place the end of the traceback at the "raise PropertyFailedError" bit, obscuring the real location of the exception?

Revision history for this message
Tim Penhey (thumper) wrote :

In my case the real location was inside the property method. It was trying to access something that wasn't there, and raising the exception for that method would have helped tracking it down.

Revision history for this message
Andrew Bennetts (spiv) wrote :

James: good point. If only python had chained exceptions....

"raise PropertyFailedError(e)" should probably also capture the traceback (using sys.exc_info()), not just the original exception instance, and pass that to PropertyFailedError. So, pretend I said "raise PropertyFailedError(sys.exc_info())" :)

It was just a sketch to give the idea; and as Tim points out my original version would already be an improvement over what the builtin property does in this situation.

Curtis Hovey (sinzui)
Changed in launchpad-foundations:
status: New → Triaged
importance: Undecided → Low
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.