Skip to content

Commit e0b5b59

Browse files
committed
fix(comment): without str #1343 (comment)
1 parent 961d692 commit e0b5b59

File tree

4 files changed

+104
-72
lines changed

4 files changed

+104
-72
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ repos:
1111
hooks:
1212
- id: isort
1313
- repo: https://github.com/astral-sh/ruff-pre-commit
14-
rev: v0.12.3
14+
rev: v0.12.10
1515
hooks:
1616
- id: ruff-check
1717
args: [

pandas-stubs/core/series.pyi

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ from pandas._typing import (
186186
np_ndarray_anyint,
187187
np_ndarray_bool,
188188
np_ndarray_complex,
189-
np_ndarray_dt,
190189
np_ndarray_float,
191190
np_ndarray_str,
192191
np_ndarray_td,
@@ -264,6 +263,16 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]):
264263
_ListLike: TypeAlias = (
265264
ArrayLike | dict[_str, np.ndarray] | Sequence[S1] | IndexOpsMixin[S1]
266265
)
266+
_NumListLike: TypeAlias = (
267+
ExtensionArray
268+
| np_ndarray_bool
269+
| np_ndarray_anyint
270+
| np_ndarray_float
271+
| np_ndarray_complex
272+
| dict[_str, np.ndarray]
273+
| Sequence[complex]
274+
| IndexOpsMixin[complex]
275+
)
267276

268277
class Series(IndexOpsMixin[S1], NDFrame):
269278
# Define __index__ because mypy thinks Series follows protocol `SupportsIndex` https://github.com/pandas-dev/pandas-stubs/pull/1332#discussion_r2285648790
@@ -2475,12 +2484,11 @@ class Series(IndexOpsMixin[S1], NDFrame):
24752484
@overload
24762485
def __rxor__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ...
24772486
@overload
2478-
def __sub__(
2479-
self: Series[Never],
2480-
other: datetime | np.datetime64 | np_ndarray_dt | TimestampSeries,
2481-
) -> TimedeltaSeries: ...
2487+
def __sub__(self: Series[Never], other: TimestampSeries) -> Never: ...
24822488
@overload
2483-
def __sub__(self: Series[Never], other: complex | _ListLike | Series) -> Series: ...
2489+
def __sub__(
2490+
self: Series[Never], other: complex | _NumListLike | Series
2491+
) -> Series: ...
24842492
@overload
24852493
def __sub__(self, other: Series[Never]) -> Series: ... # type: ignore[overload-overlap]
24862494
@overload
@@ -2571,15 +2579,15 @@ class Series(IndexOpsMixin[S1], NDFrame):
25712579
@overload
25722580
def sub(
25732581
self: Series[Never],
2574-
other: datetime | np.datetime64 | np_ndarray_dt | TimestampSeries,
2582+
other: TimestampSeries,
25752583
level: Level | None = None,
25762584
fill_value: float | None = None,
25772585
axis: int = 0,
2578-
) -> TimedeltaSeries: ...
2586+
) -> Never: ...
25792587
@overload
25802588
def sub(
25812589
self: Series[Never],
2582-
other: complex | _ListLike | Series,
2590+
other: complex | _NumListLike | Series,
25832591
level: Level | None = None,
25842592
fill_value: float | None = None,
25852593
axis: int = 0,
@@ -2705,9 +2713,10 @@ class Series(IndexOpsMixin[S1], NDFrame):
27052713
axis: int = 0,
27062714
) -> TimedeltaSeries: ...
27072715
@overload
2708-
def __rsub__( # type: ignore[overload-overlap]
2709-
self: Series[Never],
2710-
other: complex | datetime | np.datetime64 | _ListLike | Series,
2716+
def __rsub__(self: Series[Never], other: TimestampSeries) -> Never: ... # type: ignore[misc]
2717+
@overload
2718+
def __rsub__(
2719+
self: Series[Never], other: complex | _NumListLike | Series
27112720
) -> Series: ...
27122721
@overload
27132722
def __rsub__(self, other: Series[Never]) -> Series: ...
@@ -2775,13 +2784,17 @@ class Series(IndexOpsMixin[S1], NDFrame):
27752784
),
27762785
) -> Series[complex]: ...
27772786
@overload
2778-
def __rsub__(
2779-
self: Series[Timestamp], other: datetime | np.datetime64 | np_ndarray_dt
2780-
) -> TimedeltaSeries: ...
2787+
def rsub(
2788+
self: Series[Never],
2789+
other: TimestampSeries,
2790+
level: Level | None = None,
2791+
fill_value: float | None = None,
2792+
axis: int = 0,
2793+
) -> Never: ...
27812794
@overload
27822795
def rsub(
27832796
self: Series[Never],
2784-
other: complex | datetime | np.datetime64 | _ListLike | Series,
2797+
other: complex | _NumListLike | Series,
27852798
level: Level | None = None,
27862799
fill_value: float | None = None,
27872800
axis: int = 0,

tests/series/arithmetic/test_add.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
from tests import check
77

8-
left_i = pd.DataFrame({"a": [1, 2, 3]})["a"] # left operand
8+
# left operands
9+
left_i = pd.DataFrame({"a": [1, 2, 3]})["a"]
10+
left_str = pd.DataFrame({"a": ["1", "2", "3_"]})["a"]
911

1012

1113
def test_add_i_py_scalar() -> None:

tests/series/arithmetic/test_sub.py

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22
datetime,
33
timedelta,
44
)
5-
from typing import (
6-
TYPE_CHECKING,
7-
NoReturn,
8-
)
5+
from typing import NoReturn
96

