mypy
version 0.910
Consider
d = {
'a': 'a',
'b': {
'c': 1
}
}
d['b']['d'] = 'b'
Feeding this to mypy
results with
error: Unsupported target for indexed assignment ("Collection[str]")
Putting a side that mypy
inferred the wrong type for d
(it is clearly not a collection of strings), adding a very basic explicit type for d
fixes this:
d: dict = {
... # same as above
}
Success: no issues found in 1 source file
I find this very peculiar. mypy
should definitely be able to infer that d
is a dict without d: dict
.
d
is not being inferred as a collection of strings. It is being inferred as a dict
, but dicts take two type variables, one for the keys and one for the values. If we use reveal_type
:
d = {
'a': 'a',
'b': {
'c': 1
}
}
reveal_type(d)
d['b']['d'] = 'b'
I get:
(py39) jarrivillaga-mbp16-2019:~ jarrivillaga$ mypy --version
mypy 0.910
(py39) jarrivillaga-mbp16-2019:~ jarrivillaga$ mypy scratch.py
scratch.py:7: note: Revealed type is "builtins.dict[builtins.str*, typing.Collection*[builtins.str]]"
scratch.py:8: error: Unsupported target for indexed assignment ("Collection[str]")
Found 1 error in 1 file (checked 1 source file)
So, it is being inferred as: builtins.dict[builtins.str*, typing.Collection*[builtins.str]]
which is a dict mapping strings to collections of strings. This is because for your dict, you have used str
and dict[str, int]
as values, and I can only surmise that typing.Collection[str]
is the least broad type that encompasses str
and dict[str, str]
ha both. I'm not really sure how mypy is supposed to handle the inference of nested dict literals like yours.
Note, annotating with just dict
means it is going to use dict[Any, Any]
, which you probably don't want. You should try to give a more constrained type, but that depends on how you intend to use d
.