Я пытаюсь реализовать интерфейс для преобразования между типами, но я изо всех сил пытаюсь сделать его согласованным, поскольку typing.Type
является ковариантным
U = TypeVar('U')
class Into(Protocol[U]):
@abstractmethod
def into(self, t: Type[U]) -> U:
pass
документы дают аналогичныепример с принципиальным отличием
class User: ...
class BasicUser(User): ...
class ProUser(User): ...
class TeamUser(User): ...
def make_new_user(user_class: Type[User]) -> User:
return user_class()
Там говорят, что средства проверки типов должны проверять, что все подклассы User
должны реализовывать конструктор с допустимой сигнатурой, которая будет реализована как эта. Мой вариант использования отличается тем, что я могу не создавать новый тип, а просто возвращать уже существующий. Скажем, я делаю
class X: pass
class Wrapper:
def __init__(self, x: X):
self._x = x
def into(self, t: Type[X]) -> X:
return self._x
, который все работает нормально, пока кто-то не подклассов X
w = Wrapper(X)
...
class XX(X): pass
x: XX = w.into(XX)
RHS в порядке по mypy, потому что Type
является ковариантным, но, очевидно, API нарушенпотому что X
не XX
. Если Type
не является ковариантным, это не будет проблемой: RHS не будет проверять тип, пока Wrapper
не будет обновлен для поддержки XX
.
Мой вопрос: есть ли какой-то способдостичь этого (или что-то подобное), учитывая ковариацию Type
?
Context
Я хочу использовать это для преобразования типа в несколько других типов, указавжелаемый тип явно, а не просто into_X
, into_Y
и т. д. Я ожидаю сделать это с TypeVar
или overload
. У меня также возникают трудности там .
Это связано с ржавчиной Into
, где t: Type[U]
- это параметр типа, а не аргумент функции.