[Python-3000] A super() idea - no _getframe() involved

Phillip J. Eby pje at telecommunity.com
Wed Apr 19 08:34:51 CEST 2006


Here's how you solve the "how does super() get the current class" problem, 
using existing compiler and VM constructs, and without relying on class 
names, or on functions not being decorated, or anything like that.  And 
it's so simple you'll slap your forehead for not thinking of it first.  :)

Closures in Python use "cell" objects that store a reference to an object, 
and the VM has operations to efficiently load and store to these cells.  So 
what we do is that when the compiler sees a super operation, it should 
treat the reference to the containing class as a *local read of a closure 
variable*.

That is, it defines the function with MAKE_CLOSURE instead of 
MAKE_FUNCTION.  It also puts a reference to the cell object in the class's 
dictionary, let's say under __cell__.  And so the function code just uses 
LOAD_DEREF to get at the contents of that cell.

At this point, of course, the cell is empty because there's no class 
yet.  But the MAKE_CLASS opcode, after creating the class, checks to see if 
the resulting object has a __cell__ attribute, and if so, stores the 
class's self-pointer into it.  Or perhaps the 'type' constructor takes care 
of this, but if we can have class decorators it might be better to have 
MAKE_CLASS do it so it always points to the object that *will* be bound to 
the class name in the enclosing scope.

This is just a sketch, of course, and there might be something I'm missing, 
but it doesn't seem to require anything particularly outlandish; all the 
pieces are there and it seems like any Python implementation that does 
closures ought to be able to handle it.

And it doesn't depend on name mangling, the name not being reassigned, or 
anything like that.  The only bit that might get tricky is that whether the 
code object generated for a class body can have cell variables or 
not.  Since classes don't normally partake in the lexical scope system, 
it's possible that the implementation in some way precludes you from 
executing LOAD_CLOSURE in a class body code object, in which case there 
would need to be some other way to create the initial cell object.  (Or 
maybe the way that the class code object is executed precludes this.)

Apart from that potential issue, however, it actually seems simple enough 
to implement in the 2.x line, as long as the chosen syntax for expressing 
these automatic super calls is compatible with the 2.x grammar.

Regarding the grammar, I have no strong opinions, although using the 
'class' keyword, as in "super(class,self)" has a nice ring to it.  But at 
least now you can talk about the *idea* of an automatic super, without 
arguing about sys._getframe() or other denigrated hacks.

You're welcome.  :)



More information about the Python-3000 mailing list