Misleading errors and confusing behavior with zero-argument `super()` in inner functions
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 36k
- PR merge metrics
- PR metrics pending
Description
Bug report
See also: #90333.
super() exhibits behavior subtly broken in different ways when used in inner functions with zero arguments:
class Foo:
def __init__(self):
def inner():
print(str(super()))
inner()
>>> Foo()
...
RuntimeError: super(): no arguments
and in inner functions that do take arguments:
class Foo:
def __init__(self):
def inner(_=1):
print(str(super()))
inner()
>>> Foo()
...
TypeError: super(type, obj): obj must be an instance or subtype of type
...unless the first argument is None:
class Foo:
def __init__(self):
def inner(_=None):
print(str(super()))
inner()
>>> Foo()
<super: <class 'Foo'>, NULL>
but then method lookup doesn't work as expected (raises AttributeError trying to access any method not defined on NoneType).
__class__ gets injected into the code properly, it just seems that super() assumes the first argument of the immediately enclosing function is self.
It seems to me that:
- The best case would be for this behavior to look up
selffrom the same scope__class__was defined in rather than the immediate scope wheresuper()was invoked, making it possible to use zero-argument super in nested functions - If that is not possible, a consistent error should be raised regardless of the arguments to the immediately-enclosing function; all three of those examples should communicate that zero-argument super in nested functions is not supported. Especially the first error message is misleading, since it describes two-argument
super. - If zero-argument
super()is not made to work in nested functions, this quirk should be clearly documented. Right now the documentation only vaguely hints at problems:Also note that, aside from the zero argument form, super() is not limited to use inside methods.
I'd be happy to work on this but am concerned there might be a lot of edge-cases that are not obvious to me (like the workaround for super() being called from the C-API before a MAKE_CELL).
Your environment
- CPython versions tested on: 3.10.7, 3.12 dev @ eae7dad40255bad42e4abce53ff8143dcbc66af5
- Operating system and architecture: Linux x86_64
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Begin by reproducing the three nested-function examples in the issue and comparing their zero-argument super() behavior. Read the zero-argument super() documentation and investigate the mentioned class, MAKE_CELL, and C-API interactions. Done requires an agreed behavior, consistent errors or supported lookup semantics, and corresponding regression coverage or documentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100