Подсказка типа Python 2.7 для подклассов с заглушками - PullRequest
0 голосов
/ 09 мая 2018

Вы можете использовать подсказки типов для файлов-заглушек в Python 2.7 за https://www.python.org/dev/peps/pep-0484/#stub-files

Однако я не могу заставить его работать для сигнатур методов в подклассах.

В заглушке файла a.pyi:

class A(object):
    def foo(self, timestamp: float): ...

В файле Python 2.7 b.py

class B(A):
    def foo(self, timestamp):
        print(timestamp)  # Inferred type of timestamp is not float!

PyCharm 2017.3.3 не делает метку времени плавающей. Я не проверял поведение mypy.

Существует два обходных пути, которые приводят к избыточности кода (не рекомендуется)

Обходной путь 1

В заглушке b.pyi

class B(A):
    def foo(self, timestamp: float): ...

Обходной путь 2

В файле Python 2.7 b.py

class B(A):
def foo(self, timestamp):  # type: (float) -> None
    print(timestamp)

1 Ответ

0 голосов
/ 10 мая 2018

Если вы не добавляете аннотации типов в функцию, вы указываете, что НЕ хотите, чтобы PEP-484-совместимые контроллеры типов проверяли эту функцию.

Это означает, что вам нужно применить подход 2: явно добавить подсказки типа, чтобы Pycharm (и mypy) знали, что вы хотите, чтобы эта функция проверялась на тип.

Обратите внимание, что ваш обходной путь 1 действительно не работает: если вы добавляете файл * .pyi, вы говорите контролеру типов полностью игнорировать соответствующий файл * .py. Это, вероятно, не то, что вы хотите, чтобы здесь произошло.

В более широком смысле, Pycharm (или mypy) на самом деле неверно предполагал бы, что timestamp всегда имеет тип float: для подтипа допустимо расширять тип параметра. Например, это может быть случай, когда метод отметки времени B принимает значения с плавающей точкой ИЛИ strs:

class B(A):
    def timestamp(self, timestamp):
        # type: (Union[float, str]) -> None
        print(timestamp)

Или, возможно, он может быть расширен для принятия любого типа:

class B(A):
    def timestamp(self, timestamp):
        # type: (object) -> None
        print(timestamp)

Оба эти определения являются действительными подтипами A: они оба соответствуют подписи A.timestamp, не нарушая принцип подстановки Liskov .

Следовательно, поскольку мы не можем легко определить, какими должны быть сигнатуры подтипа, Pycharm (и mypy) не пытаются.

...