Type-checking generic of enum.Meta with a custom metaclass fails with code that runs, and passes with code that doesn't run.
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 20.6k
- Fork
- 3.3k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Bug Report
Trying to type-check generic types of a bound enum.Enum (with a custom metaclass) only catches type errors when the actual code fails to run; but doesn't detect the issues when the code runs.
To Reproduce
The code in this gist properly detects the type error while calling Carrier(Foo, Bar.item1):
import enum
from dataclasses import dataclass
from typing import TypeVar, Generic, Type
M = TypeVar('M', bound="MyEnum")
class Meta(enum.EnumMeta):
pass
class MyEnum(metaclass=Meta):
...
class Foo(enum.Enum, MyEnum):
item1 = "1"
item2 = "2"
class Bar(enum.Enum, MyEnum):
item1 = "1"
item2 = "2"
@dataclass
class Carrier(Generic[M]):
meta: Type[M]
instance: M
Carrier(Foo, Foo.item1)
Carrier(Foo, Bar.item1) # should fail
However that code fails to run with
Traceback (most recent call last):
File "/home/manu/src/tmp/enums.py", line 14, in <module>
class Foo(enum.Enum, MyEnum):
File "/usr/lib/python3.10/enum.py", line 173, in __prepare__
member_type, first_enum = metacls._get_mixins_(cls, bases)
File "/usr/lib/python3.10/enum.py", line 619, in _get_mixins_
raise TypeError("new enumerations should be created as "
TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`
In order for the code to run we have to swap the positions of enum.Enum and MyEnum in both Foo and Bar (see the second gist); but then mypy fails to catch the type-error.
Your Environment
- Mypy version used: master and 0.931
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.9
- Operating system and version:
Linux pavla 5.15.12-1-MANJARO #1 SMP PREEMPT Wed Dec 29 18:08:07 UTC 2021 x86_64 GNU/Linux
Previous discussion in gitter: https://gitter.im/python/typing?at=61dab43cf5a3947800f73b71
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo le due riproduzioni collegate di mypy-play con Python 3.9 e mypy master, confrontando la versione che rifiuta la chiamata non valida a Carrier con la versione che viene eseguita ma la accetta. Poi analizza come mypy gestisce le sottoclassi generiche di enum.Enum e le classi EnumMeta personalizzate, e aggiungi una copertura di regressione per l’errore di tipo previsto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- devtools
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100