Skip to content

Commit 5da6b1c

Browse files
committed
1 parent 53e0e90 commit 5da6b1c

File tree

4 files changed

+125
-91
lines changed

4 files changed

+125
-91
lines changed

pandas-stubs/core/indexes/base.pyi

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -784,18 +784,21 @@ class Index(IndexOpsMixin[S1]):
784784
@overload
785785
def __mul__(
786786
self: Index[_str],
787-
other: (
788-
np_ndarray_bool
789-
| np_ndarray_float
790-
| np_ndarray_complex
791-
| np_ndarray_dt
792-
| np_ndarray_td
793-
),
787+
other: np_ndarray_float | np_ndarray_complex | np_ndarray_dt | np_ndarray_td,
794788
) -> Never: ...
789+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
790+
# also in 3.x
795791
@overload
796792
def __mul__(
797793
self: Index[_str],
798-
other: Just[int] | Sequence[Just[int]] | np_ndarray_anyint | Index[int],
794+
other: (
795+
int
796+
| Sequence[int]
797+
| np_ndarray_bool
798+
| np_ndarray_anyint
799+
| Index[bool]
800+
| Index[int]
801+
),
799802
) -> Index[_str]: ...
800803
@overload
801804
def __mul__(self: Index[T_INT], other: bool | Sequence[bool]) -> Index[T_INT]: ...
@@ -874,18 +877,21 @@ class Index(IndexOpsMixin[S1]):
874877
@overload
875878
def __rmul__(
876879
self: Index[_str],
877-
other: (
878-
np_ndarray_bool
879-
| np_ndarray_float
880-
| np_ndarray_complex
881-
| np_ndarray_dt
882-
| np_ndarray_td
883-
),
880+
other: np_ndarray_float | np_ndarray_complex | np_ndarray_dt | np_ndarray_td,
884881
) -> Never: ...
882+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
883+
# also in 3.x
885884
@overload
886885
def __rmul__(
887886
self: Index[_str],
888-
other: Just[int] | Sequence[Just[int]] | np_ndarray_anyint | Index[int],
887+
other: (
888+
int
889+
| Sequence[int]
890+
| np_ndarray_bool
891+
| np_ndarray_anyint
892+
| Index[bool]
893+
| Index[int]
894+
),
889895
) -> Index[_str]: ...
890896
@overload
891897
def __rmul__(self: Index[T_INT], other: bool | Sequence[bool]) -> Index[T_INT]: ...

