On 9 Jul, 2013, at 1:21, Steve Dower <Steve.Dower@microsoft.com> wrote:
Except that if it's on a metaclass, the 'instance' it has access to is cls. The descriptor side of things is more interesting, but I see no reason why super can't do that itself, since it knows the actual instance to call __get__ with. (Presumably it already does this with the __dict__ lookup, since that won't call __get__ either.)
Explaining the new method is easiest if the default implementation is (literally):
def __getlocalname__(self, name): try: return self.__dict__[name] except KeyError: raise AttributeError(name)
which does not do any descriptor resolution (and is only a small step from simply replacing __dict__ with a custom object, which is basically where we started). The only change I've really suggested is making it an instance method that can be implemented on a metaclass if you want it for class members.
I've documented this (with a different name) in the current PEP draf (<http://www.python.org/dev/peps/pep-0447/>) and am working on an implementation. Using a lookup method on the metaclass has a nice side-effect: the same method could be used by object.__getattribute__ (aka PyObject_GenericGetAttr) as well which could simplify my primary usecase for this new API. There is a problem with that though: the type attribute cache in Object/typeobject.c, using that cache isn't valid if _PyType_Lookup calls a method instead of peeking in tp_dict (the cache cannot be in the default __getlocalname__ implementation because a primary usecase for the cache appears to be avoiding walking the MRO [1]). I haven't decided yet what to do about this, a number of options: * Don't use __getlocalname__ in _PyType_Lookup * Use __getlocalname__ as a fallback after peeking in tp_dict (that is, use it like __getattr__ instead of __getattribute__) and only cache the attribute when it is fetched from tp_dict. * Don't add a default __getlocalname__ and disable the attribute cache for types with a metatype that does have this method (this might be non-trivial because a metatype might grow a __getlocalname__ slot after instances of the metatype have been created; that would be ugly code but is possbile) Ronald [1] "appears" because I haven't found documentation for the cache yet