This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients lanfon72, ncoghlan, xiang.zhang
Date 2016-12-30.14:01:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1483106494.87.0.511547459455.issue29114@psf.upfronthosting.co.za>
In-reply-to
Content
Right, this isn't actually a bug, it just requires a bit more creativity to bind and resolve `__class__` correctly when defining the replacement method.

Here's what happens normally with zero-argument super():

>>> class A:
...     def f(self):
...         print(__class__)
... 
>>> A().f()
<class '__main__.A'>
>>> A.f.__closure__
(<cell at 0x7f0ea25f1f48: type object at 0x55ea30974318>,)
>>> inspect.getclosurevars(A.f)
ClosureVars(nonlocals={'__class__': <class '__main__.A'>}, globals={}, builtins={'print': <built-in function print>}, unbound=set())

And here's one way of emulating the __class__ resolution part:

>>> def make_method():
...     __class__ = A
...     def fn(self):
...         print(__class__)
...     return fn
... 
>>> A.fn = make_method()
>>> A().fn()
<class '__main__.A'>

And applying that to get zero-argument super() working in a substitute method gives:

>>> class B(A):
...     def f(self):
...         super().f()
... 
>>> B().f() # Normal super()
<class '__main__.A'>
>>> def make_B_method():
...     __class__ = B
...     def fn(self):
...         return super().fn()
...     return fn
... 
>>> B.fn = make_B_method()
>>> B().fn()  # Emulated super()
<class '__main__.A'>
History
Date User Action Args
2016-12-30 14:01:34ncoghlansetrecipients: + ncoghlan, xiang.zhang, lanfon72
2016-12-30 14:01:34ncoghlansetmessageid: <1483106494.87.0.511547459455.issue29114@psf.upfronthosting.co.za>
2016-12-30 14:01:34ncoghlanlinkissue29114 messages
2016-12-30 14:01:34ncoghlancreate