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. Implementing them resolves both warnings.

    The code below no longer produces warnings for me.

    EDIT: This contradiction seems to be known/not intended to be fixed, see this issue at the official python repository.

    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.