Search code examples
pythonpycharmoverloadingabc

How to implement MutableSequence on custom class


I want to use a class like a list. I found out that inheriting and implementing collections.abc.MutableSequence makes the class list-like, but I don't know how to overload methods such as __getitem__, __setitem__ for integer and slice seperately.

Pycharm generates code like below:

class Test(collections.abc.MutableSequence):
    def insert(self, index: int, object: _T) -> None:
        pass

    @overload
    @abstractmethod
    def __getitem__(self, i: int) -> _T: ...

    @overload
    @abstractmethod
    def __getitem__(self, s: slice) -> MutableSequence[_T]: ...

    def __getitem__(self, i: int) -> _T:
        pass

    @overload
    @abstractmethod
    def __setitem__(self, i: int, o: _T) -> None: ...

    @overload
    @abstractmethod
    def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ...

    def __setitem__(self, i: int, o: _T) -> None:
        pass

    @overload
    @abstractmethod
    def __delitem__(self, i: int) -> None: ...

    @overload
    @abstractmethod
    def __delitem__(self, i: slice) -> None: ...

    def __delitem__(self, i: int) -> None:
        pass

    def __len__(self) -> int:
        pass

I know Python does not support overloading but there are several ways to do

but I just want to follow the flow of Pycharm.

so I want to utilise the @overload decorator, but I can't understand how to use it.

Can anyone make an easy example? I would also be very grateful for just some references.


Solution

    1. collections.UserList is a good example of how to properly implement the collections.abc.MutableSequence API.
    2. Check out this YouTube talk by Raymond Hettinger on Python's Abstract Base Classes and how to use them.
    3. The typing.overload decorator is irrelevant to the runtime implementation of a function. Its sole purpose is to aid static type-checking. Good blog on how/when to use it here.