Is there a recommended way to make mypy infer that the type is a list or list[Any]?
L1 = cast(list[Any], D1['a']) also works, but this is not so much inferring that being told the type.
Why does it assume Sequence[str] as the type? Is it because it computed a type for D1 to be dict[str, Sequence[str]], with Sequence[str] being the least common type of the values in the definition of D1 that it could guess?
The error doesn’t say “Sequence” but “object”. This tells me mypy infers D1 to be dict[str, object].
You have a value-heterogeneous dictionary. You’d need to declare the variable holding it either as a dict with a union of value types, or as a TypedDict.
Or turn it into a class.
I forgot to quote the mypy message from within vscode. Maybe due to context or perhaps flags that they run it with, the type that it infers for L1 is Sequence[str].
Ok, sure, I could declare the type of the D1 explicitly. In my case the values will be only str | list[Any].
Dicts do not have per-key types. D1 has type dict[str, Sequence[str]] because str is the narrowest type (in some sense) that includes both 'a' and 'b, while Sequence[str] is similarly the narrowest type that includes both [] and 'bbb'. D1[k] will have static type Sequence[str] no matter what (str) value k has.
If you want D1['a'] to have type list, then you can use typing.TypedDict, which lets you specify per-key types, while restricting you to a fixed set of str keys.
Literals present a problem for type inference. Assuming a sufficiently rich library of available types, what type should 2 have?
int
natural
postive_int
even
Literal[2]
Similary, what type should {'a': [], 'b': 'bbb'} have? Is it a dict with string keys? With exactly 2 keys? With 'a' and 'b' specifically as keys? If the keys are part of the type, is 'a' bound to a list of strings? integers? other dicts? Is the length of 'bbb' significant?
It’s a balancing act between inferring a type that prevents values you intended to be ignored, but still allows values “not in evidence”, so to speak. mypy and PyRight demonstrate different attitudes towards this balance, for example. While mypy infers dict[str, Sequence[str]], PyRight infers dict[str, Unknown], not assuming that [] and 'bbb' should share some “tight” covering type. An even simpler disagreement: given x = 3, mypy infers int, while PyRight infers Literal[3].
(Which is a rambling way to say: you don’t want to infer an overly strict or an overly broad type for a single value, and the more complex the value, the wider a range of types you have to choose from. Type annotation is useful even when inference is available.)