协议的所有基础都必须是协议——typing.MutableMapping 不是协议吗?

Tho*_*las 5 python abc structural-typing mypy python-typing

我想为自定义映射类定义一个类型协议。这个类需要与 a 非常相似,除了它除了那些定义为抽象方法(特别是)MutableMapping之外还有几个附加方法,并且我还想提前指定自定义映射类的任何实现必须使用哪些类型作为键和值。collections.abc.MutableMapping.copy()

读完PEP 544后,我想我应该能够做到这一点:

from typing import Hashable, MutableMapping, Protocol, TypeVar


TVarMapProt = TypeVar("TVarMapProt", bound="VariableMappingProtocol")


class VariableMappingProtocol(MutableMapping[Hashable, int], Protocol):
    """
    Protocol for the type behaviour of a class which
    acts basically like a dict of int objects.
    """

    def copy(self: TVarMapProt) -> TVarMapProt:
         # TODO replace return type with Self if PEP 673 goes through
        ...
Run Code Online (Sandbox Code Playgroud)

我的想法是,在我的代码中,我可以声明需要一个类型VariableMappingProtocol,然后用户必须使用自己定义的类,以避免输入错误:

TCusVarMap = TypeVar("CusVarMap", bound="CustomVariableMapping")


class CustomVariableMapping
    """Defines all the methods that a MutableMapping does, but mapping Hashables to ints"""

    def __getitem__(self, key: Hashable) -> int:
        # implementation goes here
        ...

    # etc. for __setitem__, and so on...

    def copy(self) -> TCusVarMap:
        # implementation goes here
        ...
Run Code Online (Sandbox Code Playgroud)

问题是,当我运行mypy定义的代码时VariableMappingProtocol,出现以下错误:

test.py:7: error: All bases of a protocol must be protocols
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)

如果我删除MutableMapping以便VariableMappingProtocol仅继承,Protocol则错误就会消失。但是我没有得到我想要的所有抽象方法的结构类型MutableMapping

所以看来问题是typing.MutableMapping没有考虑到Protocol?但这很奇怪,特别是因为我可以将typingas中的一些其他类型视为Protocols,例如这个示例(来自 PEP 544)

test.py:7: error: All bases of a protocol must be protocols
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)

这不会引发任何mypy错误。

如何从MutableMappingas a继承Protocol,从而避免需要写出定义MutableMapping中的所有方法VariableMappingProtocol