Ich habe einige Zeit damit verbracht und komme nicht dahinter – Beispiel für ein Problem:
Code: Select all
from typing import Literal, NotRequired, TypedDict
class Movie(TypedDict):
Title: str
Runtime: str
Awards: str
class MovieData(TypedDict):
Awards: NotRequired[str]
Runtime: NotRequired[str]
def get_movie_field(movies: list[Movie], field: Literal['Awards', 'Runtime']) -> dict[str, MovieData]:
return {movie['Title']: {field: movie[field]} for movie in movies}
Code: Select all
# Check with mypy 1.14.0:
PS> mypy --strict .\program.py
program.py:13: error: Expected TypedDict key to be string literal [misc]
Found 1 error in 1 file (checked 1 source file)
Ich habe eine Reihe verschiedener Permutationen ausprobiert, beispielsweise das Sicherstellen von Feldern Entspricht einem der Literalwerte vor dem Diktatverständnis, aber nichts scheint zu helfen.
Mir gefällt die Lösung von @chepner. Leider konnte ich nicht herausfinden, wie ich es mit mypy im strikten Modus zum Laufen bringen kann – anhand seines Beispiels:
Code: Select all
def get_movie_field(movies, field):
return {movie['Title']: {field: movie[field]} for movie in movies}
Code: Select all
PS> mypy --strict program.py
program.py:18: error: Function is missing a type annotation [no-untyped-def]
Found 1 error in 1 file (checked 1 source file)
Bei der Durchsicht der Mypy-Dokumente habe ich das letzte get_movie_field funktioniert wie folgt – aber es behebt das Problem immer noch nicht:
Code: Select all
# @chepner's full solution updated with type annotations for
# last get_movie_field:
from typing import Literal, NotRequired, TypedDict, overload
class Movie(TypedDict):
Title: str
Runtime: str
Awards: str
class MovieData(TypedDict):
Awards: NotRequired[str]
Runtime: NotRequired[str]
@overload
def get_movie_field(movies: list[Movie], field: Literal['Awards']) -> dict[str, MovieData]:
...
@overload
def get_movie_field(movies: list[Movie], field: Literal['Runtime']) -> dict[str, MovieData]:
...
def get_movie_field(movies: list[Movie], field: Literal['Awards']|Literal['Runtime']
) -> dict[str, MovieData]:
return {movie['Title']: {field: movie[field]} for movie in movies}
Code: Select all
PS> mypy --strict program.py
program.py:19: error: Expected TypedDict key to be string literal [misc]
Found 1 error in 1 file (checked 1 source file)
Code: Select all
from typing import Literal, NotRequired, TypedDict
class Movie(TypedDict):
Title: str
Runtime: str
Awards: str
class MovieData(TypedDict):
Awards: NotRequired[str]
Runtime: NotRequired[str]
def create_MovieData(key: str, value: str) -> MovieData:
"""Creates a new TypedDict using a given key and value."""
if key == 'Awards':
return {'Awards': value}
elif key == 'Runtime':
return {'Runtime': value}
raise ValueError(f"Invalid key: {key}")
def get_movie_field(movies: list[Movie], field: Literal['Awards', 'Runtime']) -> dict[str, MovieData]:
return {movie['Title']: create_MovieData(field, movie[field]) for movie in movies}
Code: Select all
PS> mypy --strict program.py
Success: no issues found in 1 source file