Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting AttributeError in __getattr__

Tags:

python

If a class defines a __getattr__ method it needs to raise an AttributeError if the requested attribute was not found.

However, if one simply executes raise AttributeError() the usual error message is missing.

Currently I am doing the following instead:

raise AttributeError("'{}' object has no attribute '{}'".format(self.__class__.__name__, name))

This however is a lot of boiler plate code and has the potential for inconsistent error messages if the python interpreter was e.g. localised.

Is there any way to get python take care of assembling the error message the same way it does when no __getattr__ method is defined?

like image 373
ARF Avatar asked Oct 21 '25 11:10

ARF


2 Answers

Most such cases in the standard library don't bother with the message and just use the name as an argument:

raise AttributeError(attr)

letting the traceback tell the rest.

like image 53
ivan_pozdeev Avatar answered Oct 24 '25 11:10

ivan_pozdeev


The default error (along with the formatted message) is usually raised in object.__getattribute__. As such, this is the method that you want to call if you want python to do the error formatting for you.

You can do something cute and try to call __getattr__ on the super class. If __getattr__ doesn't exist, then you can fall back to using __getattribute__ which will take care of formatting the error:

class Foo(object):
    def __getattr__(self, attr):
        try:
            return super(Foo, self).__getattr__(attr)
        except AttributeError:
            return super(Foo, self).__getattribute__(attr)


f = Foo()
x = f.bar

Of course, this swallows all (possibly helpful) errors that might get raised in the super class's __getattr__, so use this carefully...

If you're at a point in your code where you know that the current class should be raising a appropriately formatted AttributeError, you can just do something a little more direct:

class RaiseAlwaysExample(BaseClass):
    def __getattr__(self, attr):
        if True:
            return object.__getattribute__(self, attr)  # Raise appropriately formatted attribute error.
like image 33
mgilson Avatar answered Oct 24 '25 11:10

mgilson



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!