pandas-stubs/core/series.pyi

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,22 +2585,21 @@ class Series(IndexOpsMixin[S1], NDFrame):
25852585
@overload
25862586
def __mul__(
25872587
self: Series[_str],
2588-
other: (
2589-
np_ndarray_bool
2590-
| np_ndarray_float
2591-
| np_ndarray_complex
2592-
| np_ndarray_dt
2593-
| np_ndarray_td
2594-
),
2588+
other: np_ndarray_float | np_ndarray_complex | np_ndarray_dt | np_ndarray_td,
25952589
) -> Never: ...
2590+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
2591+
# also in 3.x
25962592
@overload
25972593
def __mul__(
25982594
self: Series[_str],
25992595
other: (
2600-
Just[int]
2601-
| Sequence[Just[int]]
2596+
int
2597+
| Sequence[int]
2598+
| np_ndarray_bool
26022599
| np_ndarray_anyint
2600+
| Index[bool]
26032601
| Index[int]
2602+
| Series[bool]
26042603
| Series[int]
26052604
),
26062605
) -> Series[_str]: ...
@@ -2696,14 +2695,19 @@ class Series(IndexOpsMixin[S1], NDFrame):
26962695
fill_value: float | None = None,
26972696
axis: AxisIndex | None = 0,
26982697
) -> Series[Timedelta]: ...
2698+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
2699+
# also in 3.x
26992700
@overload
27002701
def mul(
27012702
self: Series[_str],
27022703
other: (
2703-
Just[int]
2704-
| Sequence[Just[int]]
2704+
int
2705+
| Sequence[int]
2706+
| np_ndarray_bool
27052707
| np_ndarray_anyint
2708+
| Index[bool]
27062709
| Index[int]
2710+
| Series[bool]
27072711
| Series[int]
27082712
),
27092713
level: Level | None = None,
@@ -2838,22 +2842,21 @@ class Series(IndexOpsMixin[S1], NDFrame):
28382842
@overload
28392843
def __rmul__(
28402844
self: Series[_str],
2841-
other: (
2842-
np_ndarray_bool
2843-
| np_ndarray_float
2844-
| np_ndarray_complex
2845-
| np_ndarray_dt
2846-
| np_ndarray_td
2847-
),
2845+
other: np_ndarray_float | np_ndarray_complex | np_ndarray_dt | np_ndarray_td,
28482846
) -> Never: ...
2847+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
2848+
# also in 3.x
28492849
@overload
28502850
def __rmul__(
28512851
self: Series[_str],
28522852
other: (
2853-
Just[int]
2854-
| Sequence[Just[int]]
2853+
int
2854+
| Sequence[int]
2855+
| np_ndarray_bool
28552856
| np_ndarray_anyint
2857+
| Index[bool]
28562858
| Index[int]
2859+
| Series[bool]
28572860
| Series[int]
28582861
),
28592862
) -> Series[_str]: ...
@@ -2951,14 +2954,19 @@ class Series(IndexOpsMixin[S1], NDFrame):
29512954
fill_value: float | None = None,
29522955
axis: AxisIndex | None = 0,
29532956
) -> Series[Timedelta]: ...
2957+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
2958+
# also in 3.x
29542959
@overload
29552960
def rmul(
29562961
self: Series[_str],
29572962
other: (
2958-
Just[int]
2959-
| Sequence[Just[int]]
2963+
int
2964+
| Sequence[int]
2965+
| np_ndarray_bool
29602966
| np_ndarray_anyint
2967+
| Index[bool]
29612968
| Index[int]
2969+
| Series[bool]
29622970
| Series[int]
29632971
),
29642972
level: Level | None = None,

tests/indexes/arithmetic/str/test_mul.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
)
1515

1616
from tests import (
17+
PD_LTE_23,
1718
TYPE_CHECKING_INVALID_USAGE,
1819
check,
1920
)
@@ -31,17 +32,19 @@ def test_mul_py_scalar(left: "pd.Index[str]") -> None:
3132
b, i, f, c = True, 1, 1.0, 1j
3233
s, d = datetime(2025, 9, 27), timedelta(seconds=1)
3334

34-
if TYPE_CHECKING_INVALID_USAGE:
35-
_00 = left * b # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
35+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
36+
# also in 3.x
37+
if PD_LTE_23:
38+
check(assert_type(left * b, "pd.Index[str]"), pd.Index, str)
3639
check(assert_type(left * i, "pd.Index[str]"), pd.Index, str)
3740
if TYPE_CHECKING_INVALID_USAGE:
3841
_02 = left * f # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
3942
_03 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
4043
_04 = left * s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
4144
_05 = left * d # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
4245

43-
if TYPE_CHECKING_INVALID_USAGE:
44-
_10 = b * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
46+
if PD_LTE_23:
47+
check(assert_type(b * left, "pd.Index[str]"), pd.Index, str)
4548
check(assert_type(i * left, "pd.Index[str]"), pd.Index, str)
4649
if TYPE_CHECKING_INVALID_USAGE:
4750
_12 = f * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
@@ -56,17 +59,19 @@ def test_mul_py_sequence(left: "pd.Index[str]") -> None:
5659
s = [datetime(2025, 9, d) for d in (27, 28, 29)]
5760
d = [timedelta(seconds=s + 1) for s in range(3)]
5861

