python / python/mypy

Interaction between an `enum` alias and `assert_never()` seems to fail

Aperta
#21,117 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

Bug Report

If you have defined an enum with some values and an extra value which is an alias of an already defined one, the completeness-check using assert_never(...) does not work as (I) expected.

To Reproduce

# file mypy_enum_alias.py
import enum

from typing import assert_never

class Version(enum.Enum):
    V1 = enum.auto()
    V2 = enum.auto()
    DEFAULT = V2

def print_version(version: Version) -> None:
    match version:
        case Version.V1:
            print("Version 1")
        case Version.V2:
            print("Version 2")
        case _:
            assert_never(version)

print(*(repr(v) for v in Version))
$ mypy mypy_enum_alias.py

Expected Behavior

Success: no issues found in 1 source file

Actual Behavior

mypy_enum_alias.py:18: error: Argument 1 to "assert_never" has incompatible type "Literal[Version.DEFAULT]"; expected "Never"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: mypy 1.19.1 (compiled: yes)
  • Mypy command-line flags: (none)
  • Mypy configuration options from mypy.ini (and other config files):
    # pyproject.toml
    # ...
    [tool.mypy]
    plugins = [
        "pydantic.mypy"
    ]
    # ...
    
  • Python version used: Python 3.13.9

If you run the script, Python bravely emits only the (two) non-aliased values:

$ python mypy_enum_alias.py
<Version.V1: 1> <Version.V2: 2>

If mypy considers all "names" of an enum, it renders the completeness check useless IMHO.

I could add the following code snippet just before case _: ... as a work-around, but that would just be pathetic:

        case Version.DEFAULT:
            pass

But for the rest I'm quite happy with mypy. A great helper in early bug detection!

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 con il riproduttore in mypy_enum_alias.py ed esegui mypy senza flag da riga di comando per confermare la diagnosi errata di assert_never. Traccia il modo in cui mypy gestisce gli alias degli enum durante il controllo di esaustività di match, quindi aggiungi o aggiorna la copertura in modo che l'esempio riporti un esito positivo senza richiedere un caso Version.DEFAULT.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
68/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.