Eric Snow added the comment:

> What would be the "right thing"?

My suggestion of using a metaclass is actually not effective here because 
__call__ has meaning for metaclasses.  Otherwise you could have made __call__ 
more dynamic via a metaclass.  Except that is another reason why my suggestion 
is incorrect.  What you are asking for is that, effectively, the state of the 
instance might be able to impact the resolution of special methods of a class.  
So a metaclass approach would not have helped since the instance would not have 
been involved in the lookup.

Regardless, this makes it more clear to me what you are trying to accomplish 
for the sake of a proxy type.  The question is, should an instance be able to 
influence the resolution of special methods that are called on its behalf?

Before answering that, consider why methods that are special to the interpreter 
get treated differently.  The language specifies that rather than using 
obj.__getattribute__ to look up special methods, they are effectively located 
in type(obj).__dict__.  They likewise are not looked up on 
obj.__class__.__dict__.  Here are the key reasons why this matters:

 * speed
 * the special methods will still be available even if the class implements its 
own __getattribute__

Once the methods are looked up, the descriptor protocol is invoked, if 
applicable.  However, it does not fall back to obj.__getattr__.  See 
Objects/typeobject.c:_PyObject_LookupSpecial.  So ultimately the descriptor 
protocol allows instances to have a say in both the existence and the behavior 
of special methods.  However, I think that the former is unfortunate since it 
obviously muddies the water here.  I doubt it was intentional.

Back to the question, should instances be allowed to influence the *lookup* of 
special methods?  Your request is that they should be and consistently.  As 
noted, the interpreter already uses the equivalent of the following when 
looking up special methods:

    def _PyObject_LookupSpecial(obj, name):
        attr = inspect.getattr_static(obj, name)
        try:
            f = inspect.getattr_static(attr, '__get__')
        except AttributeError:
            return attr
        else:
            return f(attr, obj, type(obj))

What you are asking is that callable should do this too, rather than skipping 
the descriptor part).  I expect the same would need to be done for any other 
helper that also checks for "special" capability.  For example, see the various 
__subclasshook__ implementations in Lib/_collections_abc.py.  We should be 
consistent about it if we are going to do it.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue23990>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to