Как я могу захватить ограничение для универсального типа Python, который сам имеет слоты типа? - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть случай, когда класс является общим для реализаций протокола, который сам имеет общий слот типа, и я не могу найти способ выразить это с помощью подсказки типа Python (приемлемо для Mypy).

В частности, у меня есть:

__A = TypeVar('__A', covariant=True)


class IndexableCollection(Protocol, Generic[__A]):
    def __iter__(self) -> Iterator[__A]:
        ...

    def __len__(self) -> int:
        ...

    @overload
    def __getitem__(self, key: int) -> __A:
        ...

    @overload
    def __getitem__(self, index: slice) -> Sequence[__A]:
        ...

Теперь я хочу указать NamedTuple, в котором член ограничен вышеуказанным протоколом.Может быть, что-то вроде этого (что неверно, но я не могу найти вариант, который принимается):

Coll = TypeVar('Coll', bound=IndexableCollection)

class MyTuple(NamedTuple, Generic[Coll]):
    sub_collection: Coll
    ...

В идеале я хотел бы сделать тип элемента (универсальный параметр в протоколе) также универсальнымПараметр кортежа.

Причина, по которой мне это нужно, состоит в том, что на практике элемент sub_collection иногда будет просто старым List, а в других случаях может быть массивом-пустышкой.В случае массива numpy в точке использования это связывание будет известно, и мне нужно использовать его (для многомерного среза).Это означает, что непосредственное указание типа os sub_collection как IndexableCollection в самом определении кортежа (не универсально) не является достаточно общим (не охватывает многомерную разрезаемость), поэтому мне нужно перенести его вв идеале универсальный тип.

Примечание. Подобные вещи также возникают при попытке перехватить типы с более высоким родом и могут сводиться к одной и той же проблеме (???)

...