Reputation: 6045
I have the following dictionary representing a person that could be one of many variations. Here are just a few:
person = {"name": "Johnny"}
person = {"name": "Johnny", "age": 25}
person = {"name": "Johnny", "age": 25, "active": True}
I'm extracting certain keys and using them to print a statement. The problem arises in the type hints, where I'm getting an error saying Incompatible types in assignment (expression has type "object", variable has type "Optional[str]")
when I run mypy on the script:
name: Optional[str] = person.get("name") # mypy error here
age: Optional[int] = person.get("age") # mypy error here
if name and age:
print(f"In 5 years, {name} will be {age + 5} years old")
To solve this the mypy_extensions.TypedDict
type seemed promising, but it appears I can't have missing or extra keys:
from mypy_extensions import TypedDict
PersonDict = TypedDict("PersonDict", {"name": str, "age": int})
# ERROR: Key 'age' missing for TypedDict "PersonDict"
person: PersonDict = {"name": "Johnny"}
# ERROR: Extra key 'active' for TypedDict "PersonDict"
person: PersonDict = {"name": "Johnny", "age": 25, "active": True}
Is there anyway to define types for specific keys in a dictionary, even if the keys in that dictionary are dynamic?
Upvotes: 4
Views: 3480
Reputation: 8244
Adding total=False
to your TypedDict will allow missing keys:
PersonDict = TypedDict("PersonDict", {"name": str, "age": int}, total=False)
https://mypy.readthedocs.io/en/latest/more_types.html#totality
Allowing additional keys not in the schema does not seem possible.
Upvotes: 6