python / python/mypy

Matching on boolean expressions does not narrow based on the content of the boolean expression

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

Dieses Issue hat noch niemand übernommen.

bug topic-match-statement
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

When doing pattern matching with types, the match statement might be more readable than multiple if statements

match (a is None, b is None):
    case (True, True):
        ...
    case (True, False):
        ...
    case (False, True):
        ...
    case (False, False):
        ...

instead of

if a is None and b is None:
    ...
if a is None and b is not None:
    ...
if a is not None and b is None:
    ...
if a is not None and b is not None:
    ...

However, mypy is not able to infer types from the match statements like it is from if statements.

To Reproduce

Infer types using a match statement:

def example_with_match(a: str | None, b: str | None) -> str:
    match (a is None, b is None):
        case (True, True):
            return ""
        case (True, False):
            return b
        case (False, True):
            return a
        case (False, False):
            return a + b

    raise RuntimeError  # unreachable

Gist

Expected Behavior

Like in the equivalent using if statements (there are no mypy errors)

def example_with_if(a: str | None, b: str | None) -> str:
    if a is None and b is None:
        return ""
    if a is None and b is not None:
        return b
    if a is not None and b is None:
        return a
    if a is not None and b is not None:
        return a + b

    raise RuntimeError  # unreachable

Gist

Actual Behavior

whatever.py:6: error: Incompatible return value type (got "str | None", expected "str")  [return-value]
whatever.py:8: error: Incompatible return value type (got "str | None", expected "str")  [return-value]
whatever.py:10: error: Unsupported operand types for + ("str" and "None")  [operator]
whatever.py:10: error: Unsupported left operand type for + ("None")  [operator]

Your Environment

  • Mypy version used: 1.15.0
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files):
[tool.mypy]
check_untyped_defs = true
no_implicit_optional = true
show_error_codes = true
warn_redundant_casts = true
warn_unreachable = true
python_version = "3.12"
ignore_missing_imports = true
  • Python version used: 3.12.8

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

Beginnen Sie damit, mypy auf dem bereitgestellten Python-Reproduktionsbeispiel für eine match-Anweisung auszuführen und es mit dem entsprechenden Beispiel für eine if-Anweisung zu vergleichen. Das Issue nennt weder eine Quelldatei noch einen Testpfad. Lokalisieren Sie daher den Einstiegspunkt für die Typverengung beim Pattern Matching und die relevanten Tests. Als erledigt gilt die Aufgabe, wenn alle vier Zweige a und b, wo zutreffend, auf str verengen, ohne Fehler.

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
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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