[Python-Dev] special method lookup: how much do we care?

Michael Foord fuzzyman at voidspace.org.uk
Mon May 11 00:20:01 CEST 2009


Nick Coghlan wrote:
> Benjamin Peterson wrote:
>   
>> A while ago, Guido declared that all special method lookups on
>> new-style classes bypass __getattr__ and __getattribute__. This almost
>> completely consistent now, and I've been working on patching up a few
>> incorrect cases. I've know hit __enter__ and __exit__. The compiler
>> generates LOAD_ATTR instructions for these, so it uses the normal
>> lookup. The only way I can see to fix this is add a new opcode which
>> uses _PyObject_LookupSpecial, but I don't think we really care this
>> much. Opinions?
>>     
>
> As Georg pointed out, the expectation was that we would eventually add a
> SETUP_WITH opcode that used the special method lookup (and hopefully
> speed with statements up to a point where they're competitive with
> writing out the associated try statement directly). The current code is
> the way it is because there is no "LOAD_SPECIAL" opcode and adding type
> dereferencing logic to the expansion would have been difficult without a
> custom opcode.
>
> For other special methods that are looked up from Python code, the
> closest we can ever get is to bypass the instance (i.e. using
> "type(obj).__method__(obj, *args)") to avoid metaclass confusion. The
> type slots are even *more* special than that because they bypass
> __getattribute__ and __getattr__ even on the metaclass for speed reasons.
>
> There's a reason the docs already say that for a guaranteed override you
> *must* actually define the special method on the class rather than
> merely making it accessible via __getattr__ or even __getattribute__.
>
> The PyPy guys are right to think that some developer somewhere is going
> to rely on these implementation details in CPython at some point.
> However lots of developers rely on CPython ref counting as well, no
> matter how many times they're told not to do that if they want to
> support alternative interpreters.
>   

It's actually very annoying for things like writing Mock or proxy 
objects when this behaviour is inconsistent (sorry should have spoken up 
earlier).

The Python interpreter bases some of its decisions on whether these 
methods exist at all - and when you have objects that provide methods 
through __getattr__ then you can accidentally get screwed if magic 
method lookup returns an object unexpectedly when it should have raised 
an AttributeError.

Of course for proxy objects it might be more convenient if *all* 
attribute access did go through __getattr__ - but with that not the case 
it is much better for it to be consistent rather than have to put in 
specific workaround code.

All the best,

Michael


> Cheers,
> Nick.
>
>   


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




More information about the Python-Dev mailing list