TypedDict class is an Incompatible Type for function expecting Dict

Question:

I created the below TypedDict class;

class Appinfo(TypedDict):
    appid: int
    extended: dict[str, Any]
    config: dict[str, Any]
    depots: dict[str, Any]
    ufs: dict[str, Any]

class SteamAppInfo(TypedDict):
    appid: int
    data: dict[str, Appinfo]

In my application I’m passing a variable of this class to a function expecting a dict;

    def dict_get_key_list(data: dict[str, Any], key_list: list[str]) -> Any:
        """returns a dict value or None based on list of nested dict keys provided"""
        try:
            return reduce(operator.getitem, key_list, data)
        except KeyError:
            return None

The code itself runs fine as for all intents and purposes, SteamAppInfo is a dictionary. However, MyPy is giving me the error below;

error: Argument 1 to "dict_get_key_list" of "Utils" has incompatible type "SteamAppInfo"; expected "Dict[str, Any]"

How do I get MyPy to recognise that what’s being passed is a dictionary without having to list all of the TypedDicts I’ve created as possible variable types or setting the variable type to Any?

Asked By: rkr87

||

Answers:

From the mypy documentation:

A TypedDict object is not a subtype of the regular dict[...] type (and vice versa), since dict allows arbitrary keys to be added and removed, unlike TypedDict. However, any TypedDict object is a subtype of (that is, compatible with) Mapping[str, object], since Mapping only provides read-only access to the dictionary items:

So use data: Mapping[str, Any] instead of data: dict[str, Any].

Answered By: Barmar
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.