Mypy:如何将类型作为函数参数并在该类型上调用 class 方法

Mypy: How to take a Type as function argument and invoke a class method on that type

我面临的问题最好用以下示例来解释:

from abc import ABC, abstractclassmethod
from typing import Type


class SomeInterface(ABC):
    """Interface definition"""

    @abstractclassmethod
    def say_something(cls, stuff_to_say: str) -> None:
        """Some class method to be implemented"""


class TheImplementation(SomeInterface):
    """Implementation of above interface"""

    @classmethod
    def say_something(cls, stuff_to_say: str) -> None:
        """Implementation of class method in interface"""
        print(stuff_to_say)


def do_something_with_type(input_class_type: Type[SomeInterface]) -> None:
    """Function that takes a class type as argument to call `say_something` on it"""
    input_class_type.say_something("hi")


do_something_with_type(TheImplementation)

注意上面的代码是有效的Python,它执行并打印出正确的字符串"hi"。

然而,mypy 显示以下错误:

tests/annotation_test.py:28: error: Too few arguments for "say_something" of "SomeInterface"
tests/annotation_test.py:28: error: Argument 1 to "say_something" of "SomeInterface" has incompatible type "str"; expected "SomeInterface"

我在这里做错了什么?通过阅读文档,我感觉到 do_something_with_typeinput_class_type 参数需要进行不同的注释,但我不确定该怎么做。

看来mypy不理解abstractclassmethod。堆叠 classmethodabstractmethod 应该可行:

class SomeInterface(ABC):
    @classmethod
    @abstractmethod
    def say_something(cls, stuff_to_say: str) -> None:
        raise NotImplementedError