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

Ago*_*iro 5 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

hoe*_*ing 6

引用PEP 589

类型一致性

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

[...]

  • TypedDict具有所有值的A与int不一致Mapping[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)
    
    Run Code Online (Sandbox Code Playgroud)