python / python/mypy

mypyc: cannot query ClassVar members in __init_subclass__ methods of compiled classes

Offen
#14,188 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

Bug Report

I'm using __init_subclass__ in a class that I'm compiling with mypyc (mostly to avoid using metaclasses), and I'm finding that I'm unable to check the types of the class members within that method. If I annotate a class member with ClassVar[SomeType], then it isn't in available in the class __dir__() yet during __init_subclass__; but if I leave off the ClassVar annotation, then all members are just an instance of <class 'getset_descriptor'>, and I'm unable to differentiate any of them

To Reproduce

compile this module with mypyc:

# test_module.py
from typing import ClassVar


def _print_public_attrs(cls: type) -> None:
    for n in dir(cls):
        if not n.startswith("_"):
            v = getattr(cls, n)
            print(n, v, type(v), isinstance(v, SomeDescriptor))


class SomeThing:
    pass


class SomeDescriptor:
    def __get__(
        self, instance: object | None, owner: type | None = None
    ) -> "SomeDescriptor" | SomeThing:
        return SomeThing() if instance is not None else self


class Sup:
    def __init_subclass__(cls) -> None:
        _print_public_attrs(cls)


class Sub(Sup):
    name1 = SomeDescriptor()
    name2: ClassVar[SomeDescriptor] = SomeDescriptor()


print("-----")
_print_public_attrs(Sub)

Then import it:

$ python -c "import test_module"
name1 <attribute 'name1' of 'Sub' objects> <class 'getset_descriptor'> False
-----
name1 <attribute 'name1' of 'Sub' objects> <class 'getset_descriptor'> False
name2 <psygnal._test.SomeDescriptor object at 0x1093926e0> <class 'psygnal._test.SomeDescriptor'> True

.... note that name2 (with the ClassVar annotation) isn't available yet during __init_subclass__, but name1 (without the ClassVar annotation) isn't yet an instance of SomeDescriptor during __init_subclass__.

Expected Behavior

I was hoping for some way to check the types of objects on the Sub class during __init_subclass__.

Your Environment

  • Mypy version used: mypy 0.991 (compiled: yes)
  • Mypy command-line flags: mypyc test_module.py
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.10

thank you!!

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

Beginne damit, das Verhalten aus test_module.py mit dem angegebenen mypyc-Befehl zu reproduzieren, wobei der Schwerpunkt auf dem init_subclass-Einstiegspunkt sowie den ClassVar- und Deskriptor-Mitgliedern liegt. Vergleiche die während der Erstellung der Unterklasse sichtbaren Attribute mit denen, die nach dem Import sichtbar sind; abgeschlossen ist die Aufgabe, wenn die erwartete Möglichkeit, die Klassenmitglieder zu unterscheiden, unterstützt wird oder ihre Einschränkung eindeutig geklärt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

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

Neue Issues direkt in Ihr Postfach

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