-1

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
  • How do I type hint key? Just key: int is not accepted by the type checker. It gives the warning: "slice[Any, Any, Any]" is not assignable to "int". What choices do I have here?
  • What is wrong with the return type? The full warning is "float" is not assignable to "Sequence[float]"
4
  • 1
    "Just key: int is not accepted by the type checker" - so what does it tell you? Mypy shows the missing overload; Sequences can also be sliced: docs.python.org/3/reference/datamodel.html#object.__getitem__ Commented Mar 18 at 16:44
  • @jonrsharpe See my edit. I added the override annotations as well Commented Mar 18 at 16:52
  • 1
    overload, not override - you can index into a Sequence with an int or a slice, therefore receiving either a float or a Sequence[float], as the errors tell you. Commented Mar 18 at 16:56
  • 1
    The problem is that you inherit the requirement to accept slice arguments from Sequence.__get_item__, even though nothing in the documentation indicates that you need to accept anything other than an integer key. (I suspect that is a shortcoming in the documentation, though, rather than an overreach by the signature defined in typeshed/stdlib/typing.pyi Commented Mar 18 at 17:12

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.