erroneous type mismatch with `Union` and `Literal` (false positive)
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
Mypy does not sufficiently simplify Unions and Literals before some type checks (the reproduction case uses assert_type(), but assignments and calls will also trigger the issue). The result is false positive errors.
To Reproduce
from __future__ import annotations
from enum import (
Enum,
auto,
)
from typing import (
Literal,
Union,
)
from typing_extensions import (
assert_type,
reveal_type,
)
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
RedKwds = Literal['RED', 'R']
GreenKwds = Literal['GREEN', 'G']
BlueKwds = Literal['BLUE', 'B']
ColorKwds = Union[RedKwds, GreenKwds, BlueKwds]
RedSpec = Union[Literal[Color.RED], RedKwds]
GreenSpec = Union[Literal[Color.GREEN], GreenKwds]
BlueSpec = Union[Literal[Color.BLUE], BlueKwds]
ColorSpec = Union[Color, ColorKwds] # ⎱ these are entirely
RGBSpec = Union[RedSpec, GreenSpec, BlueSpec] # ⎰ equivalent types
rgb_spec: RGBSpec
assert_type(rgb_spec, ColorSpec) # fails; should be silent # L34
# Expression is of type...
# Union[
# Union[Literal[Color.RED], Literal['RED', 'R']],
# Union[Literal[Color.GREEN], Literal['GREEN', 'G']],
# Union[Literal[Color.BLUE], Literal['BLUE', 'B']]
# ]
# ... not ...
# Union[
# Color,
# Union[
# Literal['RED', 'R'],
# Literal['GREEN', 'G'],
# Literal['BLUE', 'B']
# ]
# ]
reveal_type(rgb_spec) # L50
# Union[
# Literal[Color.RED], Literal['RED'], Literal['R'],
# Literal[Color.GREEN], Literal['GREEN'], Literal['G'],
# Literal[Color.BLUE], Literal['BLUE'], Literal['B']
# ]
# "shaking" the variable (where "shaking" is clearly a no-op) causes
# things to work as expected:
rgb_spec_shaken = (
rgb_spec
if isinstance(rgb_spec, Color) else
rgb_spec
)
assert_type(rgb_spec_shaken, ColorSpec) # passes!
reveal_type(rgb_spec_shaken) # L66
# Union[
# Color,
# Literal['RED'], Literal['R'],
# Literal['GREEN'], Literal['G'],
# Literal['BLUE'], Literal['B']
# ]
Expected Behavior
The types are provably equivalent; no error should be raised.
Actual Behavior
Mypy does not sufficiently simplify the types, resulting in an erroneous "mismatch".
Your Environment
- Mypy version used: 1.9.0, master 2024-04-22
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.8, 3.12
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 la riproduzione mypy-play dell'issue con i casi assert_type() e reveal_type() mostrati, in particolare le righe 34 e 50, quindi esamina i percorsi di semplificazione e compatibilità dei tipi coinvolti in questi controlli. Il lavoro è completato quando tipi Union e Literal equivalenti non producono più una mancata corrispondenza e il tipo rivelato visualizzato viene semplificato correttamente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- tooling
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100