107
import numpy as np
118
from numpy import typing as npt # noqa: F401
129
import pandas as pd
13-
from typing_extensions import assert_type
10+
from typing_extensions import (
11+
Never,
12+
assert_type,
13+
)
1414

1515
from tests import (
1616
TYPE_CHECKING_INVALID_USAGE,
1717
check,
1818
)
1919

20-
if TYPE_CHECKING:
21-
from pandas.core.series import TimedeltaSeries # noqa: F401
22-
2320
anchor = datetime(2025, 8, 18)
2421

2522
# left operands
@@ -152,76 +149,96 @@ def test_sub_i_pd_series() -> None:
152149
def test_sub_ts_py_datetime() -> None:
153150
"""Test pd.Series[Any] (Timestamp | Timedelta) - Python native datetime"""
154151
s = anchor
152+
a = [s + timedelta(minutes=m) for m in range(3)]
155153

156-
check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta)
154+
if TYPE_CHECKING_INVALID_USAGE:
155+
_0 = left_ts - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
156+
_1 = left_ts - a # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
157+
_2 = left_td - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
158+
_3 = left_td - a # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
157159

158-
check(assert_type(s - left_ts, pd.Series), pd.Series, pd.Timedelta)
159-
check(assert_type(s - left_td, pd.Series), pd.Series, pd.Timestamp)
160+
_4 = s - left_ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
161+
_5 = a - left_ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
162+
_6 = s - left_td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
163+
_7 = a - left_td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
160164

161-
check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta)
165+
left_ts.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
166+
left_ts.sub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
167+
left_td.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
168+
left_td.sub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
162169

163-
check(assert_type(left_ts.rsub(s), pd.Series), pd.Series, pd.Timedelta)
164-
check(assert_type(left_td.rsub(s), pd.Series), pd.Series, pd.Timestamp)
170+
left_ts.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
171+
left_ts.rsub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
172+
left_td.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
173+
left_td.rsub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
165174

166175

167176
def test_sub_ts_numpy_datetime() -> None:
168177
"""Test pd.Series[Any] (Timestamp | Timedelta) - numpy datetime(s)"""
169178
s = np.datetime64(anchor)
170179
a = np.array([s + np.timedelta64(m, "m") for m in range(3)], np.datetime64)
171180

172-
check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta)
173-
if TYPE_CHECKING_INVALID_USAGE:
174-
_0 = left_td - s
175-
check(assert_type(left_ts - a, "TimedeltaSeries"), pd.Series, pd.Timedelta)
176181
if TYPE_CHECKING_INVALID_USAGE:
177-
_1 = left_td - a
182+
# `numpy` typing gives the corresponding `ndarray`s in the static type
183+
# checking, where our `__rsub__` cannot override.
184+
_0 = left_ts - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
185+
# _1 = left_ts - a
186+
_2 = left_td - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
187+
# _3 = left_td - a
178188

179-
check(assert_type(s - left_ts, pd.Series), pd.Series, pd.Timedelta)
180-
check(assert_type(s - left_td, pd.Series), pd.Series, pd.Timestamp)
181-
# `numpy` typing gives the corresponding `ndarray`s in the static type
182-
# checking, where our `__rsub__` cannot override. At runtime, they return
183-
# `Series`s.
184-
check(assert_type(a - left_ts, "npt.NDArray[np.datetime64]"), pd.Series, pd.Timedelta) # type: ignore[assert-type]
185-
check(assert_type(a - left_td, "npt.NDArray[np.datetime64]"), pd.Series, pd.Timestamp) # type: ignore[assert-type]
189+
_4 = s - left_ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
190+
# _5 = a - left_ts
191+
_6 = s - left_td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
192+
# _7 = a - left_td
186193

