Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError and lost exception message

Tags:

python

It seems Python handles AttributeError exception non-standard. When a class defines __getattr__ method, it swallows this exception instead of propagation further to top of the stack. Is the original exception lost ?

class A(object):
    @property
    def test(self):
        raise AttributeError('message which should not be lost')
        return 'this would never return'

    def __getattr__(self, name):
        print 'Trying get attribute: ', name
        # how decide if AttributeError was already raised ??
        return 42

a = A()
print a.test
# Trying get attribute:  test
# 42

Imagine the AttributeError exception may arise anywhere at arbitrary depth in call chain.

The question is how preserve the original exception instance with 'message which should not be lost' message ? Is there some way how keep the AttributeError without recourse to workarounds like replacing with different exception class ?

like image 759
joanbm Avatar asked Jul 28 '26 12:07

joanbm


1 Answers

You are giving the object.__getattribute__() handler a signal that the attribute doesn't exist by raising an AttributeError. The defined behaviour is to then call __getattr__ instead. The exception is lost, it was handled by __getattribute__. From the documentation:

Called unconditionally to implement attribute accesses for instances of the class. If the class also defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError.

If you don't want __getattribute__ to handle the exception, you need to move your __getattr__ behaviour over to a custom __getattribute__ method instead:

class A(object):
    @property
    def test(self):
        raise AttributeError('message which should not be lost')
        return 'this would never return'

    def __getattribute__(self, name):
        try:
            value = super(A, self).__getattribute__(name)
        except AttributeError as ae:
            # chance to handle the attribute differently
            # if not, re-raise the exception
            raise ae

Note that the hasattr() function behaves the same way; it'll return False when an exception is raised when trying to access the attribute.

like image 71
Martijn Pieters Avatar answered Jul 31 '26 00:07

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!