diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index 3f3332940..35a610cf4 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -626,7 +626,7 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]): def __lt__(self, other: Self | S1) -> np_1darray_bool: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __gt__(self, other: Self | S1) -> np_1darray_bool: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] @overload - def __add__(self: Index[Never], other: _str) -> Never: ... + def __add__(self: Index[Never], other: _str) -> Index[_str]: ... @overload def __add__( self: Index[Never], other: complex | ArrayLike | SequenceNotStr[S1] | Index @@ -680,7 +680,7 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]): self: Index[_str], other: np_ndarray_str | Index[_str] ) -> Index[_str]: ... @overload - def __radd__(self: Index[Never], other: _str) -> Never: ... + def __radd__(self: Index[Never], other: _str) -> Index[_str]: ... @overload def __radd__( self: Index[Never], other: complex | ArrayLike | SequenceNotStr[S1] | Index diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 469d44ea0..73ee89cc0 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1789,6 +1789,8 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): # just failed to generate these so I couldn't match # them up. @overload + def __add__(self: Series[Never], other: _str) -> Series[_str]: ... + @overload def __add__(self: Series[Never], other: complex | ListLike) -> Series: ... @overload def __add__(self, other: Index[Never] | Series[Never]) -> Series: ... @@ -1875,6 +1877,14 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): self: Series[_str], other: np_ndarray_str | Index[_str] | Series[_str] ) -> Series[_str]: ... @overload + def add( + self: Series[Never], + other: _str, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[_str]: ... + @overload def add( self: Series[Never], other: complex | ListLike, @@ -2008,6 +2018,8 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): axis: int = 0, ) -> Series[_str]: ... @overload + def __radd__(self: Series[Never], other: _str) -> Series[_str]: ... + @overload def __radd__(self: Series[Never], other: complex | ListLike) -> Series: ... @overload def __radd__(self, other: Index[Never] | Series[Never]) -> Series: ... @@ -2108,6 +2120,14 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): @overload def __radd__(self: Series[BaseOffset], other: BaseOffset) -> Series[BaseOffset]: ... @overload + def radd( + self: Series[Never], + other: _str, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[_str]: ... + @overload def radd( self: Series[Never], other: complex | ListLike, diff --git a/tests/indexes/arithmetic/test_add.py b/tests/indexes/arithmetic/test_add.py index c7c415b46..d78e6e5d2 100644 --- a/tests/indexes/arithmetic/test_add.py +++ b/tests/indexes/arithmetic/test_add.py @@ -2,10 +2,7 @@ import numpy as np import pandas as pd -from typing_extensions import ( - Never, - assert_type, -) +from typing_extensions import assert_type from tests import ( TYPE_CHECKING_INVALID_USAGE, @@ -105,7 +102,13 @@ def test_add_i_pd_index() -> None: def test_add_i_py_str() -> None: """Test pd.Index[Any] (int) + Python str""" s = "abc" + midx = pd.MultiIndex.from_tuples([("a",)]) + idx = midx.levels[0] + + check(assert_type(idx + "c1", "pd.Index[str]"), pd.Index, str) + check(assert_type("c1" + idx, "pd.Index[str]"), pd.Index, str) if TYPE_CHECKING_INVALID_USAGE: - assert_type(left_i + s, Never) - assert_type(s + left_i, Never) + # GH1541 relaxing typing, won't work at runtime though + assert_type(left_i + s, "pd.Index[str]") + assert_type(s + left_i, "pd.Index[str]") diff --git a/tests/series/arithmetic/test_add.py b/tests/series/arithmetic/test_add.py index b1094ed71..dd926f9ec 100644 --- a/tests/series/arithmetic/test_add.py +++ b/tests/series/arithmetic/test_add.py @@ -181,3 +181,14 @@ def test_add_i_pd_series() -> None: check(assert_type(left_i.radd(i), pd.Series), pd.Series) check(assert_type(left_i.radd(f), pd.Series), pd.Series) check(assert_type(left_i.radd(c), pd.Series), pd.Series) + + +def test_series_add_str() -> None: + """Test Series.__add__ with Series[Any].""" + df = pd.DataFrame({0: ["a", "b"]}) + sr = df[0] + + check(assert_type(sr + "c1", "pd.Series[str]"), pd.Series, str) + check(assert_type("c1" + sr, "pd.Series[str]"), pd.Series, str) + check(assert_type(sr.add("c1"), "pd.Series[str]"), pd.Series, str) + check(assert_type(sr.radd("c1"), "pd.Series[str]"), pd.Series, str)