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

Dee*_*ace 12 python type-hinting mypy python-typing

mypy版本0.910

考虑

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

d['b']['d'] = 'b'
Run Code Online (Sandbox Code Playgroud)

将其提供给mypy结果

error: Unsupported target for indexed assignment ("Collection[str]")
Run Code Online (Sandbox Code Playgroud)

mypy放置推断错误类型的一侧d(它显然不是字符串集合),添加一个非常基本的显式类型d修复此问题:

d: dict = {
    ... # same as above
}
Run Code Online (Sandbox Code Playgroud)
Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)

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

jua*_*aga 7

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

d = {
    'a': 'a',
    'b': {
        'c': 1
    }
}
reveal_type(d)
d['b']['d'] = 'b'
Run Code Online (Sandbox Code Playgroud)

我得到:

(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)
Run Code Online (Sandbox Code Playgroud)

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

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