osdir.com


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

Plumbing behind super()


On Thu, Jun 27, 2019, at 23:32, adam.preble at gmail.com wrote:
> On Thursday, June 27, 2019 at 8:30:21 PM UTC-5, DL Neil wrote:
> > I'm mystified by "literally given nothing".
> 
> I'm focusing there particularly on the syntax of writing "super()" 
> without any arguments to it. However, internally it's getting fed stuff.

Any function which is defined inside a class and accesses 'super' is provided a 'cell variable' (i.e. nonlocal) called __class__, which super inspects on the stack to identify the class (along with finding the self argument)

>>> class C:
...  def foo(): super
...
>>> C.foo.__closure__
(<cell at 0x0000024105737168: type object at 0x00000241036CD0D8>,)
>>> C.foo.__code__.co_freevars
('__class__',)

You can also provide this cell manually by defining it as a nested function inside another function which has a local variable __class__.

>>> def bar():
...  __class__ = C
...  return lambda self: super()
...
>>> bar()(C())
<super: <class 'C'>, <C object>>

You can see all this happening in https://github.com/python/cpython/blob/3.8/Objects/typeobject.c#L7812