[Tutor] Builtin "property" decorator hiding exceptions

Kent Johnson kent37 at tds.net
Thu Apr 19 12:44:56 CEST 2007


Jacob Abraham wrote:
> Hi,
> 
>    The sample script below throws the exception "AttributeError: input" rather than the expected exception "AttributeError: non_existent_attribute".  
> 
>    Please help me write a decorator or descriptor of my own that fixes the issue.
> 
> class Sample(object):
>     def __init__(self):
>         self.arguments = {}
> 
>     def __getattr__(self, name):
>         ret_val = self.arguments.get(name, None)
>         if ret_val != None: return ret_val
>         raise AttributeError, name
>     
>     @property
>     def input(self):
>         self.non_existent_attribute
>     
> 
> sample = Sample()
> sample.input

I don't fully understand what is going on here but it seems that it is 
your __getattr__() that is hiding the exception.

If I take out __getattr__(), I get
AttributeError: 'Sample' object has no attribute 'non_existent_attribute'

I think this is what is happening:
- the input attribute is fetched
- input is a descriptor so its __get__ method is called
- __get__ tries to find non_existent_attribute by the usual methods, 
which fail
- __get__ calls __getattr__ which raises AttributeError
- __get__ raises AttributeError

OK, so think about it - trying to access .input has raised an 
AttributeError, i.e. attribute access through the normal mechanism has 
failed.

Now __getattr__ is called for input and again AttributeError is raised; 
this is the error you see.

If you put some print statements into __getattr__ you can see this is 
the order of events.

This is not the behaviour you want but it does make a certain sense.

If you raise a different exception in __getattr__ it is propagated out.

Kent


More information about the Tutor mailing list