Mypy: как взять тип в качестве аргумента функции и вызвать метод класса для этого типа - PullRequest
0 голосов
/ 12 января 2020

Проблема, с которой я сталкиваюсь, лучше всего объяснить на следующем примере:

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"

Что я здесь не так делаю? Из прочтения документации я чувствую, что аргумент input_class_type для do_something_with_type необходимо аннотировать по-другому, но я не уверен, как именно go об этом.

1 Ответ

1 голос
/ 12 января 2020

Похоже, что Mypy не понимает abstractclassmethod. Стеки classmethod и abstractmethod вместо этого должны работать:

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