diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index b33240c0..f34f273e 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -347,11 +347,16 @@ class Index(IndexOpsMixin[S1]): def __neg__(self) -> Self: ... def __nonzero__(self) -> None: ... __bool__ = ... - def union(self, other: list[HashableT] | Index, sort=...) -> Index: ... - def intersection(self, other: list[S1] | Self, sort: bool = ...) -> Self: ... - def difference(self, other: list | Index, sort: bool | None = None) -> Self: ... + def union( + self, other: list[HashableT] | Self, sort: bool | None = ... + ) -> Index: ... + def intersection(self, other: list[S1] | Self, sort: bool | None = ...) -> Self: ... + def difference(self, other: list | Self, sort: bool | None = None) -> Self: ... def symmetric_difference( - self, other: list[S1] | Self, result_name: Hashable = ..., sort=... + self, + other: list[S1] | Self, + result_name: Hashable = ..., + sort: bool | None = ..., ) -> Self: ... def get_loc( self, @@ -472,5 +477,6 @@ class Index(IndexOpsMixin[S1]): | Sequence[float] ), ) -> Self: ... + def infer_objects(self, copy: bool = ...) -> Self: ... UnknownIndex: TypeAlias = Index[Any] diff --git a/pandas-stubs/core/indexes/multi.pyi b/pandas-stubs/core/indexes/multi.pyi index 8a017d82..69457d21 100644 --- a/pandas-stubs/core/indexes/multi.pyi +++ b/pandas-stubs/core/indexes/multi.pyi @@ -155,7 +155,7 @@ class MultiIndex(Index): def equal_levels(self, other): ... def union(self, other, sort=...): ... # pyrefly: ignore def intersection( # pyright: ignore[reportIncompatibleMethodOverride] - self, other: list | Self, sort: bool = ... + self, other: list | Self, sort: bool | None = ... ): ... def difference(self, other, sort=...): ... def astype(self, dtype: DtypeArg, copy: bool = ...) -> Self: ... diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 57fe5f04..9cdbbf91 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1739,9 +1739,18 @@ class Series(IndexOpsMixin[S1], NDFrame): *args: Any, **kwargs: Any, ) -> Series[S1]: ... + @overload + def cumprod( + self: Series[_str], + axis: AxisIndex = ..., + skipna: _bool = ..., + *args: Any, + **kwargs: Any, + ) -> Never: ... + @overload def cumprod( self, - axis: AxisIndex | None = ..., + axis: AxisIndex = ..., skipna: _bool = ..., *args: Any, **kwargs: Any, @@ -2219,6 +2228,13 @@ class TimestampSeries(Series[Timestamp]): **kwargs: Any, ) -> Timedelta: ... def diff(self, periods: int = ...) -> TimedeltaSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + def cumprod( + self, + axis: AxisIndex = ..., + skipna: _bool = ..., + *args: Any, + **kwargs: Any, + ) -> Never: ... class TimedeltaSeries(Series[Timedelta]): # ignores needed because of mypy @@ -2324,12 +2340,26 @@ class TimedeltaSeries(Series[Timedelta]): *args: Any, **kwargs: Any, ) -> TimedeltaSeries: ... + def cumprod( + self, + axis: AxisIndex = ..., + skipna: _bool = ..., + *args: Any, + **kwargs: Any, + ) -> Never: ... class PeriodSeries(Series[Period]): @property def dt(self) -> PeriodProperties: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __sub__(self, other: PeriodSeries) -> OffsetSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def diff(self, periods: int = ...) -> OffsetSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + def cumprod( + self, + axis: AxisIndex = ..., + skipna: _bool = ..., + *args: Any, + **kwargs: Any, + ) -> Never: ... class OffsetSeries(Series[BaseOffset]): @overload # type: ignore[override] @@ -2338,6 +2368,13 @@ class OffsetSeries(Series[BaseOffset]): def __radd__( # pyright: ignore[reportIncompatibleMethodOverride] self, other: BaseOffset ) -> OffsetSeries: ... + def cumprod( + self, + axis: AxisIndex = ..., + skipna: _bool = ..., + *args: Any, + **kwargs: Any, + ) -> Never: ... class IntervalSeries(Series[Interval[_OrderableT]], Generic[_OrderableT]): @property diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 2b448075..b3f566cd 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -172,6 +172,10 @@ def test_difference_none() -> None: # GH 253 check(assert_type(ind.difference([1]), "pd.Index[int]"), pd.Index) + # check with sort parameter + check(assert_type(ind.difference([1, None], sort=False), "pd.Index[int]"), pd.Index) + check(assert_type(ind.difference([1], sort=True), "pd.Index[int]"), pd.Index) + def test_str_split() -> None: # GH 194 @@ -314,6 +318,18 @@ def test_range_index_union(): ) +def test_index_union_sort() -> None: + """Test sort argument in pd.Index.union GH1264.""" + check( + assert_type(pd.Index(["e", "f"]).union(["a", "b", "c"], sort=True), pd.Index), + pd.Index, + ) + check( + assert_type(pd.Index(["e", "f"]).union(["a", "b", "c"], sort=False), pd.Index), + pd.Index, + ) + + def test_range_index_start_stop_step(): idx = pd.RangeIndex(3) check(assert_type(idx.start, int), int) @@ -1361,3 +1377,10 @@ def test_index_dict() -> None: ), pd.TimedeltaIndex, ) + + +def test_index_infer_objects() -> None: + """Test infer_objects method on Index.""" + df = pd.DataFrame({"A": ["a", 1, 2, 3]}) + idx = df.set_index("A").index[1:] + check(assert_type(idx.infer_objects(), pd.Index), pd.Index) diff --git a/tests/test_series.py b/tests/test_series.py index b71f6498..7f51f9ad 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -3941,3 +3941,37 @@ def test_series_index_type() -> None: if TYPE_CHECKING_INVALID_USAGE: t = pd.Series([1, 2], index="ab") # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType] + + +def test_timedelta_index_cumprod() -> None: + dates = pd.Series( + [ + pd.Timestamp("2020-01-01"), + pd.Timestamp("2020-01-15"), + pd.Timestamp("2020-02-01"), + ], + dtype="datetime64[ns]", + ) + as_period_series = pd.Series(pd.PeriodIndex(dates, freq="M")) + + offset_series = as_period_series - as_period_series + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(pd.Series(["a", "b"]).cumprod(), Never) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(offset_series.cumprod(), Never) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(pd.Series([pd.Timedelta(0), pd.Timedelta(1)]).cumprod(), Never) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type( + pd.Series( + [pd.Timestamp("2024-04-29"), pd.Timestamp("2034-08-28")] + ).cumprod(), + Never, + ) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(as_period_series.cumprod(), Never)