[Python-Dev] Attribute lookup ambiguity (original) (raw)

Michael Foord fuzzyman at voidspace.org.uk
Sun Mar 21 02:30:23 CET 2010


On 20/03/2010 12:00, Pascal Chambon wrote:

Michael Foord a écrit :

On 19/03/2010 18:58, Pascal Chambon wrote: Hello

I've already crossed a bunch of articles detailing python's attribute lookup semantic (dict, descriptors, order of base class traversing...), but I have never seen, so far, an explanation of WHICH method did waht, exactly. I assumed that getattr(a, b) was the same as a.getattribute(b), and that this getattribute method (or the hidden routine replacing it when we don't override it in our class) was in charge of doing the whole job of traversing the object tree, checking descriptors, binding methods, calling getattr on failure etc. However, the test case below shows that getattribute does NOT call getattr on failure. So it seems it's an upper levl machinery, in getattr(), which is in chrge of that last action. Python 3 has the behavior you are asking for. It would be a backwards incompatible change to do it in Python 2 as getattribute not calling getattr is the documented behaviour. Python 3.2a0 (py3k:78770, Mar 7 2010, 20:32:50) [GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin >>> class x: ... def getattribute(s, name): ... print ('getattribute', name) ... raise AttributeError ... def getattr(s, name): ... print ('getattr', name) ... >>> a = x() >>> a.b getattribute b getattr b I'm confused there, because the script you gave behaves the same in python 2.6. And according to the doc, it's normal, getattr() reacts to an AttributeError from getattribute, by calling getattr : """ Python 2.6.5 documentation object.getattribute(/self/, /name/) Called unconditionally to implement attribute accesses for instances of the class. If the class also defines getattr() <http://docs.python.org/reference/datamodel.html#object.getattr>, the latter will not be called unless getattribute() <http://docs.python.org/reference/datamodel.html#object.getattribute> either calls it explicitly or raises an AttributeError <http://docs.python.org/library/exceptions.html#exceptions.AttributeError>. This method should return the (computed) attribute value or raise an AttributeError <http://docs.python.org/library/exceptions.html#exceptions.AttributeError> exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.getattribute(self, name). """ But the point which for me is still unclear, is : does the default implementation of getattribute (the one of "object") call getattr by himself, or does it rely on its caller for that, by raising an AttributeError ? For Python2, it's blatantly the latter case which is favoured, but since it looks like an implementation detail at the moment, I propose we settle it (and document it) once for all.

Ah right, my apologies. So it is still documented behaviour - getattr is obviously called by the Python runtime and not by getattribute. (It isn't just by getattr as the same behaviour is shown when doing a normal attribute lookup and not via the getattr function.)

This list is not really an appropriate place to ask questions like this though, comp.lang.python would be better. All the best, Michael Fooord Sorry if I misposted, I just (wrongly ?) assumed that it was more an undecided, implementation-specific point (since the doc gave possible behaviours for getattribute, without precising which one was the default one), and thus targetted the hands-in-core-code audience only.

Well, the documentation you pointed to specifies that getattr will be called if getattribute raises an AttributeError, it just doesn't specify that it is done by object.getattribute (which it isn't).

Michael Foord

Regards, Pascal

-- http://www.ironpythoninaction.com/ http://www.voidspace.org.uk/blog

READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20100321/1e20ff61/attachment-0001.html>



More information about the Python-Dev mailing list