2

I am trying to override getattr method and as per my understanding there should be infinite loop in the following code snippet as by default object.__getattribute__(self,attr) is invoked which will invoke overrided getattr method as attribute 'notpresent' is not present in namespaces and this process will be keep on repeating. Can anybody help me in figuring out that why this behavior is not observed here.

Moreover I am unable to figure out that why AttributeError is not raised when implicit call to getattribute is done while accessing attribute using dot notation while it is being raised second time when we are trying to invoke getattribute explicitly within method

class Test(object):

    #Act as a fallback and is invoked when getattribute is unable to find attribute

    def __getattr__(self,attr):

        print "getattr is called"
        return object.__getattribute__(self,attr) #AttributeError is raised

t=Test([1,2,3,4])

b = t.notpresent
1

2 Answers 2

4

You are calling object.__getattribute__ within Test.__getattr__.

There is no loop involved here.

Moreover, as per the docs, __getattribute__ does not implicitly call __getattr__.

Update after your edit

Here is the C-implementation of the __getattribute__ call. Especially the slot_tp_getattr_hook part.

In your case, the attribute lookup failure lead to the execution of line 6072 that calls your custom __getattr__ function.

From there on, the AttributeError has been cleared. But your call to object.__getattribute__ will set it back and line 6074 or 6075 won't handle it.

The object.__getattribute__ call is implemented like so and thus (re)raise AttributeError (line 1107).

Sign up to request clarification or add additional context in comments.

2 Comments

As per docs overrided getattr should be called if AttributeError is raised
AttributeError has already been handled, because Test.__getattr__ is being called. Thus explicitly calling object.__getattribute__ is exactly the same as calling it from Test.__getattribute__ to avoid infinite loops.
0

Because the __getattribute__ normally only looks up the attribute in the __dict__ of the object and similar places - it does not implicitely call __getattr__ to retrieve the attribute.

Note that if __getattribute__ would call __getattr__ the __getattr__ method might be called twice if __getattribute__ failed to find the attribute (since lookup is supposed to call __getattr__ when __getattribute__ fails).

2 Comments

@brunodesthuilliers Perhaps, but just commenting "Sorry but plain wrong" does not help. Could you explain in what way my answer is wrong?
__getattribute__ does not "normally only looks up the attribute in the __dict__ of the object." - it handles the whole attribute lookup, including descriptors (computed attributes), looking up the instance's dicts OR slots, and looking up the class and parents classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.