__getattribute__'s error is not available in __getattr__
Ethan Furman
ethan at stoneleaf.us
Tue May 2 20:11:07 EDT 2017
On 05/02/2017 11:16 AM, Jason Maldonis wrote:
> Here is the simplest example showing what I mean (there are many more
> complicating variations this, and unfortunately I'm running into some of
> them):
>
> class A(object):
> def __getattr__(self, attr):
> raise AttributeError("raised from A.__getattr__ to stop execution")
>
> a = A()
> print(a.x)
>
> results in:
>
> Traceback (most recent call last):
> File "test.py", line 6, in <module>
> print(a.x)
> File "test.py", line 3, in __getattr__
> raise AttributeError("raised from A.__getattr__ to stop execution")
> AttributeError: raised from A.__getattr__ to stop execution
>
> The thing to note here is that the AttributeError on the normal
> __getattribute__'s lookup isn't in the stack trace. That error is:
> Traceback (most recent call last):
> File "test2.py", line 35, in <module>
> print(a.x)
> AttributeError: 'A' object has no attribute 'x'
>
> -- that last line, "AttributeError: 'A' object has no attribute 'x'" does
> not appear in the stack trace for my above example (because __getattr__ is
> implemented). This is because in python's attribute lookup order,
> __getattr__ is called if an AttributeError is raised, and that raised
> AttributeError gets completely discarded.
>
> So basically I want access to the intermediate AttributeError that caused
> __getattr__ to be raised in the first place.
Why? In most cases* you know which object is missing -- it's the `attr` parameter above.
*The exception being an AttributeError raised inside a descriptor.
--
~Ethan~
More information about the Python-list
mailing list