Mypy: есть ли способ реализовать TypeVar SelfType?

так что это довольно незначительная проблема, но мне было интересно, знает ли кто-нибудь, кто более знаком с модулем набора текста, есть ли способ сделать это.

Я хотел бы иметь возможность определять переменную типа, которая всегда эквивалентна экземпляру класса, внутри которого она используется (и, если используется подклассом, эквивалентна экземпляру этого типа подкласса).

То, что я сейчас делаю, чтобы убедиться, что mypy понимает, что возвращаемое значение эквивалентно классу, для которого оно вызывается, аннотирует аргументы self и cls следующим образом:

from typing import TypeVar, Type

T = TypeVar("T")


class Parent:
    @classmethod
    def from_classmethod(cls: Type[T]) -> T:
        return cls()

    def from_method(self: T) -> T:
        return type(self)()


class Child(Parent):
    pass


Child.from_classmethod()  # mypy: Revealed type is Child
Child().from_method()  # mypy: Revealed type is Child

И это работает, mypy будет правильно интерпретировать их как класс Child, а не Parent.

Однако я не хочу этого делать, если мне не нужно. Мне было интересно, есть ли способ создать TypeVar, который работает следующим образом:

SelfType = ...  # some voodoo magic goes here


class Parent:
    @classmethod
    def from_classmethod(cls) -> SelfType:
        return cls()

    def from_method(self) -> SelfType:
        return type(self)()


class Child(Parent):
    pass


# OtherParent is reusing SelfType without having to redefine it
class OtherParent:
    @classmethod
    def from_classmethod(cls) -> SelfType:
        return cls()

    def from_method(self) -> SelfType:
        return type(self)()


class OtherChild(OtherParent):
    pass


Child.from_classmethod()  # mypy: Revealed type is Child
Parent.from_classmethod()  # mypy: Revealed type is Parent
OtherChild.from_classmethod()  # mypy: Revealed type is OtherChild
OtherParent.from_classmethod()  # mypy: Revealed type is OtherParent

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

Возможно ли это вообще сделать с нашей стороны, или для этого потребуется запрос функции в проекте mypy?


person matthewgdv    schedule 05.02.2019    source источник


Ответы (1)


Вы должны определить переменную типа. См. это обсуждение по теме.

  T = TypeVar('T', bound='Copyable')
  class Copyable:
      def copy(self: T) -> T:
          # return a copy of self
person Mihai Andrei    schedule 05.02.2019