Как идентичные типы могут быть несовместимы в MyPy? - PullRequest
7 голосов
/ 19 апреля 2020

В следующем примере:

from typing import Callable, Generic, Type, TypeVar

ThetaType = TypeVar('ThetaType', bound=int)
XType = TypeVar('XType', bound=int)


class IteratedFunction(Generic[ThetaType, XType]):

    def find_fixed_point(self,
                         theta: ThetaType,
                         x_init: XType) -> XType:
        return x_init


def combinator(
    iterated_function_cls: Type[
        IteratedFunction[ThetaType, XType]]) -> Callable[
            [IteratedFunction[ThetaType, XType]], XType]:
    old_find_fixed_point = iterated_function_cls.find_fixed_point

    def new_find_fixed_point(
            iterated_function: IteratedFunction[ThetaType, XType],
            theta: ThetaType,
            x_init: XType) -> XType:
        return old_find_fixed_point(iterated_function, theta, x_init)

    return new_find_fixed_point

MyPy говорит:

a.py:25: error: Incompatible return value type (got "XType", expected "XType")
a.py:25: error: Argument 1 has incompatible type "IteratedFunction[ThetaType, XType]"; expected "IteratedFunction[ThetaType, XType]"
a.py:25: error: Argument 2 has incompatible type "ThetaType"; expected "ThetaType"
a.py:25: error: Argument 3 has incompatible type "XType"; expected "XType"
a.py:27: error: Incompatible return value type (got "Callable[[IteratedFunction[ThetaType, XType], ThetaType, XType], XType]", expected "Callable[[IteratedFunction[ThetaType, XType]], XType]")

1 Ответ

0 голосов
/ 19 апреля 2020

Я не уверен, что согласен с предпосылкой этого вопроса.

Вот часть строки документации из 3.8

class TypeVar(_Final, _Immutable, _root=True):
    """Type variable.
    Usage::
      T = TypeVar('T')  # Can be anything
      A = TypeVar('A', str, bytes)  # Must be str or bytes

    ....
    def __init__(self, name, *constraints, bound=None,
                 covariant=False, contravariant=False):
    ....

Теперь, если вы только что

ThetaType = TypeVar('ThetaType')
XType = TypeVar('XType')

Можно ли утверждать, что использование ThetaType следует рассматривать как использование XType, даже если были настроены 2 разных типа? Почему добавление необязательного аргумента bound автоматически сворачивает их вместе? Источник никоим образом не предписывает наличие привязки или каких-либо аргументов рядом с именем.

Я не думаю, что работа / mypy заключается в выводе ваших намерений в типе объявления , только для проверки вашего кода против ваших заявленных типов намерений . Если вы имеете в виду, что они одинаковы, объявите только 1 TypeVar. Учитывая их, то же самое может потерять некоторое семанти c, то есть, если у вас есть реальные причины иметь 2.

Я добавлю к этому, что bound обеспечивает большую гибкость, чем constraints, поскольку это соответствует подклассам. Допустим, у вас есть 4 пользовательских подкласса int. Int1 (int), Int2, Int3, Int4 .... Теперь вы решили разбить код на части, где некоторые из них должны принимать только Int1 и Int2. Typevarint12 может несколько express, даже если все ваши подклассы соответствуют bound=int.

...