Type-checking generic of enum.Meta with a custom metaclass fails with code that runs, and passes with code that doesn't run.
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 20.6k
- Forks
- 3.3k
- Merge medio
- 1 d 18 h
- PR fusionados (30 d)
- 54
Descripción
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
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza ejecutando las dos reproducciones enlazadas de mypy-play con Python 3.9 y mypy master, comparando la versión que rechaza la llamada inválida a Carrier con la versión que se ejecuta, pero la acepta. Después, rastrea cómo mypy gestiona las subclases genéricas de enum.Enum y las clases personalizadas de EnumMeta, y añade cobertura de regresión para el error de tipo esperado.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- devtools
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100