Looking at the documentation of the super
type in Python 3.5, it notes that super(…)
is the same as super(__class__, «first argument to function»)
. To my surprise, I wrote a method that returned __class__
– and it actually worked:
>>> class c:
... def meth(self): return __class__
...
>>> c().meth()
<class '__main__.c'>
Apparently, __class__
is a free variable assigned by the closure of the function:
>>> c.meth.__code__.co_freevars
('__class__',)
>>> c.meth.__closure__
(<cell at 0x7f6346a91048: type object at 0x55823b17f3a8>,)
I'd like to know under what circumstances that free variable is associated in the closure. I know that if I assign a function to a variable as part of creating a class it doesn't happen.
>>> def meth2(self): return __class__
...
>>> meth2.__code__.co_freevars
()
Even if I create a new class and as part of that creation assign some attribute to meth2
, meth2
doesn't somehow magically gain a free variable that gets filled in.
That's unsurprising, because part of this appears to depend on the lexical state of the compiler at the time that the code is compiled.
I'd like to confirm that the conditions necessary for __class__
to be treated as a free variable are simply:
- A reference to
__class__
in the code block; and - The
def
containing the__class__
reference is lexically within aclass
declaration block.
I'd further like to understand what the conditions necessary for that variable getting filled in correctly are. It appears – at least from the Python 3.6 documentation – that something like type.__new__(…)
is involved somehow. I haven't been able to understand for sure how type
comes into play and how this all interacts with metaclasses that do not ultimately call type.__new__(…)
.
I'm particularly confused because I didn't think that at the time the namespace's __setattr__
method was used to assign the attribute containing the method to the method function (as it exists on the ultimately-constructed class object). I know that this namespace object exists because it was either constructed implicitly by the use of the class
statement, or explicitly by the metaclass's __prepare__
method – but as best I can tell, the metaclass constructs the class object that populates __class__
after the function object is set as a value within the class namespace.