[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