[Python-Dev] Attribute lookup ambiguity
Pascal Chambon
chambon.pascal at wanadoo.fr
Mon Mar 22 19:06:44 CET 2010
Michael Foord a écrit :
> On 20/03/2010 12:00, Pascal Chambon wrote:
>>
>>
>> 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.)
>
I really don't see the docs you're referring to ; until I tested myself,
I think I had no obvious reasons to guess that __getattribute__ relied
on the upper level caller instead of finishing the hard job himself.
Nick Coghlan a écrit :
> Michael Foord wrote:
>
>> 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).
>>
>
> And as for why not: because __getattribute__ implementations need to be
> able to call object.__getattribute__ without triggering the fallback
> behaviour.
>
> Cheers,
> Nick.
>
>
I guess there are cases in which it is beneficial indeed.
>
> Michael Foord wrote:
>
>> 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).
>
> If __getattribute__ raises an exception, it won't get a chance to
> do anything else, so something outside of __getattribute__ must
> catch the AttributeError and calling __getattr__. So I think the
> docs *are* specifying the behaviour here, if only by implication.
>
I don't follow you there - in my mind, the default __getattribute__
could simply have wrapped all its operations inside soem kind of
"try..catch AttributeError:" mechanism, and thus been able to fallback
to __getattr__ in any way.
If I sum it up properly the semantic is :
-A.obj and getattr(A, "obj") are exactly the same
-They trigger the calling of __getattribute__ on the object (or it's
python core equivalent)
-By default, this __getattribute__ browse the whole object hierarchy
according to well known rules (__dict__, type, type's ancestors..),
handling descriptor protocols and the like. But it doesn't fallback to
__getattr__ - it raises an AttributeError instead.
-getattr() falls back to __getattr__ if __getattribute__ fails
-customized __getattribute__ methods have the choice between calling
__getattr__ by themselves, or delegating it to getattr() by raising an
exception.
Wouldn't it be worth completing the doc with these point ? They really
didn't seem obvious to me basically (even though, after analysis, some
behaviours make more sense than others).
I might submit a patch.
regards,
Pascal
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20100322/c908270b/attachment-0001.html>
More information about the Python-Dev
mailing list