pythonpython-typingpyrightpython-collections

Implement the __getitem__ method of a minimal collections.abc sequence with type hints


How does a minimal implementation of a Sequence from collections.abc, together with the correct type hints, look like?

According to its documentation, __len__ and __getitem__ are sufficient. My type hinter complains about the implementation of __getitem__ though, although my implementation follows the python docs.

My current version is the following (with warnings from basedpyright):

from collections.abc import Sequence
from typing import override

class MySeq(Sequence[float]):
    def __init__(self):
        self._data: list[float] = list()

    @override
    def __len__(self) -> int:
        return len(self._data)

    @override
    def __getitem__(self, key) -> float: # Type annotation is missing for parameter "key"
        return self._data[key]           # Return type is unknown

Solution

  • It seems that although the __getitem__-docs list slice support as optional, the typing information requires both support for integer indices and slices. This contradiction seems to be known/not intended to be fixed, see this issue at the official python repository.

    Implementing both resolves both warnings:

    from collections.abc import Sequence
    from typing import override, overload
    
    class MySeq(Sequence[float]):
        def __init__(self):
            self._data: list[float] = list()
    
        @override
        def __len__(self) -> int:
            return len(self._data)
    
        @overload
        def __getitem__(self, key: int) -> float:
            pass
    
        @overload
        def __getitem__(self, key: slice) -> Sequence[float]:
            pass
    
        @override
        def __getitem__(self, key: int | slice) -> float | Sequence[float]:
            return self._data[key]
    

    Thanks for the comments of @jonrsharpe and @chepner for providing the right direction with this.