Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

330
Visualizações
Mypy complains about __setitem__ signature

I have a subclass of list that adds some administrative stuff on the components of the list. Everything works OK, but mypy complains about signature of the super call to __setitem__. Here is the problem reduced to its bare minimum:

from typing import List, Iterable, Union, overload
from typing_extensions import SupportsIndex


class MyData:
    pass


class MyDataSeq(List[MyData]):
    @overload
    def __setitem__(self, index: SupportsIndex, value: MyData) -> None: ...

    @overload
    def __setitem__(self, index: slice, value: Iterable[MyData]) -> None: ...

    def __setitem__(self, index: Union[SupportsIndex, slice], value: Union[MyData, Iterable[MyData]]) -> None:
        # Administrative stuff deleted
        super().__setitem__(index, value)

    def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
        # Administrative stuff deleted
        super().__delitem__(index)

When I run mypy on this, I get:

src\seq.py:18: error: Invalid index type "Union[SupportsIndex, slice]" for "MyDataSeq"; expected type "SupportsIndex"
src\seq.py:18: error: Incompatible types in assignment (expression has type "Union[MyData, Iterable[MyData]]", target has type "MyData")
Found 2 errors in 1 file (checked 1 source file)

I'm at a loss here, because obviously __setitem__, just like __delitem__, accepts both an int-like (SupportsIndex) and a slice object as its first argument. It is almost as if mypy somehow reaches the conclusion that only int-like objects are supported -- that matches with the second error that it expects only a MyData as second argument, not Iterable[MyData].

I have tried this on both Python 3.7 and 3.9, the errors are the same. I can of course tell mypy to ignore these errors, but I really would like to know what causes this, and how to solve it. Any ideas?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

In accordance to this similar issue. Mypy doesn't use overload information to type-check the function body.

To solve your problem, you could give a hint to Mypy what types you are passing to it by means of isinstance. Like so:

from typing import List, Iterable, Union, overload
from typing_extensions import SupportsIndex


class MyData:
    pass


class MyDataSeq(List[MyData]):
    @overload
    def __setitem__(self, index: SupportsIndex, value: MyData) -> None: ...

    @overload
    def __setitem__(self, index: slice, value: Iterable[MyData]) -> None: ...

    def __setitem__(self, index: Union[SupportsIndex, slice], value: Union[MyData, Iterable[MyData]]) -> None:
        # Administrative stuff deleted
        if isinstance(index, slice) and isinstance(value, Iterable):
            super().__setitem__(index, value)
        elif isinstance(index, int) and isinstance(value, MyData):
            super().__setitem__(index, value)
        else:
            raise TypeError(f"{index}/{value} Invalid index/value type.")

    def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
        # Administrative stuff deleted
        super().__delitem__(index)
over 4 years ago · Santiago Trujillo Relatório

0

You don't need to annotate the implementation, only the decorated definitions.

class MyDataSeq(List[MyData]):
    @overload
    def __setitem__(self, index: SupportsIndex, value: MyData) -> None:
        ...

    @overload
    def __setitem__(self, index: slice, value: Iterable[MyData]) -> None:
       ...

    def __setitem__(self, index, value):
        # Administrative stuff deleted
        super().__setitem__(index, value)

    def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
        # Administrative stuff deleted
        super().__delitem__(index)

(This will leave a similar problem for __delitem__ to be resolved, but I think that's a matter for a separate question.)

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda