python / python/mypy

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

Aperta
#14,188 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

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!!

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 il comportamento di test_module.py con il comando mypyc mostrato, concentrandoti sull'entry point init_subclass e sui membri ClassVar e descrittori. Confronta gli attributi visibili durante la creazione della sottoclasse con quelli visibili dopo l'importazione; il lavoro è completato quando la capacità prevista di distinguere i membri della classe è supportata oppure la sua limitazione è chiaramente risolta.

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à
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
38/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.