python / python/mypy

Type narrowing for dict.get("key") is not None

Offen
#14,766 2 Kommentare 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature topic-type-narrowing
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

See Code and Explanation below

To Reproduce

from typing import TypedDict, Optional


class DictA(TypedDict):
    my_value: str


class DictB(TypedDict, total=False):
    my_optional_dict: Optional[DictA]


def test(arg: DictB) -> None:
    if arg.get("my_optional_dict") is not None:
        print(arg["my_optional_dict"]["my_value"])

Playground Link

Expected Behavior
According to the TypedDict, we have 3 cases for the Key my_optional_dict:

  1. The Dict did not have this Key (indicated by total=False
  2. The Value of this Key is None
  3. The Value of this Key is a DictA

If we look at the if in the test function, it does 2 things:

  1. Check if the Dict contains this Key
  2. Check if the value is not None

This means, that the my_optional_dict of arg is always of the type DictA, so mypy should not see a problem here.

Actual Behavior

main.py:14: error: Value of type "Optional[DictA]" is not indexable  [index]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.0.0
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11.1

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

Beginne damit, den bereitgestellten TypedDict-Reproduzierer mit mypy anhand des angegebenen Python 3.11-Beispiels und ohne Konfigurationsflags auszuführen. Verfolge, wie der Typechecker arg.get("my_optional_dict") nach der None-Prüfung eingrenzt, und füge anschließend einen auf test() basierenden Regressionstest hinzu, der ohne einen Indexierbarkeitsfehler erfolgreich durchläuft.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
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.