python / python/mypy

Type-checking generic of enum.Meta with a custom metaclass fails with code that runs, and passes with code that doesn't run.

Abierto
#11,970 4 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug topic-enum
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

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. 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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.