Python 3.6: подпись {метод} несовместима с супер-типом {Class}

При попытке обновить мой код для соответствия PEP-484 (я использую mypy 0.610), я столкнулся с следующим сообщением:

$ mypy mymodule --strict-optional --ignore-missing-imports --disallow-untyped-calls --python-version 3.6

myfile.py:154: error: Signature of "deliver" incompatible with supertype "MyClass"

Мои занятия:

from abc import abstractmethod

from typing import Any


class MyClass(object):

@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
 raise NotImplementedError

myfile.py:

class MyImplementation(MyClass):

[...]

 def deliver(self, source_path: str,
 dest_branches: list,
 commit_msg: str = None,
 exclude_files: list = None) -> bool:

 [...]

 return True

Я определенно делаю что-то неправильно здесь, но я не могу понять, что :)

Любые указатели будут высоко оценены.

1 ответ

@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
 raise NotImplementedError

Это выражение не означает, что подклассы могут deliver любую подпись, которую они хотят. Подкласс deliver методы должны быть готовы принять любые аргументы, суперкласс deliver метод будет принимать, так что ваш подкласс deliver должен быть готов принять произвольные позиционные или именованные аргументы:

# omitting annotations
def deliver(self, *args, **kwargs):
 ...

Ваш подкласс deliver не имеет эту подпись.

Если все подклассы должны иметь одну и ту же подпись deliver вы написали для MyImplementation, тогда вы должны дать MyClass.deliver ту же подпись. Если в ваших подклассах будут разные подписи deliver, возможно, этот метод не должен быть действительно в суперклассе, или, может быть, вам нужно переосмыслить свою иерархию классов или дать им одну и ту же подпись.

licensed under cc by-sa 3.0 with attribution.