python / python/mypy

metaclass instance variable should be seen as class ClassVar

Offen
#16,967 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

When a metaclass has an instance variable, the class (that is an instance of the metaclass) should have that variable as a ClassVar

The class is an instance of the metaclass.

To Reproduce

from typing import Any
from typing_extensions import reveal_type


class M(type):
    """ ensure classes of this type have ClassVar `x` """
    x: list[int]

    def __new__(mcs, name: str, bases: tuple[type, ...], dct: dict[str, Any]) -> "M":
        # construct class
        new_class = super().__new__(mcs, name, bases, dct)
        if "x" not in dct:
            new_class.x = [2]
        return new_class


class C(metaclass=M):
    x = []  # mypy reports "need type annotation" when it should know "ClassVar[list[int]]"


class D(metaclass=M):
    pass

    def f(self) -> None:
        self.x = [5]  # no type error reported
        # should report assigning instance variable over class variable


class E(metaclass=M):
    x = 3  # no type error reported - expected '"Literal[3]" is incompatible with "list[int]"'


print(C.x)  # []
print(D.x)  # [2]
print(E.x)  # 3

reveal_type(C.x)  # mypy: correctly sees list[int]  pyright: list[Unknown]

reveal_type(D.x)  # list[int]

reveal_type(E.x)  # mypy: list[int]  pyright: int
# I don't think it matters what this reports,
# because there should be a type error at assignment above.

Expected Behavior

in code comments

Actual Behavior

in code comments

Your Environment

  • Mypy version used: 1.8.0
  • Mypy command-line flags: --strict
  • Python version used: 3.10

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Führe den bereitgestellten Reproducer mit mypy 1.8.0 und --strict aus und vergleiche anschließend die Diagnosen und die aufgedeckten Typen mit den erwarteten Ergebnissen in den Codekommentaren. Verfolge den Typprüfpfad für Instanzvariablen von Metaklassen und Klassenkörper; abgeschlossen ist die Aufgabe, wenn C.x, D.x und E.x das beabsichtigte ClassVar-bezogene Verhalten und die Zuweisungsfehler erzeugen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.