python / python/cpython

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

Aperta
#98,349 2 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

interpreter-core type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo i tre esempi di funzioni annidate nell'issue e confrontando il loro comportamento di super() senza argomenti. Leggi la documentazione di super() senza argomenti e analizza le interazioni menzionate tra class, MAKE_CELL e C-API. Il lavoro è completato quando sono definiti un comportamento concordato, errori coerenti o una semantica di lookup supportata, insieme alla relativa copertura di regressione o documentazione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
compilers
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.