[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