[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Plumbing behind super()

I was wrong in the last email because I accidentally in super_gettro instead of super_init.

Just for some helper context:

>>> class Foo:
...   pass
>>> class Bar(Foo):
...   def __init__(self):
...     super().__init__()
...     self.a = 2
>>> dis(Bar)
Disassembly of __init__:
  3           0 LOAD_GLOBAL              0 (super)
              2 CALL_FUNCTION            0
              4 LOAD_ATTR                1 (__init__)
              6 CALL_FUNCTION            0
              8 POP_TOP

  4          10 LOAD_CONST               1 (2)
             12 LOAD_FAST                0 (self)
             14 STORE_ATTR               2 (a)
             16 LOAD_CONST               0 (None)
             18 RETURN_VALUE

I originally set a breakpoint at super_getattro so I was seeing it getting the self pointer from TOS, but I think I needed super_init--especially since that is getting called from a CALL_FUNCTION opcode, instead of super_getattro and it's LOAD_ATTR. I think that's from the self.a assignment.

The super_init code melted my brain! It looks like it's grabbing the current frame and interrogating it to find __class__. I think I have the same amount of visibility and similar structure in what I'm writing but... woah.