python / python/mypy

Mypy doesn't recognize that different string literals in if/else statement match a union of string literals

Offen
#18,442 2 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug topic-join-v-union
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

When a function has a type signature like def foo(bar: Literal["a", "b"]) -> None: ... mypy throws an error if the argument passed in can be either a or b as it implies a general string.

To Reproduce

from typing import Literal

CHOICE = bool(...)

def foo(bar: Literal["a", "b"]) -> None: ...

def main() -> None:
    bar = "a"
    if CHOICE:
        bar = "b"

    foo(bar)

Expected Behavior

It would be nice if mypy recognized that bar here could only be Literal["a"] or Literal["b"], i.e Literal["a", "b"].

Actual Behavior

mre.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "Literal['a', 'b']" [arg-type]

Your Environment

  • Mypy version used: 1.14.1
  • Mypy command-line flags: Default
  • Mypy configuration options from mypy.ini (and other config files): Default
  • Python version used: 3.13

Context

This came up because of a recent change in typeshed https://github.com/python/typeshed/pull/12181 which causes this pip code to trigger a mypy error: https://github.com/pypa/pip/blob/24.3.1/src/pip/_internal/utils/unpacking.py#L179

I assume this issue of different implicit Literal / str types inside branches has been discussed before but I couldn't find it searching through the GitHub issues.

x-ref: https://github.com/pypa/pip/pull/13148

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere die Diagnose in mre.py mit mypy 1.14.1 anhand des gezeigten Beispiels für eine Zuweisung in einem Branch und verfolge anschließend, wie der Type Checker bar über die if/else-Pfade hinweg inferiert. Verwende die pip-Referenz unpacking.py als realitätsnahen Fall; abgeschlossen ist die Aufgabe, wenn beide Beispiele die Union von String-Literalen ohne einen incompatible-type-Fehler akzeptieren.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
52/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.