Repository navigation
super() allocates memory, not possible to call a supermethod without heap allocation #2719
Description
Activity
You could do
self.mysuper = super()during__init__and then callself.mysuper.func()later.It looks like the only way of making it allocation free is to add a new bytecode and change the compiler.
For example, the line of code
super().foo(1)would change from the current bytecode:LOAD_GLOBAL super LOAD_GLOBAL __class__ LOAD_FAST 0 CALL_FUNCTION n=2 nkw=0 # this creates a super object LOAD_METHOD foo # this loads the foo method from the parent LOAD_CONST_SMALL_INT 1 CALL_METHOD n=1 nkw=0 POP_TOPto something like:
LOAD_GLOBAL __class__ LOAD_FAST 0 LOAD_SUPER_METHOD foo # this loads the foo method directly LOAD_CONST_SMALL_INT 1 CALL_METHOD n=1 nkw=0 POP_TOPThat requires a fair bit of addition to the compiler to detect this pattern and emit different code, and then a new bytecode in the VM. A lot of bytes for such an improvement/optimisation.
I'd suggest doing what @dhylands suggests, pre-creating the super object.
It looks like the only way of making it allocation free is to add a new bytecode and change the compiler.
Yes, I'd definitely think this should be handled by the compiler.
That requires a fair bit of addition to the compiler to detect this pattern and emit different code, and then a new bytecode in the VM. A lot of bytes for such an improvement/optimisation.
I'm not familiar enough with the compiler, but wouldn't think it would add that much code. And super() already appears to be handled (somewhat) specially, based e.g. on #1158. But the whole point is that claim with which any MicroPython presentation starts - that it can call a method without allocating memory - becomes not true as soon as it comes to calling a supermethod, and that's basic OO pattern. I'd think it's worth fixing that.
I'd suggest doing what @dhylands suggests, pre-creating the super object.
Of course I workaround that, even without wasting local var slots, using Python 1.x style super method call:
SuperClass.method(self, params). The talk is about fixing it implementation-side to allow efficient idiomatic Python3.If super() is being revisited I should mention that I've encountered rare cases where it returned an incorrect object. This only happened in the
__init__()method and in large programs; despite effort I never managed to produce a small reproducible test case. I worked round the problem usingSuperClass.__init__(self, args).
Alas I failed to record what it returned but it may have beenNone.super() method calls now work without allocating heap memory.
While uPy can call a method without allocating memory, it can't call a supermethod in such way, because super() allocates memory. Can anything be done about that?