Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions pandas-stubs/_libs/tslibs/period.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ from pandas import (
Timedelta,
TimedeltaIndex,
)
from pandas.core.series import (
OffsetSeries,
)
from typing_extensions import TypeAlias

from pandas._libs.tslibs import NaTType
Expand Down Expand Up @@ -97,7 +94,7 @@ class Period(PeriodMixin):
def __add__(self, other: Index) -> PeriodIndex: ...
@overload
def __add__(
self, other: OffsetSeries | Series[Timedelta]
self, other: Series[BaseOffset] | Series[Timedelta]
) -> Series[Period]: ... # pyrefly: ignore[bad-specialization]
# ignore[misc] here because we know all other comparisons
# are False, so we use Literal[False]
Expand Down
32 changes: 22 additions & 10 deletions pandas-stubs/core/series.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
@overload
def diff(self: Series[Timedelta], periods: int = ...) -> Series[Timedelta]: ... # type: ignore[overload-overlap]
@overload
def diff(self: Series[Period], periods: int = ...) -> OffsetSeries: ... # type: ignore[overload-overlap]
def diff(self: Series[Period], periods: int = ...) -> Series[BaseOffset]: ... # type: ignore[overload-overlap]
@overload
def diff(self, periods: int = ...) -> Series[float]: ...
def autocorr(self, lag: int = 1) -> float: ...
Expand Down Expand Up @@ -1061,7 +1061,7 @@ class Series(IndexOpsMixin[S1], NDFrame):
convertDType: _bool = ...,
args: tuple = ...,
**kwargs: Any,
) -> OffsetSeries: ...
) -> Series[BaseOffset]: ...
@overload
def apply(
self,
Expand Down Expand Up @@ -2014,6 +2014,10 @@ class Series(IndexOpsMixin[S1], NDFrame):
other: _str | Sequence[_str] | np_ndarray_str | Index[_str] | Series[_str],
) -> Series[_str]: ...
@overload
def __radd__(self: Series[BaseOffset], other: Period) -> Series[Period]: ...
@overload
def __radd__(self: Series[BaseOffset], other: BaseOffset) -> Series[BaseOffset]: ...
@overload
def radd(
self: Series[Never],
other: complex | _ListLike | Index | Series,
Expand Down Expand Up @@ -4669,6 +4673,22 @@ class Series(IndexOpsMixin[S1], NDFrame):
**kwargs,
) -> np_1darray[np.int64]: ...
@overload
def to_numpy(
self: Series[BaseOffset],
dtype: None = None,
copy: bool = False,
na_value: Scalar = ...,
**kwargs,
) -> np_1darray[np.object_]: ...
@overload
def to_numpy(
self: Series[BaseOffset],
dtype: type[np.bytes_],
copy: bool = False,
na_value: Scalar = ...,
**kwargs,
) -> np_1darray[np.bytes_]: ...
@overload
def to_numpy( # pyright: ignore[reportIncompatibleMethodOverride]
self,
dtype: DTypeLike | None = None,
Expand Down Expand Up @@ -4762,14 +4782,6 @@ class _SeriesSubclassBase(Series[S1], Generic[S1, GenericT_co]):
**kwargs,
) -> np_1darray: ...

class OffsetSeries(_SeriesSubclassBase[BaseOffset, np.object_]):
@overload # type: ignore[override]
def __radd__(self, other: Period) -> Series[Period]: ...
@overload
def __radd__( # pyright: ignore[reportIncompatibleMethodOverride]
self, other: BaseOffset
) -> OffsetSeries: ...

class IntervalSeries(
_SeriesSubclassBase[Interval[_OrderableT], np.object_], Generic[_OrderableT]
):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ scipy = { version = ">=1.9.1", python = "<3.14" }
scipy-stubs = ">=1.15.3.0"
SQLAlchemy = ">=2.0.39"
types-python-dateutil = ">=2.8.19"
beautifulsoup4 = "<=4.13.5"
beautifulsoup4 = ">=4.13.5"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
beautifulsoup4 = ">=4.13.5"
beautifulsoup4 = ">=4.14.2"

html5lib = ">=1.1"
python-calamine = ">=0.2.0"

Expand Down
13 changes: 5 additions & 8 deletions tests/series/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@
)

if TYPE_CHECKING:
from pandas.core.series import OffsetSeries

from tests import (
BooleanDtypeArg,
BytesDtypeArg,
Expand All @@ -89,9 +87,6 @@
VoidDtypeArg,
)

else:
OffsetSeries: TypeAlias = pd.Series

if not PD_LTE_23:
from pandas.errors import Pandas4Warning # type: ignore[attr-defined] # pyright: ignore # isort: skip
else:
Expand Down Expand Up @@ -3487,7 +3482,7 @@ def test_diff() -> None:
pd.Series(
pd.period_range(start="2017-01-01", end="2017-02-01", freq="D")
).diff(),
"OffsetSeries",
"pd.Series[BaseOffset]",
),
pd.Series,
BaseOffset,
Expand All @@ -3499,7 +3494,7 @@ def test_diff() -> None:
pd.Series(
pd.period_range(start="2017-01-01", end="2017-02-01", freq="D")
).diff(),
"OffsetSeries",
"pd.Series[BaseOffset]",
),
pd.Series,
BaseOffset,
Expand Down Expand Up @@ -3672,7 +3667,9 @@ def test_apply_dateoffset() -> None:
months = [1, 2, 3]
s = pd.Series(months)
check(
assert_type(s.apply(lambda x: pd.DateOffset(months=x)), "OffsetSeries"),
assert_type(
s.apply(lambda x: pd.DateOffset(months=x)), "pd.Series[BaseOffset]"
),
pd.Series,
pd.DateOffset,
)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_timefuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
if TYPE_CHECKING:
from pandas.core.series import (
IntervalSeries,
OffsetSeries,
)

if not PD_LTE_23:
Expand Down Expand Up @@ -947,7 +946,8 @@ def test_series_types_to_numpy() -> None:
ts_s = pd.to_datetime(pd.Series(["2020-01-01", "2020-01-02"]))
p_s = pd.Series(pd.period_range("2012-1-1", periods=10, freq="D"))
o_s = cast(
"OffsetSeries", pd.Series([pd.DateOffset(days=1), pd.DateOffset(days=2)])
"pd.Series[BaseOffset]",
pd.Series([pd.DateOffset(days=1), pd.DateOffset(days=2)]),
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you see if we can create a Series.__new__() overload that would accept a sequence of BaseOffset so that we don't need the cast here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So turns out this creates a Series[DateOffset] and not Series[BaseOffset] that is why this is an issue, not sure why though it is not working since it is supposed to inherit from BaseOffset.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I checked and seems like Series[DateOffset] does not match with Series[BaseOffset] even though DateOffset is always a BaseOffset:
assert_type(o_s, "pd.Series[BaseOffset]") ■ "assert_type" mismatch: expected "Series[BaseOffset]" but received "Series[DateOffset]"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to add an overload for Series.__new__() that accepts a sequence of BaseOffset and then it should work. Similar to how there are overloads that produce Series[Timestamp], Series[Timedelta], etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the to_numpy overloads and added the new overloads and it is looking good!

i_s = cast("IntervalSeries", pd.interval_range(1, 2).to_series())

Expand Down