CodingFrog
CodingFrog

Reputation: 1655

How to set the python type hinting for a dictionary variable?

Let say I have a dictionary:

from typing import Dict

v = { 'height': 5, 'width': 14, 'depth': 3 }

result = do_something(v)

def do_something(value: Dict[???]):
    # do stuff

How do I declare the dictionary type in do_something?

Upvotes: 101

Views: 155139

Answers (3)

Ders
Ders

Reputation: 1732

It depends on how well-defined your dictionary is.

Maybe there is a dictionary where you don't really know what it contains or will contain, but at least you know the keys should be string and the values should be boolean.

def do_something(value: dict[str, bool]):
    pass

However, perhaps you actually know very well exactly what keys it should have.

from __future__ import ReadOnly
from typing import Literal, NotRequired, TypedDict


class Movie(TypedDict):
    title: ReadOnly[str]
    year: NotRequired[ReadOnly[int]]


class RatedMovie(Movie):
    # also has fields of Movie
    star_rating: Literal[1, 2, 3, 4, 5]


def do_something(movie: Movie) -> None:
    t = movie["title"]  # we get decent IDE type-hinting here


# and here
movie: Movie = {
    "title": "The Princess Bride",
    "year": 1987,
}


# and here
do_something({"title": "Fight Club"})

See TypedDict.

ReadOnly planned v3.13 (not available). NotRequired from v3.11.


As an aside, I HIGHLY recommend NOT using total=False TypedDicts. This type is very vague and should only be used for dictionaries where every field is optional. Marking individual fields as NotRequired should be heavily favored. Using total=False and using Required is a strange inversion of logic that feels like an antipattern waiting to emerge, although I guess it could save you some typing :)

Upvotes: 8

Hunter Kohler
Hunter Kohler

Reputation: 2695

Python 3.9 on:

Use lowercase dict in the same method as the accepted answer. typing.Dict and similar upper case generic types which mirror built-ins are deprecated due to PEP 585:

def my_func(value: dict[str, int]):
    pass

Upvotes: 73

chepner
chepner

Reputation: 530833

Dict takes two "arguments", the type of its keys and the type of its values. For a dict that maps strings to integers, use

def do_something(value: Dict[str, int]):

The documentation could probably be a little more explicit, though.

Upvotes: 117

Related Questions