From 3c90c97b9aefccbf552046793c028e85ad3a5cdd Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 15 Jul 2022 20:20:50 +0300 Subject: [PATCH] List[Foo] + List[Bar] now returns List[Foo | Bar] (#8293) Co-authored-by: Alex Waygood Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- stdlib/builtins.pyi | 6 +++++- test_cases/stdlib/builtins/test_list.py | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test_cases/stdlib/builtins/test_list.py diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 1fffc5786..1a88e708a 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -986,8 +986,12 @@ class list(MutableSequence[_T], Generic[_T]): @overload def __setitem__(self, __s: slice, __o: Iterable[_T]) -> None: ... def __delitem__(self, __i: SupportsIndex | slice) -> None: ... + # Overloading looks unnecessary, but is needed to work around complex mypy problems + @overload def __add__(self, __x: list[_T]) -> list[_T]: ... - def __iadd__(self: Self, __x: Iterable[_T]) -> Self: ... + @overload + def __add__(self, __x: list[_S]) -> list[_S | _T]: ... + def __iadd__(self: Self, __x: Iterable[_T]) -> Self: ... # type: ignore[misc] def __mul__(self, __n: SupportsIndex) -> list[_T]: ... def __rmul__(self, __n: SupportsIndex) -> list[_T]: ... def __imul__(self: Self, __n: SupportsIndex) -> Self: ... diff --git a/test_cases/stdlib/builtins/test_list.py b/test_cases/stdlib/builtins/test_list.py new file mode 100644 index 000000000..793d7951b --- /dev/null +++ b/test_cases/stdlib/builtins/test_list.py @@ -0,0 +1,19 @@ +from typing import List, Union +from typing_extensions import assert_type + + +# list.__add__ example from #8292 +class Foo: + def asd(self) -> int: + return 1 + + +class Bar: + def asd(self) -> int: + return 2 + + +combined = [Foo()] + [Bar()] +assert_type(combined, List[Union[Foo, Bar]]) +for item in combined: + assert_type(item.asd(), int)