python / python/mypy

How to implement overload of `__setitem__` for `MutableSequence`?

Open
#7,858 3 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature priority-1-normal topic-overloads
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

I'm trying to implement my own MutableSequence but struggling with the proper way to implement the @overload

Here's my code example:

from typing import Iterable
from typing import List
from typing import MutableSequence
from typing import Union
from typing import overload


class RecordBehaviourList(MutableSequence[str]):
    def __init__(self, lst: List[str]) -> None:
        self._lst = lst

    @overload
    def __getitem__(self, index: int) -> str:
        ...

    @overload  # noqa: F811  # TODO: flake8 3.8
    def __getitem__(self, index: slice) -> MutableSequence[str]:
        ...

    def __getitem__(  # noqa: F811  # TODO: flake8 3.8
            self,
            index: Union[int, slice],
    ) -> Union[str, MutableSequence[str]]:
        return self._lst[index]

    @overload
    def __setitem__(self, index: int, value: str) -> None:
        ...

    @overload  # noqa: F811  # TODO: flake8 3.8
    def __setitem__(self, index: slice, value: Iterable[str]) -> None:
        ...

    def __setitem__(  # noqa: F811  # TODO: flake8 3.8
            self,
            index: Union[int, slice],
            value: Union[str, Iterable[str]],
    ) -> None:
        self._lst[index] = value

    def __delitem__(self, index: Union[int, slice]) -> None:
        del self._lst[index]

    def insert(self, index: int, value: str) -> None:
        self._lst.insert(index, value)

I've taken the overload definitions from this example (?) but perhaps I'm doing this incorrectly?

For now I can # type: ignore but seems non-ideal

Here's my version information and current output

$ mypy --version
mypy 0.740
$ mypy t3.py
t3.py:39: error: Invalid index type "Union[int, slice]" for "List[str]"; expected type "int"
t3.py:39: error: Incompatible types in assignment (expression has type "Union[str, Iterable[str]]", target has type "str")
Found 2 errors in 1 file (checked 1 source file)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example in t3.py with mypy 0.740 and compare the overload definitions linked from typeshed. Investigate why the implementation of setitem is rejected for List[str]; done means establishing the correct supported typing or confirming a mypy diagnostic issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.