python / python/mypy

`match-case` does not work correctly with Literals vs Enums

Abierto
#20,142 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug topic-enum topic-literal-types topic-match-statement
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

from enum import StrEnum
from typing import Literal, assert_never, reveal_type

class Color(StrEnum):
    RED = "r"
    GREEN = "g"
    BLUE = "b"

def test_literal_as_enum(x: Literal["g"] = "g") -> None:
    match x:
        case Color.RED:
            assert_never(x)
        case Color.GREEN:
            reveal_type(x)
        case Color.BLUE:
            assert_never(x)
        case _:
            assert_never(x)

def test_enum_as_litearl(y: Literal[Color.BLUE] = Color.BLUE) -> None:
    match y:
        case "r":
            assert_never(y)
        case "g":
            assert_never(y)
        case "b":
            reveal_type(y)
        case _:
            assert_never(y)

test_literal_as_enum()  # selects green branch at runtim
test_enum_as_litearl()  # selects blue branch at runtime

Expected no errors, but mypy-playground reports

main.py:14: error: Statement is unreachable  [unreachable]
main.py:18: error: Argument 1 to "assert_never" has incompatible type "Literal['g']"; expected "Never"  [arg-type]
main.py:27: error: Statement is unreachable  [unreachable]
main.py:29: error: Argument 1 to "assert_never" has incompatible type "Literal[Color.BLUE]"; expected "Never"  [arg-type]

Related: https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456
Also: #16327, #17162, #19616 (but none of these is specifically about match-case)

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

Empieza reproduciendo los errores reportados en el ejemplo enlazado de mypy-playground con Python 3.12, master y warn-unreachable habilitados. Rastrea el estrechamiento de match-case para cadenas Literal y miembros de StrEnum y usa después las comprobaciones assert_never y reveal_type mostradas como criterios de finalización: el ejemplo no debería producir ningún error.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
42/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.