为什么 mypy 很难分配给嵌套的字典?

Why does mypy have a hard time with assignment to nested dicts?

mypy 版本 0.910

考虑

d = {
    'a': 'a',
    'b': {
        'c': 1
    }
}

d['b']['d'] = 'b'

将此提供给 mypy 结果

error: Unsupported target for indexed assignment ("Collection[str]")

mypy 推断出 d 的错误类型(这显然不是字符串集合)作为一个方面,为 d 添加一个非常基本的显式类型修复了这个问题:

d: dict = {
    ... # same as above
}

Success: no issues found in 1 source file

我觉得这很奇怪。 mypy 绝对应该能够推断出 d 是一个没有 d: dict.

的字典

d 未被推断为字符串集合。它被推断为 dict,但字典采用两种类型变量,一种用于键,一种用于值。如果我们使用 reveal_type:

d = {
    'a': 'a',
    'b': {
        'c': 1
    }
}
reveal_type(d)
d['b']['d'] = 'b'

我得到:

(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)

因此,它被推断为:builtins.dict[builtins.str*, typing.Collection*[builtins.str]] 这是一个将字符串映射到字符串集合的字典。这是因为对于你的字典,你使用了 strdict[str, int] 作为值,我只能推测 typing.Collection[str] 是包含 strdict[str, str] 都有。我不太确定 mypy 应该如何处理像你这样的嵌套字典文字的推断。

请注意,仅使用 dict 进行注释意味着它将使用 dict[Any, Any],您可能 不需要 。您应该尝试提供更受约束的类型,但这取决于您打算如何使用d.