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 <[email protected]>
<http://bugs.python.org/issue23990>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com