Борьба с набором текста. Тип ковариации - PullRequest
0 голосов
/ 12 октября 2019

Я пытаюсь реализовать интерфейс для преобразования между типами, но я изо всех сил пытаюсь сделать его согласованным, поскольку 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] - это параметр типа, а не аргумент функции.

...