抽象类和字典的 mypy 问题

Dan*_*ero 2 python abstract-class abc mypy

伟大的,考虑以下代码。

from abc import ABC, abstractmethod


class Interface(ABC):
    @abstractmethod
    def method(self) -> None:
        pass


class A(Interface):
    def method(self) -> None:
        pass


class B(Interface):
    def method(self) -> None:
        pass


mapping = {'A': A, 'B': B}


# does NOT pass mypy checks
def create_map(param: str) -> Interface:
    if param in mapping:
        return mapping[param]()
    else:
        raise NotImplementedError()

# passes mypy checks
def create_if(param: str) -> Interface:
    if param == 'A':
        return A()
    elif param == 'B':
        return B()
    else:
        raise NotImplementedError()

Run Code Online (Sandbox Code Playgroud)

出于某种原因,create_if通过了所有mypy类型检查,但create_map没有通过。这reveal_type两个函数的 都是'def (param: builtins.str) -> test.Interface'

我得到的错误与我试图直接实例化一个抽象类一样,考虑到 mypy 的这个参考,这很奇怪。

error: Cannot instantiate abstract class 'Interface' with abstract attribute 'method'
Run Code Online (Sandbox Code Playgroud)

另外,如果我 make mapping = {'A': A}(即 remove 'B': B)现在create_map也通过了。

有人可以对此有所了解吗?

Dan*_*ero 7

显然,我所缺少的只是映射的类型注释。

mapping: Mapping[str, Type[Interface]] = {'A': A, 'B': B}
Run Code Online (Sandbox Code Playgroud)

谢谢@jonafato

归功于 mypy 问题18433048显示此语法。