python / python/mypy

super() is analyzed differently from super(C, self) in generic subclass context

Aperta
#13,039 3 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-inheritance topic-type-variables
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug Report

Consider a minimal reproducing example, based on one from #7362

from typing import TypeVar

T = TypeVar('T', str, int)

class C(list[T]):
    def pop_item(self, key: int) -> T:
        reveal_type(super().pop(key))
        return super().pop(key)

(https://mypy-play.net/?mypy=0.961&python=3.10&gist=ab00ab8ee474443b979cb00ea4284946)

main.py:7: note: Revealed type is "T`1"
main.py:8: error: Incompatible return value type (got "T", expected "str")
main.py:8: error: Incompatible return value type (got "T", expected "int")

This is clearly unexpected, as this should work normally. However, if instead of writing super(), we write super(C, self), which is exactly equivalent syntactically in Python 3, we get

from typing import TypeVar

T = TypeVar('T', str, int)

class C(list[T]):
    def pop_item(self, key: int) -> T:
        reveal_type(super(C, self).pop(key))
        return super(C, self).pop(key)

(https://mypy-play.net/?mypy=0.961&python=3.10&gist=44206838005bf4acfa264a42eecb0eb5)

main.py:7: note: Revealed type is "builtins.str"
main.py:7: note: Revealed type is "builtins.int"

As expected.

Possible fix

Here, Mypy is analyzing super(), differently from super(C, self), which is syntactically incorrect. If super() would instead be (correctly) parsed as super(C, self) in this case, the problem disappears. Note that this also fixes #7362 and #10130.

I don't know enough about Mypy internals to understand why Mypy does not take super() to be equal to super(C, self) here, but perhaps this could be an easy fix?

2024 edit
This reproduces on 1.8.0 as well.

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 eseguendo l’esempio minimo riproducibile dell’issue in mypy o nei casi mypy-play collegati, confrontando bare super() con super(C, self). Traccia come viene analizzata ciascuna forma nel contesto di una sottoclasse generica. Il lavoro è completato quando entrambe le forme rivelano lo stesso tipo concreto e l’istruzione return passa senza errori di tipo incompatibile.

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

Valutazione

Stack tecnologico
python
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.