python / python/cpython

Misleading errors and confusing behavior with zero-argument `super()` in inner functions

未关闭
#98,349 2 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

interpreter-core type-bug
主要语言
Python
星标
77.2k
派生
36k
PR 合并指标
PR 指标待抓取

描述

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 self from the same scope __class__ was defined in rather than the immediate scope where super() 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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先重现 issue 中的三个嵌套函数示例,并比较它们的无参数 super() 行为。阅读无参数 super() 的文档,并调查提到的 class、MAKE_CELL 和 C-API 交互。完成的标准是确定一致的行为、统一的错误或受支持的查找语义,以及相应的回归覆盖或文档。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
compilers
Issue 类型
缺陷
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。