python / python/mypy

Generic TypedDict and inferring return value

Offen
#17,753 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

I was working on some code that needs to be passed a generic TypedDict, like this:

from typing import TypeVar, TypedDict, Generic

T = TypeVar("T")

ReturnValue = TypeVar("ReturnValue")


class Option(TypedDict, Generic[ReturnValue]):
    name: str
    value: ReturnValue


class Menu:
    def ask(self, text: str, options: list[Option[T]]) -> T:
        return options[0]["value"]

And the usage would be this:

value = Menu().ask("text", [{"value": 123, "name": "abc"}])

reveal_type(value)

In this case the value type should int, but unfortunately I get this error:

main.py:18: error: Need type annotation for "value"  [var-annotated]
main.py:18: error: Argument 2 to "ask" of "Menu" has incompatible type "list[dict[str, int]]"; expected "list[Option[Never]]"  [arg-type]

Playground: https://mypy-play.net/?mypy=latest&python=3.12&flags=verbose%2Cstrict&gist=9a8643b51a69f6d60ab5b0b482e10865

This seems to be working well in pyright 😊

Also I didn't find yet a workaround, changing the class to this:

class Menu:
    def ask(self, text: str, options: list[dict[str, T]]) -> T:
        return options[0]["value"]

Almost works, but for example in the case above it would infer the type as object 😊

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 mit dem minimalen Python-Beispiel und der verknüpften mypy-play-Reproduktion, um die aktuellen Fehler bei der Inferenz zu bestätigen. Verfolge die Typinferenz bei generischen TypedDict-Argumenten und überprüfe anschließend, dass das Beispiel value als int inferiert, ohne eine Annotation zu erfordern oder einen Fehler wegen eines inkompatiblen Arguments zu melden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
tooling
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
42/100

Neue Issues direkt in Ihr Postfach

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