[Python] What should typing be for __add__ in a subclass of list?

Discussão em 'Python' iniciado por Stack, Dezembro 7, 2024.

  1. Stack

    Stack Membro Participativo

    This is a simplification of my code:

    # my_list.py
    from __future__ import annotations


    class MyList(list[int]):
    def __add__(self, other: list[int]) -> MyList:
    return MyList()


    mypy says:

    > mypy .\my_list.py --strict
    my_list.py:5: error: Signature of "__add__" incompatible with supertype "list" [override]
    my_list.py:5: note: Superclass:
    my_list.py:5: note: @overload
    my_list.py:5: note: def __add__(self, list[int], /) -> list[int]
    my_list.py:5: note: @overload
    my_list.py:5: note: def [_S] __add__(self, list[_S], /) -> list[_S | int]
    my_list.py:5: note: Subclass:
    my_list.py:5: note: def __add__(self, list[int], /) -> MyList


    If I do this, mypy no longer complains:

    from typing import overload, TypeVar

    _T = TypeVar("_T")

    class MyList(list[int]):
    @overload
    def __add__(self, other: list[int]) -> list[int]:
    ...

    @overload
    def __add__(self, other: list[_T]) -> list[_T | int]:
    ...

    def __add__(self, other: list[_T] | list[int]) -> list[_T | int]:
    return [0]


    ... but then it doesn't really make sense for addition of MyLists to return lists...

    Also, the problem gets much worse if we try to add a __iadd__ method... Then it either says that its signature isn't compatible with that of __add__, or is incompatible with some superclass's signature...

    Signature of "__iadd__" incompatible with "__add__" of supertype "list" [override]
    Signatures of "__iadd__" and "__add__" are incompatible [misc]


    To me things should be really simple here, but they're not. Also I am aware of the Liskov Substitution Principle, and I think I've taken it into account for all of my tests.

    Continue reading...

Compartilhe esta Página