59-
if TYPE_CHECKING_INVALID_USAGE:
60-
_00 = left * b # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
62+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
63+
# also in 3.x
64+
if PD_LTE_23:
65+
check(assert_type(left * b, "pd.Index[str]"), pd.Index, str)
6166
check(assert_type(left * i, "pd.Index[str]"), pd.Index, str)
6267
if TYPE_CHECKING_INVALID_USAGE:
6368
_02 = left * f # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
6469
_03 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
6570
_04 = left * s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
6671
_05 = left * d # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
6772

68-
if TYPE_CHECKING_INVALID_USAGE:
69-
_10 = b * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
73+
if PD_LTE_23:
74+
check(assert_type(b * left, "pd.Index[str]"), pd.Index, str)
7075
check(assert_type(i * left, "pd.Index[str]"), pd.Index, str)
7176
if TYPE_CHECKING_INVALID_USAGE:
7277
_12 = f * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
@@ -84,8 +89,10 @@ def test_mul_numpy_array(left: "pd.Index[str]") -> None:
8489
s = np.array([np.datetime64(f"2025-09-{d}") for d in (27, 28, 29)], np.datetime64)
8590
d = np.array([np.timedelta64(s + 1, "s") for s in range(3)], np.timedelta64)
8691

87-
if TYPE_CHECKING_INVALID_USAGE:
88-
assert_type(left * b, Never)
92+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
93+
# also in 3.x
94+
if PD_LTE_23:
95+
check(assert_type(left * b, "pd.Index[str]"), pd.Index, str)
8996
check(assert_type(left * i, "pd.Index[str]"), pd.Index, str)
9097
if TYPE_CHECKING_INVALID_USAGE:
9198
assert_type(left * f, Never)
@@ -96,8 +103,8 @@ def test_mul_numpy_array(left: "pd.Index[str]") -> None:
96103
# `numpy` typing gives the corresponding `ndarray`s in the static type
97104
# checking, where our `__rmul__` cannot override. At runtime, they return
98105
# `Index` with the correct element type.
99-
if TYPE_CHECKING_INVALID_USAGE:
100-
assert_type(b * left, "npt.NDArray[np.bool_]")
106+
if PD_LTE_23:
107+
check(assert_type(b * left, "npt.NDArray[np.bool_]"), pd.Index, str)
101108
check(assert_type(i * left, "npt.NDArray[np.int64]"), pd.Index, str)
102109
if TYPE_CHECKING_INVALID_USAGE:
103110
assert_type(f * left, "npt.NDArray[np.float64]")
@@ -115,17 +122,19 @@ def test_mul_pd_index(left: "pd.Index[str]") -> None:
115122
s = pd.Index([datetime(2025, 9, d) for d in (27, 28, 29)])
116123
d = pd.Index([timedelta(seconds=s + 1) for s in range(3)])
117124

118-
if TYPE_CHECKING_INVALID_USAGE:
119-
_00 = left * b # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
125+
# pandas-dev/pandas#62595: we may want to support Series[str] * bool
126+
# also in 3.x
127+
if PD_LTE_23:
128+
check(assert_type(left * b, "pd.Index[str]"), pd.Index, str)
120129
check(assert_type(left * i, "pd.Index[str]"), pd.Index, str)
121130
if TYPE_CHECKING_INVALID_USAGE:
122131
_02 = left * f # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
123132
_03 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
124133
_04 = left * s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
125134
_05 = left * d # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
126135

127-
if TYPE_CHECKING_INVALID_USAGE:
128-
_10 = b * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
136+
if PD_LTE_23:
137+
check(assert_type(b * left, "pd.Index[str]"), pd.Index, str)
129138
check(assert_type(i * left, "pd.Index[str]"), pd.Index, str)
130139
if TYPE_CHECKING_INVALID_USAGE:
131140
_12 = f * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue]

0 commit comments

Comments
 (0)