[Python-Dev] PEP 447: add type.locallookup (original) (raw)

Ronald Oussoren ronaldoussoren at mac.com
Thu Sep 19 11:32:17 CEST 2013


On 14 Sep, 2013, at 8:30, Nick Coghlan <ncoghlan at gmail.com> wrote:

[... interesting text that I'll respond to later ...]

So my proposed name is based on the idea that what Ronald is after with the PEP is a hook that only gets invoked when the interpreter is doing this hunt for descriptors, but not for ordinary attribute lookups.

I'll describe the usecase that led to my proposal. I'm amongst other the primary author (and sole maintainer) of PyObjC, which is a bridge between the Python and Objective-C class/object models. PyObjC defines a proxy class for every (Objective-C) class in the Objective-C runtime and when an Objective-C object is made available to Python code the PyObjC bridge creates a proxy object that is an instance of this proxy object. This is simular what wxWidgets or PyQt do, but everything is done at runtime by introspecting the Objective-C runtime.

The first time a method is called the bridge looks for an Objective-C selector with the same name and adds that to the class dictionary. This works fine for normal method lookups, by overriding getattribute, but causes problems with super: super happily ignores getattribute and peeks in the class dict which may not yet contain the name we're looking for and that can result in incorrect results (both incorrect AttributeErrors and totally incorrect results when the name is not yet present in the parent class' dict but is in the grandparent's dict).

The current release of PyObjC "solves" this problem by providing a subclass of super (objc.super) that should be used instead of the builtin one and that works, although the implementation of this class is a gross hack.

Users's of PyObjC are currently oblivious of the problem because I sneak in objc.super as a module's globals()['super'] when it imports PyObjC in the currently prefered way (which is using *-imports: "from Cocoa import *"). I'm currently migrating to deprecating *-imports because those are bad for the usual reasons, but also because framework binding modules are huge and using plain imports makes it possible to delay, and often even avoid, the cost of loading stuff from the framework binding modules. That switch will however make the problem of using builtin.super extremely visible for PyObjC users.

That, and the implementation hack of objc.super, is why I started looking for a way to cleanly provide a way to hook into the attribute resolution for super(), which ended up as PEP 447.

Note that the description is slightly simplified from what PyObjC reall does, Objective-C can (and does) have class and instance methods with the same name, because of that all PyObjC classes have a meta class of the same name and that makes everything even more complicated, but that should not be important for the previous description.

PyObjC also enables implementing Objective-C classes in Python, but that's also not relevant for this discussion.

Ronald



More information about the Python-Dev mailing list