为什么TypedDict与匹配的Mapping不兼容?

时间:2020-02-19 15:47:11

标签: python python-3.x mypy

考虑以下代码:

from typing import Any, Mapping, TypedDict


class MyDict(TypedDict):
    foo: bool


def my_func_any(a: Mapping[str, Any]) -> None:
    print(a)


def my_func_bool(a: Mapping[str, bool]) -> None:
    print(a)


d: MyDict = {
    'foo': True
}

my_func_any(d)
my_func_bool(d)  # line 21

使用mypy==0.761检查时,会出现以下错误:

test.py:21:错误:“ my_func_bool”的参数1具有不兼容的类型“ MyDict”;预期的“映射[str,bool]”

我希望my_func_any(d)my_func_bool(d)都可以,但是后者是一个错误。这是错误还是我错过了什么?

1 个答案:

答案 0 :(得分:3)

引用PEP 589

类型一致性

首先,任何TypedDict类型都与Mapping[str, object]保持一致。

[...]

  • 具有所有TypedDict值的intMapping[str, int]不一致,因为由于结构子类型的原因,可能有其他非int值在该类型中不可见。例如,可以使用values()中的items()Mapping方法来访问它们。示例:

    class A(TypedDict):
        x: int
    
    class B(TypedDict):
        x: int
        y: str
    
    def sum_values(m: Mapping[str, int]) -> int:
        n = 0
        for v in m.values():
            n += v  # Runtime error
        return n
    
    def f(a: A) -> None:
        sum_values(a)  # Error: 'A' incompatible with Mapping[str, int]
    
    b: B = {'x': 0, 'y': 'foo'}
    f(b)