_PyObject_LookupSpecial is used in place of obj.__getattribute__ for
looking up special methods. (As far as I recall it is not exposed in
the stdlib, e.g. inspect.getattr_special.) Correct me if I'm wrong
(please!), but there are two key reasons:
* access to special methods in spite of obj.__getattribute__
While _PyObject_LookupSpecial does not do lookup on obj.__dict__ or
call obj.__getattr__, it does resolve descriptors. This is important
particularly since special methods will nearly always be some kind of
descriptor. However, one consequence of this is that instances can
influence whether or not some capability, as relates to the special
method, is available. This is accomplished by the descriptor's
__get__ raising AttributeError.
My question is: was this intentional? Considering the obscure bugs
that can result (e.g. where did the AttributeError come from?), it
seems more likely that it is an oversight of an obscure corner case.
If that is the case then it would be nice if we could fix
_PyObject_LookupSpecial to chain any AttributeError coming from
descr.__get__ into a RuntimeError. However, I doubt we could get away
with that at this point.
Also, while it may be appropriate in general to allow instances to
dictate the availability of attributes/methods (e.g. through
__getattribute__, __getattr__, or descriptors), I'm not convinced it
makes sense for special methods. We are already explicitly
disconnecting special methods from instances in
_PyObject_LookupSpecial (except in the case of descriptors...).
p.s. I also find it a bit strange that instances have any say at all
in which methods (i.e. behavior) are *available*. Certainly instances
influence behavior, but I always find their impact on method
availability to be surprising. Conceptually for me instances are all
about state and classes about behavior (driven by state). However, it
is very rarely that I run into code that takes advantage of the