187-
check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta)
188-
if TYPE_CHECKING_INVALID_USAGE:
189-
left_td.sub(s)
190-
check(assert_type(left_ts.sub(a), "TimedeltaSeries"), pd.Series, pd.Timedelta)
191-
if TYPE_CHECKING_INVALID_USAGE:
192-
left_td.sub(a)
194+
left_ts.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
195+
left_ts.sub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
196+
left_td.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
197+
left_td.sub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
193198

194-
check(assert_type(left_ts.rsub(s), pd.Series), pd.Series, pd.Timedelta)
195-
check(assert_type(left_td.rsub(s), pd.Series), pd.Series, pd.Timestamp)
196-
check(assert_type(left_ts.rsub(a), pd.Series), pd.Series, pd.Timedelta)
197-
check(assert_type(left_td.rsub(a), pd.Series), pd.Series, pd.Timestamp)
199+
left_ts.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
200+
left_ts.rsub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
201+
left_td.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
202+
left_td.rsub(a) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
198203

199204

200205
def test_sub_ts_pd_datetime() -> None:
201206
"""Test pd.Series[Any] (Timestamp | Timedelta) - Pandas datetime(s)"""
202207
s = pd.Timestamp(anchor)
203208
a = pd.Series([s + pd.Timedelta(minutes=m) for m in range(3)])
204209

205-
check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta)
206-
if TYPE_CHECKING_INVALID_USAGE:
207-
_0 = left_td - s
208-
check(assert_type(left_ts - a, "TimedeltaSeries"), pd.Series, pd.Timedelta)
209210
if TYPE_CHECKING_INVALID_USAGE:
210-
_1 = left_td - a
211+
_0 = left_ts - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
212+
assert_type(left_ts - a, Never)
213+
_2 = left_td - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
214+
assert_type(left_td - a, Never)
211215

212-
check(assert_type(s - left_ts, pd.Series), pd.Series, pd.Timedelta)
213-
check(assert_type(s - left_td, pd.Series), pd.Series, pd.Timestamp)
214-
check(assert_type(a - left_ts, pd.Series), pd.Series, pd.Timedelta)
215-
check(assert_type(a - left_td, pd.Series), pd.Series, pd.Timestamp)
216+
_4 = s - left_ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
217+
assert_type(a - left_ts, Never)
218+
_6 = s - left_td # type: ignore[operator] # pyright: ignore[reportOperatorIssue]
219+
assert_type(a - left_td, Never)
220+
221+
left_ts.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
222+
assert_type(left_ts.sub(a), Never)
223+
224+
225+
def test_sub_ts_pd_datetime_1() -> None:
226+
"""Test pd.Series[Any] (Timestamp | Timedelta) - Pandas datetime(s)"""
227+
s = pd.Timestamp(anchor)
228+
a = pd.Series([s + pd.Timedelta(minutes=m) for m in range(3)])
216229

217-
check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta)
218-
if TYPE_CHECKING_INVALID_USAGE:
219-
left_td.sub(s)
220-
check(assert_type(left_ts.sub(a), "TimedeltaSeries"), pd.Series, pd.Timedelta)
221230
if TYPE_CHECKING_INVALID_USAGE:
222-
left_td.sub(a)
231+
# When I merge this one to the previous one, mypy does not allow me to pass
232+
left_ts.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
233+
assert_type(left_ts.rsub(a), Never)
223234

224-
check(assert_type(left_ts.rsub(s), pd.Series), pd.Series, pd.Timedelta)
225-
check(assert_type(left_td.rsub(s), pd.Series), pd.Series, pd.Timestamp)
226-
check(assert_type(left_ts.rsub(a), pd.Series), pd.Series, pd.Timedelta)
227-
check(assert_type(left_td.rsub(a), pd.Series), pd.Series, pd.Timestamp)
235+
236+
def test_sub_ts_pd_datetime_2() -> None:
237+
"""Test pd.Series[Any] (Timestamp | Timedelta) - Pandas datetime(s)"""
238+
s = pd.Timestamp(anchor)
239+
a = pd.Series([s + pd.Timedelta(minutes=m) for m in range(3)])
240+
241+
if TYPE_CHECKING_INVALID_USAGE:
242+
# When I merge this one to the previous one, mypy does not allow me to pass
243+
left_td.rsub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue]
244+
assert_type(left_td.rsub(a), Never)

0 commit comments

Comments
 (0)