diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c04587ea9..a94f5c741 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,8 +2,8 @@ minimum_pre_commit_version: 2.15.0 ci: autofix_prs: false repos: -- repo: https://github.com/python/black - rev: 25.1.0 +- repo: https://github.com/psf/black + rev: 25.9.0 hooks: - id: black - repo: https://github.com/PyCQA/isort @@ -11,7 +11,7 @@ repos: hooks: - id: isort - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.10 + rev: v0.13.2 hooks: - id: ruff-check args: [ diff --git a/docs/philosophy.md b/docs/philosophy.md index e8ee764a4..d434e31bd 100644 --- a/docs/philosophy.md +++ b/docs/philosophy.md @@ -55,12 +55,12 @@ revealed by `mypy` as follows: ```text ttest.py:5: note: Revealed type is "pandas.core.series.Series[pandas._libs.tslibs.timestamps.Timestamp]" ttest.py:7: note: Revealed type is "pandas.core.series.Series[pandas._libs.tslibs.timestamps.Timestamp]" -ttest.py:9: note: Revealed type is "pandas.core.series.TimedeltaSeries" +ttest.py:9: note: Revealed type is "pandas.core.series.Series[pandas._libs.tslibs.timestamps.Timedelta]" ttest.py:10: error: Unsupported operand types for + ("Series[Timestamp]" and "Series[Timestamp]") [operator] ``` The type `Series[Timestamp]` is the result of creating a series from `pd.to_datetime()`, while -the type `TimedeltaSeries` is the result of subtracting two `Series[Timestamp]` as well as +the type `Series[Timedelta]` is the result of subtracting two `Series[Timestamp]` as well as the result of `pd.to_timedelta()`. ### Progressive arithmetic typing for generic Series diff --git a/pandas-stubs/_libs/interval.pyi b/pandas-stubs/_libs/interval.pyi index bdbac57ad..5152f32b9 100644 --- a/pandas-stubs/_libs/interval.pyi +++ b/pandas-stubs/_libs/interval.pyi @@ -13,7 +13,6 @@ from pandas import ( Timedelta, Timestamp, ) -from pandas.core.series import TimedeltaSeries from pandas._typing import ( IntervalClosedType, @@ -173,7 +172,7 @@ class Interval(IntervalMixin, Generic[_OrderableT]): @overload def __gt__( self, - other: Series[int] | Series[float] | Series[Timestamp] | TimedeltaSeries, + other: Series[int] | Series[float] | Series[Timestamp] | Series[Timedelta], ) -> Series[bool]: ... @overload def __lt__(self, other: Interval[_OrderableT]) -> bool: ... @@ -184,7 +183,7 @@ class Interval(IntervalMixin, Generic[_OrderableT]): @overload def __lt__( self, - other: Series[int] | Series[float] | Series[Timestamp] | TimedeltaSeries, + other: Series[int] | Series[float] | Series[Timestamp] | Series[Timedelta], ) -> Series[bool]: ... @overload def __ge__(self, other: Interval[_OrderableT]) -> bool: ... @@ -195,7 +194,7 @@ class Interval(IntervalMixin, Generic[_OrderableT]): @overload def __ge__( self, - other: Series[int] | Series[float] | Series[Timestamp] | TimedeltaSeries, + other: Series[int] | Series[float] | Series[Timestamp] | Series[Timedelta], ) -> Series[bool]: ... @overload def __le__(self, other: Interval[_OrderableT]) -> bool: ... diff --git a/pandas-stubs/_libs/tslibs/period.pyi b/pandas-stubs/_libs/tslibs/period.pyi index b658270ed..00847c217 100644 --- a/pandas-stubs/_libs/tslibs/period.pyi +++ b/pandas-stubs/_libs/tslibs/period.pyi @@ -15,7 +15,6 @@ from pandas import ( from pandas.core.series import ( OffsetSeries, PeriodSeries, - TimedeltaSeries, ) from typing_extensions import TypeAlias @@ -86,7 +85,7 @@ class Period(PeriodMixin): @overload def __sub__(self, other: PeriodIndex) -> Index: ... @overload - def __sub__(self, other: TimedeltaSeries) -> PeriodSeries: ... + def __sub__(self, other: Series[Timedelta]) -> PeriodSeries: ... @overload def __sub__(self, other: TimedeltaIndex) -> PeriodIndex: ... @overload @@ -96,7 +95,7 @@ class Period(PeriodMixin): @overload def __add__(self, other: Index) -> PeriodIndex: ... @overload - def __add__(self, other: OffsetSeries | TimedeltaSeries) -> PeriodSeries: ... + def __add__(self, other: OffsetSeries | Series[Timedelta]) -> PeriodSeries: ... # ignore[misc] here because we know all other comparisons # are False, so we use Literal[False] @overload @@ -172,7 +171,7 @@ class Period(PeriodMixin): @overload def __radd__(self, other: Index) -> Index: ... @overload - def __radd__(self, other: TimedeltaSeries) -> PeriodSeries: ... + def __radd__(self, other: Series[Timedelta]) -> PeriodSeries: ... @overload def __radd__(self, other: NaTType) -> NaTType: ... @property diff --git a/pandas-stubs/_libs/tslibs/timedeltas.pyi b/pandas-stubs/_libs/tslibs/timedeltas.pyi index 8e0498f55..a8f03fbcb 100644 --- a/pandas-stubs/_libs/tslibs/timedeltas.pyi +++ b/pandas-stubs/_libs/tslibs/timedeltas.pyi @@ -17,7 +17,6 @@ from pandas import ( Series, TimedeltaIndex, ) -from pandas.core.series import TimedeltaSeries from typing_extensions import ( Self, TypeAlias, @@ -162,10 +161,7 @@ class Timedelta(timedelta): @overload def __add__(self, other: pd.TimedeltaIndex) -> pd.TimedeltaIndex: ... @overload - def __add__( - self, - other: TimedeltaSeries, - ) -> TimedeltaSeries: ... + def __add__(self, other: Series[Timedelta]) -> Series[Timedelta]: ... @overload def __add__(self, other: Series[Timestamp]) -> Series[Timestamp]: ... @overload @@ -198,9 +194,7 @@ class Timedelta(timedelta): @overload def __sub__(self, other: pd.TimedeltaIndex) -> TimedeltaIndex: ... @overload - def __sub__( - self, other: TimedeltaSeries | Series[pd.Timedelta] - ) -> TimedeltaSeries: ... + def __sub__(self, other: Series[pd.Timedelta]) -> Series[pd.Timedelta]: ... @overload def __rsub__(self, other: timedelta | Timedelta | np.timedelta64) -> Timedelta: ... @overload @@ -234,9 +228,9 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.integer] | np_ndarray[ShapeT, np.floating] ) -> np_ndarray[ShapeT, np.timedelta64]: ... @overload - def __mul__(self, other: Series[int]) -> TimedeltaSeries: ... + def __mul__(self, other: Series[int]) -> Series[Timedelta]: ... @overload - def __mul__(self, other: Series[float]) -> TimedeltaSeries: ... + def __mul__(self, other: Series[float]) -> Series[Timedelta]: ... @overload def __mul__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... @overload @@ -246,9 +240,9 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.floating] | np_ndarray[ShapeT, np.integer] ) -> np_ndarray[ShapeT, np.timedelta64]: ... @overload - def __rmul__(self, other: Series[int]) -> TimedeltaSeries: ... + def __rmul__(self, other: Series[int]) -> Series[Timedelta]: ... @overload - def __rmul__(self, other: Series[float]) -> TimedeltaSeries: ... + def __rmul__(self, other: Series[float]) -> Series[Timedelta]: ... # maybe related to https://github.com/python/mypy/issues/10755 @overload def __rmul__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... @@ -269,11 +263,11 @@ class Timedelta(timedelta): @overload def __floordiv__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... @overload - def __floordiv__(self, other: Series[int]) -> TimedeltaSeries: ... + def __floordiv__(self, other: Series[int]) -> Series[Timedelta]: ... @overload - def __floordiv__(self, other: Series[float]) -> TimedeltaSeries: ... + def __floordiv__(self, other: Series[float]) -> Series[Timedelta]: ... @overload - def __floordiv__(self, other: TimedeltaSeries) -> Series[int]: ... + def __floordiv__(self, other: Series[Timedelta]) -> Series[int]: ... @overload def __floordiv__(self, other: NaTType | None) -> float: ... @overload @@ -294,11 +288,11 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.integer] | np_ndarray[ShapeT, np.floating] ) -> np_ndarray[ShapeT, np.timedelta64]: ... @overload - def __truediv__(self, other: TimedeltaSeries) -> Series[float]: ... + def __truediv__(self, other: Series[Timedelta]) -> Series[float]: ... @overload - def __truediv__(self, other: Series[int]) -> TimedeltaSeries: ... + def __truediv__(self, other: Series[int]) -> Series[Timedelta]: ... @overload - def __truediv__(self, other: Series[float]) -> TimedeltaSeries: ... + def __truediv__(self, other: Series[float]) -> Series[Timedelta]: ... @overload def __truediv__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... def __rtruediv__(self, other: timedelta | Timedelta | NaTType) -> float: ... @@ -306,7 +300,7 @@ class Timedelta(timedelta): @overload def __eq__(self, other: timedelta | Timedelta | np.timedelta64) -> bool: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] @overload - def __eq__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... # type: ignore[overload-overlap] + def __eq__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... # type: ignore[overload-overlap] @overload def __eq__(self, other: Index) -> np_1darray[np.bool]: ... # type: ignore[overload-overlap] @overload @@ -319,7 +313,7 @@ class Timedelta(timedelta): @overload def __ne__(self, other: timedelta | Timedelta | np.timedelta64) -> bool: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] @overload - def __ne__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... # type: ignore[overload-overlap] + def __ne__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... # type: ignore[overload-overlap] @overload def __ne__(self, other: Index) -> np_1darray[np.bool]: ... # type: ignore[overload-overlap] @overload @@ -334,7 +328,7 @@ class Timedelta(timedelta): @overload def __mod__(self, other: float) -> Timedelta: ... @overload - def __mod__(self, other: Series[int] | Series[float]) -> TimedeltaSeries: ... + def __mod__(self, other: Series[int] | Series[float]) -> Series[Timedelta]: ... @overload def __mod__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... @overload @@ -343,8 +337,8 @@ class Timedelta(timedelta): ) -> np_ndarray[ShapeT, np.timedelta64]: ... @overload def __mod__( - self, other: Series[int] | Series[float] | TimedeltaSeries - ) -> TimedeltaSeries: ... + self, other: Series[int] | Series[float] | Series[Timedelta] + ) -> Series[Timedelta]: ... def __divmod__(self, other: timedelta) -> tuple[int, Timedelta]: ... # Mypy complains Forward operator "" is not callable, so ignore misc # for le, lt ge and gt @@ -358,7 +352,7 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.timedelta64] ) -> np_ndarray[ShapeT, np.bool_]: ... @overload - def __le__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... + def __le__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... # Override due to more types supported than dt.timedelta @overload # type: ignore[override] def __lt__(self, other: timedelta | Timedelta | np.timedelta64) -> bool: ... # type: ignore[misc] @@ -369,7 +363,7 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.timedelta64] ) -> np_ndarray[ShapeT, np.bool_]: ... @overload - def __lt__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... + def __lt__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... # Override due to more types supported than dt.timedelta @overload # type: ignore[override] def __ge__(self, other: timedelta | Timedelta | np.timedelta64) -> bool: ... # type: ignore[misc] @@ -380,7 +374,7 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.timedelta64] ) -> np_ndarray[ShapeT, np.bool_]: ... @overload - def __ge__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... + def __ge__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... # Override due to more types supported than dt.timedelta @overload # type: ignore[override] def __gt__(self, other: timedelta | Timedelta | np.timedelta64) -> bool: ... # type: ignore[misc] @@ -391,7 +385,7 @@ class Timedelta(timedelta): self, other: np_ndarray[ShapeT, np.timedelta64] ) -> np_ndarray[ShapeT, np.bool_]: ... @overload - def __gt__(self, other: TimedeltaSeries | Series[pd.Timedelta]) -> Series[bool]: ... + def __gt__(self, other: Series[pd.Timedelta]) -> Series[bool]: ... def __hash__(self) -> int: ... def isoformat(self) -> str: ... def to_numpy(self) -> np.timedelta64: ... diff --git a/pandas-stubs/_libs/tslibs/timestamps.pyi b/pandas-stubs/_libs/tslibs/timestamps.pyi index 277496785..fd34007d4 100644 --- a/pandas-stubs/_libs/tslibs/timestamps.pyi +++ b/pandas-stubs/_libs/tslibs/timestamps.pyi @@ -22,10 +22,7 @@ from pandas import ( TimedeltaIndex, ) from pandas.core.indexes.base import Index -from pandas.core.series import ( - Series, - TimedeltaSeries, -) +from pandas.core.series import Series from typing_extensions import ( Never, Self, @@ -225,8 +222,6 @@ class Timestamp(datetime, SupportsIndex): @overload def __add__(self, other: timedelta | np.timedelta64 | Tick) -> Self: ... @overload - def __add__(self, other: TimedeltaSeries) -> Series[Timestamp]: ... - @overload def __add__(self, other: TimedeltaIndex) -> DatetimeIndex: ... @overload def __radd__(self, other: timedelta) -> Self: ... @@ -244,8 +239,6 @@ class Timestamp(datetime, SupportsIndex): @overload def __sub__(self, other: TimedeltaIndex) -> DatetimeIndex: ... @overload - def __sub__(self, other: TimedeltaSeries) -> Series[Timestamp]: ... - @overload def __sub__( self, other: np_ndarray[ShapeT, np.timedelta64] ) -> np_ndarray[ShapeT, np.datetime64]: ... diff --git a/pandas-stubs/core/arraylike.pyi b/pandas-stubs/core/arraylike.pyi index bdceaf21d..45f5f0fc8 100644 --- a/pandas-stubs/core/arraylike.pyi +++ b/pandas-stubs/core/arraylike.pyi @@ -19,14 +19,6 @@ class OpsMixin: def __rxor__(self, other: Any) -> Self: ... # ------------------------------------------------------------- # Arithmetic Methods - def __mul__(self, other: Any) -> Self: ... - def __rmul__(self, other: Any) -> Self: ... - # Handled by subclasses that specify only the valid values - # that can be passed - # def __truediv__(self, other: Any) -> Self: ... - # def __rtruediv__(self, other: Any) -> Self: ... - # def __floordiv__(self, other: Any) -> Self: ... - # def __rfloordiv__(self, other: Any) -> Self: ... def __mod__(self, other: Any) -> Self: ... def __rmod__(self, other: Any) -> Self: ... def __divmod__(self, other: Any) -> tuple[Self, Self]: ... diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 27fb80f45..ce61a30f1 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -763,7 +763,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): @overload def to_xml( self, - path_or_buffer: Literal[None] = ..., + path_or_buffer: None = ..., index: bool = ..., root_name: str | None = ..., row_name: str | None = ..., @@ -1806,6 +1806,8 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): level: Level | None = ..., fill_value: float | None = None, ) -> Self: ... + def __mul__(self, other: Any) -> Self: ... + def __rmul__(self, other: Any) -> Self: ... @final def add_prefix(self, prefix: _str, axis: Axis | None = None) -> Self: ... @final diff --git a/pandas-stubs/core/groupby/indexing.pyi b/pandas-stubs/core/groupby/indexing.pyi index c013d4c74..150a7a86b 100644 --- a/pandas-stubs/core/groupby/indexing.pyi +++ b/pandas-stubs/core/groupby/indexing.pyi @@ -27,6 +27,6 @@ class GroupByNthSelector(Generic[_GroupByT]): def __call__( self, n: PositionalIndexer | tuple, - dropna: Literal["any", "all", None] = ..., + dropna: Literal["any", "all"] | None = ..., ) -> DataFrame | Series: ... def __getitem__(self, n: PositionalIndexer | tuple) -> DataFrame | Series: ... diff --git a/pandas-stubs/core/indexes/accessors.pyi b/pandas-stubs/core/indexes/accessors.pyi index a4617f7ae..175756f39 100644 --- a/pandas-stubs/core/indexes/accessors.pyi +++ b/pandas-stubs/core/indexes/accessors.pyi @@ -30,7 +30,6 @@ from pandas.core.frame import DataFrame from pandas.core.series import ( PeriodSeries, Series, - TimedeltaSeries, ) from typing_extensions import Never @@ -165,7 +164,11 @@ class _DatetimeLikeOps( _DTTimestampTimedeltaReturnType = TypeVar( "_DTTimestampTimedeltaReturnType", - bound=Series | Series[Timestamp] | TimedeltaSeries | DatetimeIndex | TimedeltaIndex, + bound=Series + | Series[Timestamp] + | Series[Timedelta] + | DatetimeIndex + | TimedeltaIndex, ) class _DatetimeRoundingMethods(Generic[_DTTimestampTimedeltaReturnType]): @@ -316,7 +319,7 @@ class _TimedeltaPropertiesNoRounding( class TimedeltaProperties( Properties, _TimedeltaPropertiesNoRounding[Series[int], Series[float]], - _DatetimeRoundingMethods[TimedeltaSeries], + _DatetimeRoundingMethods[Series[Timedelta]], ): @property def unit(self) -> TimeUnit: ... @@ -440,7 +443,7 @@ class _dtDescriptor(CombinedDatetimelikeProperties, Generic[S1]): ) -> TimestampProperties: ... @overload def __get__( - self, instance: Series[Timedelta] | TimedeltaSeries, owner: Any + self, instance: Series[Timedelta], owner: Any ) -> TimedeltaProperties: ... @overload def __get__( diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index d327a47f0..034b04cc5 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -477,7 +477,6 @@ class Index(IndexOpsMixin[S1]): def __ge__(self, other: Self | S1) -> np_1darray[np.bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __lt__(self, other: Self | S1) -> np_1darray[np.bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __gt__(self, other: Self | S1) -> np_1darray[np.bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - # overwrite inherited methods from OpsMixin @overload def __add__(self: Index[Never], other: _str) -> Never: ... @overload @@ -630,7 +629,7 @@ class Index(IndexOpsMixin[S1]): @overload def __sub__(self: Index[Never], other: DatetimeIndex) -> Never: ... @overload - def __sub__(self: Index[Never], other: complex | NumListLike | Index) -> Index: ... + def __sub__(self: Index[Never], other: complex | _ListLike | Index) -> Index: ... @overload def __sub__(self, other: Index[Never]) -> Index: ... @overload @@ -770,46 +769,23 @@ class Index(IndexOpsMixin[S1]): self: Index[int] | Index[float], other: timedelta ) -> TimedeltaIndex: ... @overload - def __mul__(self, other: Any) -> Self: ... + def __mul__( + self, other: float | Sequence[float] | Index[int] | Index[float] + ) -> Self: ... + def __rmul__( + self, other: float | Sequence[float] | Index[int] | Index[float] + ) -> Self: ... def __floordiv__( - self, - other: ( - float - | IndexOpsMixin[int] - | IndexOpsMixin[float] - | Sequence[int] - | Sequence[float] - ), + self, other: float | Sequence[float] | Index[int] | Index[float] ) -> Self: ... def __rfloordiv__( - self, - other: ( - float - | IndexOpsMixin[int] - | IndexOpsMixin[float] - | Sequence[int] - | Sequence[float] - ), + self, other: float | Sequence[float] | Index[int] | Index[float] ) -> Self: ... def __truediv__( - self, - other: ( - float - | IndexOpsMixin[int] - | IndexOpsMixin[float] - | Sequence[int] - | Sequence[float] - ), + self, other: float | Sequence[float] | Index[int] | Index[float] ) -> Self: ... def __rtruediv__( - self, - other: ( - float - | IndexOpsMixin[int] - | IndexOpsMixin[float] - | Sequence[int] - | Sequence[float] - ), + self, other: float | Sequence[float] | Index[int] | Index[float] ) -> Self: ... def infer_objects(self, copy: bool = True) -> Self: ... diff --git a/pandas-stubs/core/indexes/datetimes.pyi b/pandas-stubs/core/indexes/datetimes.pyi index 741eab022..3f882c808 100644 --- a/pandas-stubs/core/indexes/datetimes.pyi +++ b/pandas-stubs/core/indexes/datetimes.pyi @@ -23,10 +23,7 @@ from pandas import ( from pandas.core.arrays import DatetimeArray from pandas.core.indexes.accessors import DatetimeIndexProperties from pandas.core.indexes.datetimelike import DatetimeTimedeltaMixin -from pandas.core.series import ( - Series, - TimedeltaSeries, -) +from pandas.core.series import Series from typing_extensions import Self from pandas._libs.tslibs.offsets import DateOffset @@ -69,15 +66,10 @@ class DatetimeIndex( # various ignores needed for mypy, as we do want to restrict what can be used in # arithmetic for these types - @overload # type: ignore[override] - def __add__(self, other: TimedeltaSeries) -> Series[Timestamp]: ... - @overload def __add__( # pyright: ignore[reportIncompatibleMethodOverride] - self, other: timedelta | Timedelta | TimedeltaIndex | BaseOffset + self, other: timedelta | Timedelta | TimedeltaIndex | BaseOffset # type: ignore[override] ) -> DatetimeIndex: ... @overload # type: ignore[override] - def __sub__(self, other: TimedeltaSeries) -> Series[Timestamp]: ... - @overload def __sub__( self, other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaIndex | BaseOffset, diff --git a/pandas-stubs/core/indexes/interval.pyi b/pandas-stubs/core/indexes/interval.pyi index 787d5344d..2ef586772 100644 --- a/pandas-stubs/core/indexes/interval.pyi +++ b/pandas-stubs/core/indexes/interval.pyi @@ -13,9 +13,6 @@ import numpy as np import pandas as pd from pandas import Index from pandas.core.indexes.extension import ExtensionIndex -from pandas.core.series import ( - TimedeltaSeries, -) from typing_extensions import TypeAlias from pandas._libs.interval import ( @@ -59,7 +56,7 @@ _EdgesTimestamp: TypeAlias = ( _EdgesTimedelta: TypeAlias = ( Sequence[pd.Timedelta] | npt.NDArray[np.timedelta64] - | TimedeltaSeries + | pd.Series[pd.Timedelta] | pd.TimedeltaIndex ) _TimestampLike: TypeAlias = pd.Timestamp | np.datetime64 | dt.datetime diff --git a/pandas-stubs/core/indexes/timedeltas.pyi b/pandas-stubs/core/indexes/timedeltas.pyi index 5c998f80c..0b3392f7c 100644 --- a/pandas-stubs/core/indexes/timedeltas.pyi +++ b/pandas-stubs/core/indexes/timedeltas.pyi @@ -19,7 +19,7 @@ from pandas.core.indexes.accessors import TimedeltaIndexProperties from pandas.core.indexes.datetimelike import DatetimeTimedeltaMixin from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.period import PeriodIndex -from pandas.core.series import TimedeltaSeries +from pandas.core.series import Series from typing_extensions import Self from pandas._libs import ( @@ -62,9 +62,9 @@ class TimedeltaIndex( def __sub__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: dt.timedelta | np.timedelta64 | np_ndarray_td | Self ) -> Self: ... - def __mul__(self, other: num) -> Self: ... + def __mul__(self, other: float) -> Self: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] @overload # type: ignore[override] - def __truediv__(self, other: num | Sequence[float]) -> Self: ... + def __truediv__(self, other: float | Sequence[float]) -> Self: ... @overload def __truediv__( # pyright: ignore[reportIncompatibleMethodOverride] self, other: dt.timedelta | Sequence[dt.timedelta] @@ -81,7 +81,7 @@ class TimedeltaIndex( @property def inferred_type(self) -> str: ... @final - def to_series(self, index=..., name: Hashable = ...) -> TimedeltaSeries: ... + def to_series(self, index=..., name: Hashable = ...) -> Series[Timedelta]: ... def shift(self, periods: int = 1, freq=...) -> Self: ... @overload diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index fa0013fe2..96509c4c6 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -68,7 +68,6 @@ from pandas.core.groupby.groupby import BaseGroupBy from pandas.core.indexers import BaseIndexer from pandas.core.indexes.accessors import ( PeriodProperties, - TimedeltaProperties, _dtDescriptor, ) from pandas.core.indexes.category import CategoricalIndex @@ -190,6 +189,7 @@ from pandas._typing import ( WriteBuffer, _T_co, np_1darray, + np_ndarray, np_ndarray_anyint, np_ndarray_bool, np_ndarray_complex, @@ -214,6 +214,10 @@ class _SupportsAdd(Protocol[_T_co]): class _SupportsMul(Protocol[_T_co]): def __mul__(self, value: Self, /) -> _T_co: ... +@type_check_only +class SupportsTruedivInt(Protocol[_T_co]): + def __truediv__(self, value: int, /) -> _T_co: ... + class _iLocIndexerSeries(_iLocIndexer, Generic[S1]): # get item @overload @@ -367,7 +371,7 @@ class Series(IndexOpsMixin[S1], NDFrame): dtype: TimedeltaDtypeArg = ..., name: Hashable = ..., copy: bool = ..., - ) -> TimedeltaSeries: ... + ) -> Series[Timedelta]: ... @overload def __new__( cls, @@ -769,6 +773,8 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def unique(self: Series[Timestamp]) -> DatetimeArray: ... # type: ignore[overload-overlap] @overload + def unique(self: Series[Timedelta]) -> TimedeltaArray: ... # type: ignore[overload-overlap] + @overload def unique(self) -> np.ndarray: ... @overload def drop_duplicates( @@ -834,7 +840,9 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def diff(self: Series[_str], periods: int = ...) -> Never: ... @overload - def diff(self: Series[Timestamp], periods: int = ...) -> TimedeltaSeries: ... # type: ignore[overload-overlap] + def diff(self: Series[Timestamp], periods: int = ...) -> Series[Timedelta]: ... # type: ignore[overload-overlap] + @overload + def diff(self: Series[Timedelta], periods: int = ...) -> Series[Timedelta]: ... # type: ignore[overload-overlap] @overload def diff(self, periods: int = ...) -> Series[float]: ... def autocorr(self, lag: int = 1) -> float: ... @@ -1334,7 +1342,7 @@ class Series(IndexOpsMixin[S1], NDFrame): dtype: TimedeltaDtypeArg, copy: _bool = ..., errors: IgnoreRaise = ..., - ) -> TimedeltaSeries: ... + ) -> Series[Timedelta]: ... @overload def astype( self, @@ -1646,7 +1654,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self: Series[Never], other: complex | _ListLike | Index | Series ) -> Series: ... @overload - def __add__(self, other: Index[Never] | Series[Never]) -> Series: ... # type: ignore[overload-overlap] + def __add__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload def __add__( self: Series[bool], @@ -1736,23 +1744,26 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries | BaseOffset ), ) -> Series[Timestamp]: ... @overload def __add__( self: Series[Timedelta], - other: datetime | np.datetime64 | np_ndarray_dt | Series[Timestamp], + other: ( + datetime | np.datetime64 | np_ndarray_dt | DatetimeIndex | Series[Timestamp] + ), ) -> Series[Timestamp]: ... @overload def __add__( self: Series[Timedelta], - other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaSeries, - ) -> TimedeltaSeries: ... - @overload - def __add__( - self: Series[Timedelta], other: Series[Timedelta] + other: ( + timedelta + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), ) -> Series[Timedelta]: ... @overload def __add__(self: Series[Timedelta], other: Period) -> PeriodSeries: ... @@ -1767,7 +1778,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def add( self, - other: Series[Never], + other: Index[Never] | Series[Never], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -1901,7 +1912,6 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries | BaseOffset ), level: Level | None = None, @@ -1909,15 +1919,30 @@ class Series(IndexOpsMixin[S1], NDFrame): axis: int = 0, ) -> Series[Timestamp]: ... @overload + def add( + self: Series[Timedelta], + other: ( + datetime + | Sequence[datetime] + | np.datetime64 + | np_ndarray_dt + | DatetimeIndex + | Series[Timestamp] + ), + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[Timestamp]: ... + @overload def add( self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries ), level: Level | None = None, fill_value: float | None = None, @@ -1936,6 +1961,8 @@ class Series(IndexOpsMixin[S1], NDFrame): self: Series[Never], other: complex | _ListLike | Index | Series ) -> Series: ... @overload + def __radd__(self, other: Index[Never] | Series[Never]) -> Series: ... + @overload def __radd__( self: Series[bool], other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], @@ -2023,16 +2050,28 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries | BaseOffset ), ) -> Series[Timestamp]: ... @overload def __radd__( self: Series[Timedelta], - other: datetime | np.datetime64 | np_ndarray_dt | Series[Timestamp], + other: ( + datetime | np.datetime64 | np_ndarray_dt | DatetimeIndex | Series[Timestamp] + ), ) -> Series[Timestamp]: ... @overload + def __radd__( + self: Series[Timedelta], + other: ( + timedelta + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + ) -> Series[Timedelta]: ... + @overload def __radd__(self: Series[Timedelta], other: Period) -> PeriodSeries: ... @overload def radd( @@ -2044,8 +2083,8 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series: ... @overload def radd( - self: Series[S1], - other: Series[Never], + self, + other: Index[Never] | Series[Never], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2179,7 +2218,6 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries | BaseOffset ), level: Level | None = None, @@ -2187,15 +2225,30 @@ class Series(IndexOpsMixin[S1], NDFrame): axis: int = 0, ) -> Series[Timestamp]: ... @overload + def radd( + self: Series[Timedelta], + other: ( + datetime + | Sequence[datetime] + | np.datetime64 + | np_ndarray_dt + | DatetimeIndex + | Series[Timestamp] + ), + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[Timestamp]: ... + @overload def radd( self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries ), level: Level | None = None, fill_value: float | None = None, @@ -2217,200 +2270,531 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def __and__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... def __eq__(self, other: object) -> Series[_bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - def __floordiv__(self, other: num | _ListLike | Series[S1]) -> Series[int]: ... - def __ge__( # type: ignore[override] - self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date - ) -> Series[_bool]: ... - def __gt__( # type: ignore[override] - self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date - ) -> Series[_bool]: ... - def __le__( # type: ignore[override] - self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date - ) -> Series[_bool]: ... - def __lt__( # type: ignore[override] - self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date - ) -> Series[_bool]: ... - @overload - def __mul__( # type: ignore[overload-overlap] - self: Series[Never], other: complex | NumListLike | Series - ) -> Series: ... - @overload - def __mul__(self, other: Series[Never]) -> Series: ... # type: ignore[overload-overlap] - @overload - def __mul__( - self: Series[bool], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], - ) -> Series[T_COMPLEX]: ... @overload - def __mul__(self: Series[bool], other: np_ndarray_bool) -> Series[bool]: ... + def __floordiv__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload - def __mul__(self: Series[bool], other: np_ndarray_anyint) -> Series[int]: ... + def __floordiv__( + self: Series[int] | Series[float], + other: np_ndarray_bool | np_ndarray_complex | np_ndarray_dt | np_ndarray_td, + ) -> Never: ... @overload - def __mul__(self: Series[bool], other: np_ndarray_float) -> Series[float]: ... + def __floordiv__( + self: Series[bool] | Series[complex], other: np_ndarray + ) -> Never: ... @overload - def __mul__( + def __floordiv__( self: Series[int], other: ( - bool | Sequence[bool] | np_ndarray_bool | np_ndarray_anyint | Series[bool] + Just[int] + | Sequence[Just[int]] + | np_ndarray_anyint + | Index[int] + | Series[int] ), ) -> Series[int]: ... @overload - def __mul__( + def __floordiv__( self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], - ) -> Series[T_COMPLEX]: ... - @overload - def __mul__(self: Series[int], other: np_ndarray_float) -> Series[float]: ... - @overload - def __mul__( - self: Series[float], other: ( - int - | Sequence[int] - | np_ndarray_bool - | np_ndarray_anyint + Just[float] + | Sequence[Just[float]] | np_ndarray_float - | Series[T_INT] + | Index[float] + | Series[float] ), ) -> Series[float]: ... @overload - def __mul__( + def __floordiv__( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], - ) -> Series[T_COMPLEX]: ... - @overload - def __mul__( - self: Series[complex], other: ( - T_COMPLEX - | Sequence[T_COMPLEX] - | np_ndarray_bool + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] | np_ndarray_anyint | np_ndarray_float - | Series[T_COMPLEX] + | Index[int] + | Index[float] + | Series[int] + | Series[float] ), - ) -> Series[complex]: ... - @overload - def __mul__( - self: Series[T_COMPLEX], other: np_ndarray_complex - ) -> Series[complex]: ... - @overload - def __mul__( - self: Series[bool] | Series[int] | Series[float], - other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaSeries, - ) -> TimedeltaSeries: ... + ) -> Series[float]: ... @overload - def __mul__( - self: Series[bool] | Series[int] | Series[float], other: Series[Timedelta] - ) -> Series[Timedelta]: ... + def __floordiv__( + self: Series[Timedelta], + other: np_ndarray_bool | np_ndarray_complex | np_ndarray_dt, + ) -> Never: ... @overload - def __mul__( + def __floordiv__( self: Series[Timedelta], other: ( - float - | Sequence[float] - | np_ndarray_bool + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] | np_ndarray_anyint | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] ), - ) -> TimedeltaSeries: ... - @overload - def __mul__( - self: Series[Timedelta], other: Series[bool] | Series[int] | Series[float] ) -> Series[Timedelta]: ... @overload - def mul( - self: Series[Never], - other: complex | _ListLike | Series, - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series: ... + def __floordiv__( + self: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + ) -> Series[int]: ... @overload - def mul( # type: ignore[overload-overlap] + def floordiv( self, - other: Series[Never], - level: Level | None = None, + other: Index[Never] | Series[Never], + level: Level | None = ..., fill_value: float | None = None, - axis: int = 0, + axis: AxisIndex | None = 0, ) -> Series: ... @overload - def mul( - self: Series[bool], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series[T_COMPLEX]: ... - @overload - def mul( - self: Series[bool], - other: np_ndarray_bool, - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series[bool]: ... - @overload - def mul( - self: Series[bool], - other: np_ndarray_anyint, - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series[int]: ... - @overload - def mul( - self: Series[bool], - other: np_ndarray_float, - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series[float]: ... - @overload - def mul( + def floordiv( self: Series[int], other: ( - bool | Sequence[bool] | np_ndarray_bool | np_ndarray_anyint | Series[bool] + Just[int] + | Sequence[Just[int]] + | np_ndarray_anyint + | Index[int] + | Series[int] ), - level: Level | None = None, + level: Level | None = ..., fill_value: float | None = None, - axis: int = 0, + axis: AxisIndex | None = 0, ) -> Series[int]: ... @overload - def mul( - self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> Series[T_COMPLEX]: ... - @overload - def mul( + def floordiv( self: Series[int], - other: np_ndarray_float, - level: Level | None = None, + other: ( + Just[float] + | Sequence[Just[float]] + | np_ndarray_float + | Index[float] + | Series[float] + ), + level: Level | None = ..., fill_value: float | None = None, - axis: int = 0, + axis: AxisIndex | None = 0, ) -> Series[float]: ... @overload - def mul( + def floordiv( self: Series[float], other: ( - int - | Sequence[int] - | np_ndarray_bool + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] | np_ndarray_anyint | np_ndarray_float - | Series[T_INT] + | Index[int] + | Index[float] + | Series[int] + | Series[float] ), - level: Level | None = None, + level: Level | None = ..., fill_value: float | None = None, - axis: int = 0, + axis: AxisIndex | None = 0, + ) -> Series[float]: ... + @overload + def floordiv( + self: Series[Timedelta], + other: ( + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] + | np_ndarray_anyint + | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex | None = 0, + ) -> Series[Timedelta]: ... + @overload + def floordiv( + self: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex | None = 0, + ) -> Series[int]: ... + @overload + def __rfloordiv__(self, other: Index[Never] | Series[Never]) -> Series: ... + @overload + def __rfloordiv__( + self: Series[int] | Series[float], + other: np_ndarray_bool | np_ndarray_complex | np_ndarray_dt | np_ndarray_td, + ) -> Never: ... + @overload + def __rfloordiv__( + self: Series[bool] | Series[complex], other: np_ndarray + ) -> Never: ... + @overload + def __rfloordiv__( + self: Series[int], + other: ( + Just[int] + | Sequence[Just[int]] + | np_ndarray_anyint + | Index[int] + | Series[int] + ), + ) -> Series[int]: ... + @overload + def __rfloordiv__( + self: Series[int], + other: ( + Just[float] + | Sequence[Just[float]] + | np_ndarray_float + | Index[float] + | Series[float] + ), + ) -> Series[float]: ... + @overload + def __rfloordiv__( + self: Series[float], + other: ( + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] + | np_ndarray_anyint + | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] + ), + ) -> Series[float]: ... + @overload + def __rfloordiv__( + self: Series[Timedelta], + other: ( + np_ndarray_bool + | np_ndarray_anyint + | np_ndarray_float + | np_ndarray_complex + | np_ndarray_dt + ), + ) -> Never: ... + @overload + def __rfloordiv__( + self: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + ) -> Series[int]: ... + @overload + def rfloordiv( + self, + other: Index[Never] | Series[Never], + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex | None = 0, + ) -> Series: ... + @overload + def rfloordiv( + self: Series[int], + other: ( + Just[int] + | Sequence[Just[int]] + | np_ndarray_anyint + | Index[int] + | Series[int] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex = ..., + ) -> Series[int]: ... + @overload + def rfloordiv( + self: Series[int], + other: ( + Just[float] + | Sequence[Just[float]] + | np_ndarray_float + | Index[float] + | Series[float] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex = ..., + ) -> Series[float]: ... + @overload + def rfloordiv( + self: Series[float], + other: ( + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] + | np_ndarray_anyint + | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex = ..., + ) -> Series[float]: ... + @overload + def rfloordiv( + self: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + level: Level | None = ..., + fill_value: float | None = None, + axis: AxisIndex = ..., + ) -> Series[int]: ... + def __ge__( # type: ignore[override] + self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date + ) -> Series[_bool]: ... + def __gt__( # type: ignore[override] + self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date + ) -> Series[_bool]: ... + def __le__( # type: ignore[override] + self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date + ) -> Series[_bool]: ... + def __lt__( # type: ignore[override] + self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date + ) -> Series[_bool]: ... + @overload + def __mul__( # type: ignore[overload-overlap] + self: Series[Never], other: complex | NumListLike | Index | Series + ) -> Series: ... + @overload + def __mul__(self, other: Index[Never] | Series[Never]) -> Series: ... + @overload + def __mul__( + self: Series[bool], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], + ) -> Series[T_COMPLEX]: ... + @overload + def __mul__(self: Series[bool], other: np_ndarray_bool) -> Series[bool]: ... + @overload + def __mul__(self: Series[bool], other: np_ndarray_anyint) -> Series[int]: ... + @overload + def __mul__(self: Series[bool], other: np_ndarray_float) -> Series[float]: ... + @overload + def __mul__( + self: Series[int], + other: ( + bool + | Sequence[bool] + | np_ndarray_bool + | np_ndarray_anyint + | Index[bool] + | Series[bool] + ), + ) -> Series[int]: ... + @overload + def __mul__( + self: Series[int], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], + ) -> Series[T_COMPLEX]: ... + @overload + def __mul__(self: Series[int], other: np_ndarray_float) -> Series[float]: ... + @overload + def __mul__( + self: Series[float], + other: ( + int + | Sequence[int] + | np_ndarray_bool + | np_ndarray_anyint + | np_ndarray_float + | Index[T_INT] + | Series[T_INT] + ), + ) -> Series[float]: ... + @overload + def __mul__( + self: Series[float], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], + ) -> Series[T_COMPLEX]: ... + @overload + def __mul__( + self: Series[complex], + other: ( + T_COMPLEX + | Sequence[T_COMPLEX] + | np_ndarray_bool + | np_ndarray_anyint + | np_ndarray_float + | Index[T_COMPLEX] + | Series[T_COMPLEX] + ), + ) -> Series[complex]: ... + @overload + def __mul__( + self: Series[T_COMPLEX], other: np_ndarray_complex + ) -> Series[complex]: ... + @overload + def __mul__( + self: Series[bool] | Series[int] | Series[float], + other: ( + timedelta + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + ) -> Series[Timedelta]: ... + @overload + def __mul__(self: Series[Timedelta], other: np_ndarray_complex) -> Never: ... + @overload + def __mul__( + self: Series[Timedelta], + other: ( + float + | Sequence[float] + | np_ndarray_bool + | np_ndarray_anyint + | np_ndarray_float + | Index[bool] + | Index[int] + | Index[float] + | Series[bool] + | Series[int] + | Series[float] + ), + ) -> Series[Timedelta]: ... + @overload + def mul( + self: Series[Never], + other: complex | _ListLike | Index | Series, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series: ... + @overload + def mul( + self, + other: Index[Never] | Series[Never], + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series: ... + @overload + def mul( + self: Series[bool], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[T_COMPLEX]: ... + @overload + def mul( + self: Series[bool], + other: np_ndarray_bool, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[bool]: ... + @overload + def mul( + self: Series[bool], + other: np_ndarray_anyint, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[int]: ... + @overload + def mul( + self: Series[bool], + other: np_ndarray_float, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[float]: ... + @overload + def mul( + self: Series[int], + other: ( + bool + | Sequence[bool] + | np_ndarray_bool + | np_ndarray_anyint + | Index[bool] + | Series[bool] + ), + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[int]: ... + @overload + def mul( + self: Series[int], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[T_COMPLEX]: ... + @overload + def mul( + self: Series[int], + other: np_ndarray_float, + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, + ) -> Series[float]: ... + @overload + def mul( + self: Series[float], + other: ( + int + | Sequence[int] + | np_ndarray_bool + | np_ndarray_anyint + | np_ndarray_float + | Index[T_INT] + | Series[T_INT] + ), + level: Level | None = None, + fill_value: float | None = None, + axis: int = 0, ) -> Series[float]: ... @overload def mul( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2424,6 +2808,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), level: Level | None = None, @@ -2441,15 +2826,14 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def mul( self: Series[bool] | Series[int] | Series[float], - other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaSeries, - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex | None = 0, - ) -> TimedeltaSeries: ... - @overload - def mul( - self: Series[bool] | Series[int] | Series[float], - other: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), level: Level | None = ..., fill_value: float | None = None, axis: AxisIndex | None = 0, @@ -2463,29 +2847,27 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[bool] + | Index[int] + | Index[float] + | Series[bool] + | Series[int] + | Series[float] ), level: Level | None = ..., fill_value: float | None = None, axis: AxisIndex | None = 0, - ) -> TimedeltaSeries: ... - @overload - def mul( - self: Series[Timedelta], - other: Series[bool] | Series[int] | Series[float], - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex | None = 0, ) -> Series[Timedelta]: ... @overload def __rmul__( # type: ignore[overload-overlap] - self: Series[Never], other: complex | NumListLike | Series + self: Series[Never], other: complex | NumListLike | Index | Series ) -> Series: ... @overload - def __rmul__(self, other: Series[Never]) -> Series: ... # type: ignore[overload-overlap] + def __rmul__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload def __rmul__( self: Series[bool], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __rmul__(self: Series[bool], other: np_ndarray_bool) -> Series[bool]: ... @@ -2497,12 +2879,18 @@ class Series(IndexOpsMixin[S1], NDFrame): def __rmul__( self: Series[int], other: ( - bool | Sequence[bool] | np_ndarray_bool | np_ndarray_anyint | Series[bool] + bool + | Sequence[bool] + | np_ndarray_bool + | np_ndarray_anyint + | Index[bool] + | Series[bool] ), ) -> Series[int]: ... @overload def __rmul__( - self: Series[int], other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX] + self: Series[int], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __rmul__(self: Series[int], other: np_ndarray_float) -> Series[float]: ... @@ -2515,13 +2903,14 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), ) -> Series[float]: ... @overload def __rmul__( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __rmul__( @@ -2532,6 +2921,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), ) -> Series[complex]: ... @@ -2542,13 +2932,17 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def __rmul__( self: Series[bool] | Series[int] | Series[float], - other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaSeries, - ) -> TimedeltaSeries: ... - @overload - def __rmul__( - self: Series[bool] | Series[int] | Series[float], other: Series[Timedelta] + other: ( + timedelta + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), ) -> Series[Timedelta]: ... @overload + def __rmul__(self: Series[Timedelta], other: np_ndarray_complex) -> Never: ... + @overload def __rmul__( self: Series[Timedelta], other: ( @@ -2557,24 +2951,26 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[bool] + | Index[int] + | Index[float] + | Series[bool] + | Series[int] + | Series[float] ), - ) -> TimedeltaSeries: ... - @overload - def __rmul__( - self: Series[Timedelta], other: Series[bool] | Series[int] | Series[float] ) -> Series[Timedelta]: ... @overload def rmul( self: Series[Never], - other: complex | _ListLike | Series, + other: complex | _ListLike | Index | Series, level: Level | None = None, fill_value: float | None = None, axis: int = 0, ) -> Series: ... @overload - def rmul( # type: ignore[overload-overlap] + def rmul( self, - other: Series[Never], + other: Index[Never] | Series[Never], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2582,7 +2978,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rmul( self: Series[bool], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2615,7 +3011,12 @@ class Series(IndexOpsMixin[S1], NDFrame): def rmul( self: Series[int], other: ( - bool | Sequence[bool] | np_ndarray_bool | np_ndarray_anyint | Series[bool] + bool + | Sequence[bool] + | np_ndarray_bool + | np_ndarray_anyint + | Index[bool] + | Series[bool] ), level: Level | None = None, fill_value: float | None = None, @@ -2624,7 +3025,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rmul( self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2646,6 +3047,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), level: Level | None = None, @@ -2655,7 +3057,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rmul( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -2669,6 +3071,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), level: Level | None = None, @@ -2686,15 +3089,14 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rmul( self: Series[bool] | Series[int] | Series[float], - other: timedelta | np.timedelta64 | np_ndarray_td | TimedeltaSeries, - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex | None = 0, - ) -> TimedeltaSeries: ... - @overload - def rmul( - self: Series[bool] | Series[int] | Series[float], - other: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), level: Level | None = ..., fill_value: float | None = None, axis: AxisIndex | None = 0, @@ -2708,18 +3110,16 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[bool] + | Index[int] + | Index[float] + | Series[bool] + | Series[int] + | Series[float] ), level: Level | None = ..., fill_value: float | None = None, axis: AxisIndex | None = 0, - ) -> TimedeltaSeries: ... - @overload - def rmul( - self: Series[Timedelta], - other: Series[bool] | Series[int] | Series[float], - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex | None = 0, ) -> Series[Timedelta]: ... def __mod__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... def __ne__(self, other: object) -> Series[_bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] @@ -2739,7 +3139,6 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def __rand__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... def __rdivmod__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - def __rfloordiv__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... def __rmod__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... def __rpow__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... # ignore needed for mypy as we want different results based on the arguments @@ -2762,7 +3161,7 @@ class Series(IndexOpsMixin[S1], NDFrame): other: complex | NumListLike | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series: ... @overload - def __sub__(self, other: Index[Never] | Series[Never]) -> Series: ... # type: ignore[overload-overlap] + def __sub__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload def __sub__( self: Series[bool], @@ -2853,11 +3252,10 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series[complex]: ... @overload def __sub__( - self: Series[Timestamp], other: datetime | np.datetime64 | np_ndarray_dt - ) -> TimedeltaSeries: ... - @overload - def __sub__( - self: Series[Timestamp], other: Series[Timestamp] + self: Series[Timestamp], + other: ( + datetime | np.datetime64 | np_ndarray_dt | DatetimeIndex | Series[Timestamp] + ), ) -> Series[Timedelta]: ... @overload def __sub__( @@ -2867,11 +3265,13 @@ class Series(IndexOpsMixin[S1], NDFrame): | np.timedelta64 | np_ndarray_td | TimedeltaIndex - | TimedeltaSeries + | Series[Timedelta] | BaseOffset ), ) -> Series[Timestamp]: ... @overload + def __sub__(self: Series[Timedelta], other: np_ndarray_dt) -> Never: ... + @overload def __sub__( self: Series[Timedelta], other: ( @@ -2879,9 +3279,9 @@ class Series(IndexOpsMixin[S1], NDFrame): | np.timedelta64 | np_ndarray_td | TimedeltaIndex - | TimedeltaSeries + | Series[Timedelta] ), - ) -> TimedeltaSeries: ... + ) -> Series[Timedelta]: ... @overload def sub( self: Series[Never], @@ -2891,7 +3291,7 @@ class Series(IndexOpsMixin[S1], NDFrame): axis: int = 0, ) -> Series: ... @overload - def sub( # type: ignore[overload-overlap] + def sub( self, other: Index[Never] | Series[Never], level: Level | None = None, @@ -3010,15 +3410,14 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def sub( self: Series[Timestamp], - other: datetime | Sequence[datetime] | np.datetime64 | np_ndarray_dt, - level: Level | None = None, - fill_value: float | None = None, - axis: int = 0, - ) -> TimedeltaSeries: ... - @overload - def sub( - self: Series[Timestamp], - other: Series[Timestamp], + other: ( + datetime + | Sequence[datetime] + | np.datetime64 + | np_ndarray_dt + | DatetimeIndex + | Series[Timestamp] + ), level: Level | None = None, fill_value: float | None = None, axis: int = 0, @@ -3032,7 +3431,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np.timedelta64 | np_ndarray_td | TimedeltaIndex - | TimedeltaSeries + | Series[Timedelta] | BaseOffset ), level: Level | None = None, @@ -3044,17 +3443,18 @@ class Series(IndexOpsMixin[S1], NDFrame): self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex - | TimedeltaSeries + | Series[Timedelta] ), level: Level | None = None, fill_value: float | None = None, axis: int = 0, - ) -> TimedeltaSeries: ... + ) -> Series[Timedelta]: ... @overload - def __rsub__( # type: ignore[overload-overlap] + def __rsub__( self: Series[Never], other: ( complex @@ -3064,7 +3464,6 @@ class Series(IndexOpsMixin[S1], NDFrame): | NumListLike | Index[T_COMPLEX] | Series[T_COMPLEX] - | Series[Timestamp] ), ) -> Series: ... @overload @@ -3158,20 +3557,34 @@ class Series(IndexOpsMixin[S1], NDFrame): ), ) -> Series[complex]: ... @overload - def __rsub__( - self: Series[Timestamp], other: datetime | np.datetime64 | np_ndarray_dt - ) -> TimedeltaSeries: ... + def __rsub__(self: Series[Timestamp], other: np_ndarray_td) -> Never: ... @overload def __rsub__( - self: Series[Timestamp], other: Series[Timestamp] + self: Series[Timestamp], + other: ( + datetime | np.datetime64 | np_ndarray_dt | DatetimeIndex | Series[Timestamp] + ), ) -> Series[Timedelta]: ... @overload def __rsub__( self: Series[Timedelta], - other: datetime | np.datetime64 | np_ndarray_dt | Series[Timestamp], + other: ( + datetime | np.datetime64 | np_ndarray_dt | DatetimeIndex | Series[Timestamp] + ), ) -> Series[Timestamp]: ... @overload - def rsub( # type: ignore[overload-overlap] + def __rsub__( + self: Series[Timedelta], + other: ( + timedelta + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + ) -> Series[Timedelta]: ... + @overload + def rsub( self: Series[Never], other: ( complex @@ -3308,33 +3721,54 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rsub( self: Series[Timestamp], - other: datetime | Sequence[datetime] | np.datetime64 | np_ndarray_dt, + other: ( + datetime + | Sequence[datetime] + | np.datetime64 + | np_ndarray_dt + | DatetimeIndex + | Series[Timestamp] + ), level: Level | None = None, fill_value: float | None = None, axis: int = 0, - ) -> TimedeltaSeries: ... + ) -> Series[Timedelta]: ... @overload def rsub( - self: Series[Timestamp], - other: Series[Timestamp], + self: Series[Timedelta], + other: ( + datetime + | Sequence[datetime] + | np.datetime64 + | np_ndarray_dt + | DatetimeIndex + | Series[Timestamp] + ), level: Level | None = None, fill_value: float | None = None, axis: int = 0, - ) -> Series[Timedelta]: ... + ) -> Series[Timestamp]: ... @overload def rsub( self: Series[Timedelta], - other: datetime | np.datetime64 | np_ndarray_dt | Series[Timestamp], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), level: Level | None = None, fill_value: float | None = None, axis: int = 0, - ) -> Series[Timestamp]: ... + ) -> Series[Timedelta]: ... @overload - def __truediv__( # type:ignore[overload-overlap] - self: Series[Never], other: complex | NumListLike | Series + def __truediv__( # type: ignore[overload-overlap] + self: Series[Never], other: complex | NumListLike | Index | Series ) -> Series: ... @overload - def __truediv__(self, other: Series[Never]) -> Series: ... + def __truediv__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload def __truediv__(self: Series[bool], other: np_ndarray_bool) -> Never: ... @overload @@ -3346,6 +3780,8 @@ class Series(IndexOpsMixin[S1], NDFrame): | Sequence[float] | np_ndarray_anyint | np_ndarray_float + | Index[int] + | Index[float] | Series[int] | Series[float] ), @@ -3353,7 +3789,9 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def __truediv__( self: Series[bool], - other: Just[complex] | Sequence[Just[complex]] | Series[complex], + other: ( + Just[complex] | Sequence[Just[complex]] | Index[complex] | Series[complex] + ), ) -> Series[complex]: ... @overload def __truediv__( @@ -3364,13 +3802,14 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), ) -> Series[float]: ... @overload def __truediv__( self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __truediv__( @@ -3381,13 +3820,14 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), ) -> Series[float]: ... @overload def __truediv__( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __truediv__( @@ -3398,6 +3838,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), ) -> Series[complex]: ... @@ -3407,19 +3848,35 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series[complex]: ... @overload def __truediv__( - self: Series[Timestamp], - other: float | Sequence[float] | Series[int] | Series[float], - ) -> Series[Timestamp]: ... + self: Series[Timedelta], + other: ( + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] + | np_ndarray_anyint + | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] + ), + ) -> Series[Timedelta]: ... + @overload + def __truediv__( + self: Series[Timedelta], + other: np_ndarray_bool | np_ndarray_complex | np_ndarray_dt, + ) -> Never: ... @overload def __truediv__( self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries ), ) -> Series[float]: ... @overload @@ -3427,7 +3884,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def truediv( self: Series[Never], - other: complex | _ListLike | Series, + other: complex | _ListLike | Index | Series, level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3435,7 +3892,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def truediv( self, - other: Series[Never], + other: Index[Never] | Series[Never], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3449,6 +3906,8 @@ class Series(IndexOpsMixin[S1], NDFrame): | Sequence[float] | np_ndarray_anyint | np_ndarray_float + | Index[int] + | Index[float] | Series[int] | Series[float] ), @@ -3459,7 +3918,9 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def truediv( self: Series[bool], - other: Just[complex] | Sequence[Just[complex]] | Series[complex], + other: ( + Just[complex] | Sequence[Just[complex]] | Index[complex] | Series[complex] + ), level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3473,6 +3934,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), level: Level | None = None, @@ -3482,7 +3944,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def truediv( self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3496,6 +3958,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), level: Level | None = None, @@ -3505,7 +3968,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def truediv( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3519,6 +3982,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), level: Level | None = None, @@ -3535,27 +3999,38 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series[complex]: ... @overload def truediv( - self: Series[Timestamp], - other: float | Sequence[float] | Series[int] | Series[float], + self: Series[Timedelta], + other: ( + Just[int] + | Just[float] + | Sequence[Just[int]] + | Sequence[Just[float]] + | np_ndarray_anyint + | np_ndarray_float + | Index[int] + | Index[float] + | Series[int] + | Series[float] + ), level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, - ) -> Series[Timestamp]: ... + ) -> Series[Timedelta]: ... @overload def truediv( self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries ), level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, - ) -> Series[Timedelta]: ... + ) -> Series[float]: ... @overload def truediv( self, @@ -3566,11 +4041,11 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series: ... div = truediv @overload - def __rtruediv__( # type:ignore[overload-overlap] - self: Series[Never], other: complex | NumListLike | Series + def __rtruediv__( # type: ignore[overload-overlap] + self: Series[Never], other: complex | NumListLike | Index | Series ) -> Series: ... @overload - def __rtruediv__(self, other: Series[Never]) -> Series: ... + def __rtruediv__(self, other: Index[Never] | Series[Never]) -> Series: ... @overload def __rtruediv__(self: Series[bool], other: np_ndarray_bool) -> Never: ... @overload @@ -3582,6 +4057,8 @@ class Series(IndexOpsMixin[S1], NDFrame): | Sequence[float] | np_ndarray_anyint | np_ndarray_float + | Index[int] + | Index[float] | Series[int] | Series[float] ), @@ -3589,7 +4066,9 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def __rtruediv__( self: Series[bool], - other: Just[complex] | Sequence[Just[complex]] | Series[complex], + other: ( + Just[complex] | Sequence[Just[complex]] | Index[complex] | Series[complex] + ), ) -> Series[complex]: ... @overload def __rtruediv__( @@ -3600,12 +4079,14 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), ) -> Series[float]: ... @overload def __rtruediv__( - self: Series[int], other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX] + self: Series[int], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __rtruediv__( @@ -3616,13 +4097,14 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), ) -> Series[float]: ... @overload def __rtruediv__( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], ) -> Series[T_COMPLEX]: ... @overload def __rtruediv__( @@ -3633,6 +4115,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), ) -> Series[complex]: ... @@ -3641,15 +4124,22 @@ class Series(IndexOpsMixin[S1], NDFrame): self: Series[T_COMPLEX], other: np_ndarray_complex ) -> Series[complex]: ... @overload + def __rtruediv__( + self: Series[Timedelta], + other: ( + np_ndarray_bool | np_ndarray_anyint | np_ndarray_float | np_ndarray_complex + ), + ) -> Never: ... + @overload def __rtruediv__( self: Series[Timedelta], other: ( timedelta + | Sequence[timedelta] | np.timedelta64 | np_ndarray_td | TimedeltaIndex | Series[Timedelta] - | TimedeltaSeries ), ) -> Series[float]: ... @overload @@ -3657,7 +4147,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rtruediv( self: Series[Never], - other: complex | _ListLike | Series, + other: complex | _ListLike | Index | Series, level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3665,7 +4155,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rtruediv( self, - other: Series[Never], + other: Index[Never] | Series[Never], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3679,6 +4169,8 @@ class Series(IndexOpsMixin[S1], NDFrame): | Sequence[float] | np_ndarray_anyint | np_ndarray_float + | Index[int] + | Index[float] | Series[int] | Series[float] ), @@ -3689,7 +4181,9 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rtruediv( self: Series[bool], - other: Just[complex] | Sequence[Just[complex]] | Series[complex], + other: ( + Just[complex] | Sequence[Just[complex]] | Index[complex] | Series[complex] + ), level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3703,6 +4197,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), level: Level | None = None, @@ -3712,7 +4207,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rtruediv( self: Series[int], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3726,6 +4221,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_INT] | Series[T_INT] ), level: Level | None = None, @@ -3735,7 +4231,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rtruediv( self: Series[float], - other: T_COMPLEX | Sequence[T_COMPLEX] | Series[T_COMPLEX], + other: T_COMPLEX | Sequence[T_COMPLEX] | Index[T_COMPLEX] | Series[T_COMPLEX], level: Level | None = None, fill_value: float | None = None, axis: AxisIndex = 0, @@ -3749,6 +4245,7 @@ class Series(IndexOpsMixin[S1], NDFrame): | np_ndarray_bool | np_ndarray_anyint | np_ndarray_float + | Index[T_COMPLEX] | Series[T_COMPLEX] ), level: Level | None = None, @@ -3764,6 +4261,21 @@ class Series(IndexOpsMixin[S1], NDFrame): axis: AxisIndex = 0, ) -> Series[complex]: ... @overload + def rtruediv( + self: Series[Timedelta], + other: ( + timedelta + | Sequence[timedelta] + | np.timedelta64 + | np_ndarray_td + | TimedeltaIndex + | Series[Timedelta] + ), + level: Level | None = None, + fill_value: float | None = None, + axis: AxisIndex = 0, + ) -> Series[float]: ... + @overload def rtruediv( self, other: Path, @@ -3889,13 +4401,6 @@ class Series(IndexOpsMixin[S1], NDFrame): axis: Literal[0] = 0, method: CalculationMethod = "single", ) -> Expanding[Series]: ... - def floordiv( - self, - other: num | _ListLike | Series[S1], - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex | None = 0, - ) -> Series[int]: ... def ge( self, other: Scalar | Series[S1], @@ -3968,13 +4473,13 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Timestamp: ... @overload def mean( - self, + self: SupportsGetItem[Scalar, SupportsTruedivInt[S2]], axis: AxisIndex | None = 0, skipna: _bool = True, level: None = ..., numeric_only: _bool = False, **kwargs: Any, - ) -> float: ... + ) -> S2: ... @overload def median( self: Series[Never], @@ -3986,22 +4491,31 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> float: ... @overload def median( - self: Series[Timestamp], + self: Series[complex], axis: AxisIndex | None = 0, skipna: _bool = True, level: None = ..., numeric_only: _bool = False, **kwargs: Any, - ) -> Timestamp: ... + ) -> float: ... @overload def median( - self, + self: SupportsGetItem[Scalar, SupportsTruedivInt[S2]], axis: AxisIndex | None = 0, skipna: _bool = True, level: None = ..., numeric_only: _bool = False, **kwargs: Any, - ) -> float: ... + ) -> S2: ... + @overload + def median( + self: Series[Timestamp], + axis: AxisIndex | None = 0, + skipna: _bool = True, + level: None = ..., + numeric_only: _bool = False, + **kwargs: Any, + ) -> Timestamp: ... def min( self, axis: AxisIndex | None = 0, @@ -4056,13 +4570,6 @@ class Series(IndexOpsMixin[S1], NDFrame): fill_value: float | None = None, axis: AxisIndex = ..., ) -> Series[S1]: ... - def rfloordiv( - self, - other, - level: Level | None = ..., - fill_value: float | None = None, - axis: AxisIndex = ..., - ) -> Series[S1]: ... def rmod( self, other: Series[S1] | Scalar, @@ -4119,6 +4626,25 @@ class Series(IndexOpsMixin[S1], NDFrame): **kwargs: Any, ) -> Scalar: ... @overload + def std( + self: Series[Never], + axis: AxisIndex | None = 0, + skipna: _bool | None = True, + ddof: int = 1, + numeric_only: _bool = False, + **kwargs: Any, + ) -> float: ... + @overload + def std( + self: Series[complex], + axis: AxisIndex | None = 0, + skipna: _bool | None = True, + level: None = ..., + ddof: int = ..., + numeric_only: _bool = False, + **kwargs: Any, + ) -> np.float64: ... + @overload def std( self: Series[Timestamp], axis: AxisIndex | None = 0, @@ -4130,13 +4656,13 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Timedelta: ... @overload def std( - self, + self: SupportsGetItem[Scalar, SupportsTruedivInt[S2]], axis: AxisIndex | None = 0, skipna: _bool | None = True, ddof: int = 1, numeric_only: _bool = False, **kwargs: Any, - ) -> float: ... + ) -> S2: ... def sum( self: SupportsGetItem[Scalar, _SupportsAdd[_T]], axis: AxisIndex | None = 0, @@ -4149,7 +4675,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload # type: ignore[override] def to_numpy( # pyrefly: ignore[bad-override] self: Series[Timestamp], - dtype: None = None, + dtype: None | type[np.datetime64] = None, copy: bool = False, na_value: Scalar = ..., **kwargs, @@ -4163,7 +4689,23 @@ class Series(IndexOpsMixin[S1], NDFrame): **kwargs, ) -> np_1darray[GenericT]: ... @overload + def to_numpy( # pyrefly: ignore[bad-override] + self: Series[Timedelta], + dtype: None | type[np.timedelta64] = None, + copy: bool = False, + na_value: Scalar = ..., + **kwargs, + ) -> np_1darray[np.timedelta64]: ... + @overload def to_numpy( + self: Series[Timedelta], + dtype: np.dtype[GenericT] | SupportsDType[GenericT] | type[GenericT], + copy: bool = False, + na_value: Scalar = ..., + **kwargs, + ) -> np_1darray[GenericT]: ... + @overload + def to_numpy( # pyright: ignore[reportIncompatibleMethodOverride] self, dtype: DTypeLike | None = None, copy: bool = False, @@ -4257,123 +4799,6 @@ class _SeriesSubclassBase(Series[S1], Generic[S1, GenericT_co]): **kwargs, ) -> np_1darray: ... -class TimedeltaSeries(_SeriesSubclassBase[Timedelta, np.timedelta64]): - # ignores needed because of mypy - @overload # type: ignore[override] - def __add__(self, other: Period) -> PeriodSeries: ... - @overload - def __add__( - self, other: datetime | Timestamp | DatetimeIndex | Series[Timestamp] - ) -> Series[Timestamp]: ... - @overload - def __add__(self, other: timedelta | np.timedelta64) -> TimedeltaSeries: ... - def __radd__(self, other: datetime | Series[Timestamp]) -> Series[Timestamp]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - def __mul__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, other: num | Sequence[num] | Series[int] | Series[float] - ) -> TimedeltaSeries: ... - def unique(self) -> TimedeltaArray: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - def __sub__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, - other: timedelta | TimedeltaSeries | TimedeltaIndex | np.timedelta64, - ) -> TimedeltaSeries: ... - @overload # type: ignore[override] - def __truediv__(self, other: float | Sequence[float]) -> Self: ... - @overload - def __truediv__( # pyright: ignore[reportIncompatibleMethodOverride] - self, - other: ( - timedelta - | TimedeltaSeries - | np.timedelta64 - | TimedeltaIndex - | Sequence[timedelta] - ), - ) -> Series[float]: ... - @overload # type: ignore[override] - def __rtruediv__( - self, - other: ( - timedelta - | np.timedelta64 - | Sequence[timedelta] - | np_ndarray_td - | TimedeltaSeries - | TimedeltaIndex - ), - ) -> Series[float]: ... - @overload - def __rtruediv__( # pyright: ignore[reportIncompatibleMethodOverride] - self: Series[Timedelta], - other: ( - timedelta - | np.timedelta64 - | Series[Timedelta] - | np_ndarray_td - | TimedeltaSeries - | TimedeltaIndex - ), - ) -> Series[float]: ... - @overload # type: ignore[override] - def __floordiv__(self, other: float | Sequence[float]) -> Self: ... - @overload - def __floordiv__( # pyright: ignore[reportIncompatibleMethodOverride] - self, - other: ( - timedelta - | np.timedelta64 - | TimedeltaSeries - | TimedeltaIndex - | Sequence[timedelta] - ), - ) -> Series[int]: ... - def __rfloordiv__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, - other: ( - timedelta - | np.timedelta64 - | TimedeltaSeries - | TimedeltaIndex - | Sequence[timedelta] - ), - ) -> Series[int]: ... - @property - def dt( # pyright: ignore[reportIncompatibleMethodOverride] # pyrefly: ignore - self, - ) -> TimedeltaProperties: ... - def mean( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, - axis: AxisIndex | None = 0, - skipna: _bool = ..., - level: None = ..., - numeric_only: _bool = ..., - **kwargs: Any, - ) -> Timedelta: ... - def median( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, - axis: AxisIndex | None = 0, - skipna: _bool = ..., - level: None = ..., - numeric_only: _bool = ..., - **kwargs: Any, - ) -> Timedelta: ... - def std( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - self, - axis: AxisIndex | None = 0, - skipna: _bool | None = ..., - level: None = ..., - ddof: int = ..., - numeric_only: _bool = ..., - **kwargs: Any, - ) -> Timedelta: ... - def diff(self, periods: int = ...) -> TimedeltaSeries: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] - def cumsum( - self, - axis: AxisIndex | None = 0, - skipna: _bool = ..., - *args: Any, - **kwargs: Any, - ) -> TimedeltaSeries: ... - class PeriodSeries(_SeriesSubclassBase[Period, np.object_]): @property def dt(self) -> PeriodProperties: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] @@ -4384,7 +4809,9 @@ class OffsetSeries(_SeriesSubclassBase[BaseOffset, np.object_]): @overload # type: ignore[override] def __radd__(self, other: Period) -> PeriodSeries: ... @overload - def __radd__(self, other: BaseOffset) -> OffsetSeries: ... + def __radd__( # pyright: ignore[reportIncompatibleMethodOverride] + self, other: BaseOffset + ) -> OffsetSeries: ... class IntervalSeries( _SeriesSubclassBase[Interval[_OrderableT], np.object_], Generic[_OrderableT] diff --git a/pandas-stubs/core/tools/timedeltas.pyi b/pandas-stubs/core/tools/timedeltas.pyi index 38ed0c074..3057ce808 100644 --- a/pandas-stubs/core/tools/timedeltas.pyi +++ b/pandas-stubs/core/tools/timedeltas.pyi @@ -4,10 +4,7 @@ from typing import overload from pandas import Index from pandas.core.indexes.timedeltas import TimedeltaIndex -from pandas.core.series import ( - Series, - TimedeltaSeries, -) +from pandas.core.series import Series from pandas._libs.tslibs import Timedelta from pandas._libs.tslibs.timedeltas import TimeDeltaUnitChoices @@ -28,7 +25,7 @@ def to_timedelta( arg: Series, unit: TimeDeltaUnitChoices | None = ..., errors: RaiseCoerce = ..., -) -> TimedeltaSeries: ... +) -> Series[Timedelta]: ... @overload def to_timedelta( arg: ( diff --git a/pyproject.toml b/pyproject.toml index 47c13a987..889de3a4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,13 +36,13 @@ types-pytz = ">= 2022.1.1" numpy = ">= 1.23.5" [tool.poetry.group.dev.dependencies] -mypy = "1.18.1" +mypy = "1.18.2" pandas = "2.3.2" pyarrow = ">=10.0.1" pytest = ">=7.1.2" pyright = ">=1.1.405" -ty = ">=0.0.1a20" -pyrefly = ">=0.33.0" +ty = ">=0.0.1a21" +pyrefly = ">=0.33.1" poethepoet = ">=0.16.5" loguru = ">=0.6.0" typing-extensions = ">=4.4.0" diff --git a/tests/indexes/arithmetic/bool/test_add.py b/tests/indexes/arithmetic/bool/test_add.py index 8389ad367..b80a25b1d 100644 --- a/tests/indexes/arithmetic/bool/test_add.py +++ b/tests/indexes/arithmetic/bool/test_add.py @@ -13,7 +13,6 @@ def test_add_py_scalar() -> None: """Test pd.Index[bool] + Python native scalars""" b, i, f, c = True, 1, 1.0, 1j - left.__add__(b) check(assert_type(left + b, "pd.Index[bool]"), pd.Index, np.bool_) check(assert_type(left + i, "pd.Index[int]"), pd.Index, np.integer) check(assert_type(left + f, "pd.Index[float]"), pd.Index, np.floating) @@ -26,7 +25,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Index[bool] + Python native sequence""" + """Test pd.Index[bool] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Index[bool]"), pd.Index, np.bool_) @@ -41,7 +40,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Index[bool] + numpy array""" + """Test pd.Index[bool] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -66,7 +65,7 @@ def test_add_numpy_array() -> None: def test_add_pd_index() -> None: - """Test pd.Index[bool] + pandas index""" + """Test pd.Index[bool] + pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/bool/test_sub.py b/tests/indexes/arithmetic/bool/test_sub.py index c36d0916a..faac659dd 100644 --- a/tests/indexes/arithmetic/bool/test_sub.py +++ b/tests/indexes/arithmetic/bool/test_sub.py @@ -32,7 +32,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Index[bool] - Python native sequence""" + """Test pd.Index[bool] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] if TYPE_CHECKING_INVALID_USAGE: @@ -49,7 +49,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Index[bool] - numpy array""" + """Test pd.Index[bool] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -76,7 +76,7 @@ def test_sub_numpy_array() -> None: def test_sub_pd_index() -> None: - """Test pd.Index[bool] - pandas index""" + """Test pd.Index[bool] - pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/complex/test_add.py b/tests/indexes/arithmetic/complex/test_add.py index 0d9662dc2..bf3f6a4c2 100644 --- a/tests/indexes/arithmetic/complex/test_add.py +++ b/tests/indexes/arithmetic/complex/test_add.py @@ -25,7 +25,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Index[complex] + Python native sequence""" + """Test pd.Index[complex] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Index[complex]"), pd.Index, np.complexfloating) @@ -40,7 +40,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Index[complex] + numpy array""" + """Test pd.Index[complex] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -67,7 +67,7 @@ def test_add_numpy_array() -> None: def test_add_pd_index() -> None: - """Test pd.Index[complex] + pandas index""" + """Test pd.Index[complex] + pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/complex/test_sub.py b/tests/indexes/arithmetic/complex/test_sub.py index a31a2cc88..8df2892d1 100644 --- a/tests/indexes/arithmetic/complex/test_sub.py +++ b/tests/indexes/arithmetic/complex/test_sub.py @@ -27,7 +27,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Index[complex] - Python native sequence""" + """Test pd.Index[complex] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Index[complex]"), pd.Index, np.complexfloating) @@ -42,7 +42,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Index[complex] - numpy array""" + """Test pd.Index[complex] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -69,7 +69,7 @@ def test_sub_numpy_array() -> None: def test_sub_pd_index() -> None: - """Test pd.Index[complex] - pandas index""" + """Test pd.Index[complex] - pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/float/test_add.py b/tests/indexes/arithmetic/float/test_add.py index b882fd6fe..ce5a84f1f 100644 --- a/tests/indexes/arithmetic/float/test_add.py +++ b/tests/indexes/arithmetic/float/test_add.py @@ -25,7 +25,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Index[float] + Python native sequence""" + """Test pd.Index[float] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Index[float]"), pd.Index, np.floating) @@ -40,7 +40,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Index[float] + numpy array""" + """Test pd.Index[float] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -65,7 +65,7 @@ def test_add_numpy_array() -> None: def test_add_pd_index() -> None: - """Test pd.Index[float] + pandas index""" + """Test pd.Index[float] + pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/float/test_sub.py b/tests/indexes/arithmetic/float/test_sub.py index 8c589df3c..c35a7a5a6 100644 --- a/tests/indexes/arithmetic/float/test_sub.py +++ b/tests/indexes/arithmetic/float/test_sub.py @@ -27,7 +27,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Index[float] - Python native sequence""" + """Test pd.Index[float] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Index[float]"), pd.Index, np.floating) @@ -42,7 +42,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Index[float] - numpy array""" + """Test pd.Index[float] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -67,7 +67,7 @@ def test_sub_numpy_array() -> None: def test_sub_pd_index() -> None: - """Test pd.Index[float] - pandas index""" + """Test pd.Index[float] - pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/int/test_add.py b/tests/indexes/arithmetic/int/test_add.py index 126898b46..2d3cc7c1d 100644 --- a/tests/indexes/arithmetic/int/test_add.py +++ b/tests/indexes/arithmetic/int/test_add.py @@ -25,7 +25,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Index[int] + Python native sequence""" + """Test pd.Index[int] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Index[int]"), pd.Index, np.integer) @@ -40,7 +40,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Index[int] + numpy array""" + """Test pd.Index[int] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -65,7 +65,7 @@ def test_add_numpy_array() -> None: def test_add_pd_index() -> None: - """Test pd.Index[int] + pandas index""" + """Test pd.Index[int] + pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/int/test_sub.py b/tests/indexes/arithmetic/int/test_sub.py index edea4de21..dfc151b2e 100644 --- a/tests/indexes/arithmetic/int/test_sub.py +++ b/tests/indexes/arithmetic/int/test_sub.py @@ -27,7 +27,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Index[int] - Python native sequence""" + """Test pd.Index[int] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Index[int]"), pd.Index, np.integer) @@ -42,7 +42,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Index[int] - numpy array""" + """Test pd.Index[int] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -67,7 +67,7 @@ def test_sub_numpy_array() -> None: def test_sub_pd_index() -> None: - """Test pd.Index[int] - pandas index""" + """Test pd.Index[int] - pandas Indexes""" b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) f = pd.Index([1.0, 2.0, 3.0]) diff --git a/tests/indexes/arithmetic/str/test_add.py b/tests/indexes/arithmetic/str/test_add.py index d985a2c93..d4783f98f 100644 --- a/tests/indexes/arithmetic/str/test_add.py +++ b/tests/indexes/arithmetic/str/test_add.py @@ -32,7 +32,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Index[str] + Python native sequence""" + """Test pd.Index[str] + Python native sequences""" i = [3, 5, 8] r0 = ["a", "bc", "def"] r1 = tuple(r0) @@ -49,7 +49,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Index[str] + numpy array""" + """Test pd.Index[str] + numpy arrays""" i = np.array([3, 5, 8], np.int64) r0 = np.array(["a", "bc", "def"], np.str_) @@ -75,7 +75,7 @@ def test_add_numpy_array() -> None: def test_add_pd_index() -> None: - """Test pd.Index[str] + pandas index""" + """Test pd.Index[str] + pandas Indexes""" i = pd.Index([3, 5, 8]) r0 = pd.Index(["a", "bc", "def"]) diff --git a/tests/indexes/arithmetic/test_add.py b/tests/indexes/arithmetic/test_add.py index b4f2194af..c7c415b46 100644 --- a/tests/indexes/arithmetic/test_add.py +++ b/tests/indexes/arithmetic/test_add.py @@ -33,7 +33,7 @@ def test_add_i_py_scalar() -> None: def test_add_i_py_sequence() -> None: - """Test pd.Index[Any] (int) + Python native sequence""" + """Test pd.Index[Any] (int) + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left_i + b, pd.Index), pd.Index) @@ -48,7 +48,7 @@ def test_add_i_py_sequence() -> None: def test_add_i_numpy_array() -> None: - """Test pd.Index[Any] (int) + numpy array""" + """Test pd.Index[Any] (int) + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -82,7 +82,7 @@ def test_add_i_numpy_array() -> None: def test_add_i_pd_index() -> None: - """Test pd.Index[Any] (int) + pandas index""" + """Test pd.Index[Any] (int) + pandas Indexes""" a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) diff --git a/tests/indexes/arithmetic/test_sub.py b/tests/indexes/arithmetic/test_sub.py index 0a6217006..98ee8b8b5 100644 --- a/tests/indexes/arithmetic/test_sub.py +++ b/tests/indexes/arithmetic/test_sub.py @@ -29,7 +29,7 @@ def test_sub_i_py_scalar() -> None: def test_sub_i_py_sequence() -> None: - """Test pd.Index[Any] (int) - Python native sequence""" + """Test pd.Index[Any] (int) - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left_i - b, pd.Index), pd.Index) @@ -44,7 +44,7 @@ def test_sub_i_py_sequence() -> None: def test_sub_i_numpy_array() -> None: - """Test pd.Index[Any] (int) - numpy array""" + """Test pd.Index[Any] (int) - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -78,7 +78,7 @@ def test_sub_i_numpy_array() -> None: def test_sub_i_pd_index() -> None: - """Test pd.Index[Any] (int) - pandas index""" + """Test pd.Index[Any] (int) - pandas Indexes""" a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] b = pd.Index([True, False, True]) i = pd.Index([2, 3, 5]) diff --git a/tests/series/arithmetic/bool/test_add.py b/tests/series/arithmetic/bool/test_add.py index 81c2bf13a..cd3959d08 100644 --- a/tests/series/arithmetic/bool/test_add.py +++ b/tests/series/arithmetic/bool/test_add.py @@ -36,7 +36,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[bool] + Python native sequence""" + """Test pd.Series[bool] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Series[bool]"), pd.Series, np.bool_) @@ -63,7 +63,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Series[bool] + numpy array""" + """Test pd.Series[bool] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,12 +99,12 @@ def test_add_numpy_array() -> None: ) -def test_add_pd_series() -> None: - """Test pd.Series[bool] + pandas series""" - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_add_pd_index() -> None: + """Test pd.Series[bool] + pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[bool]"), pd.Series, np.bool_) check(assert_type(left + i, "pd.Series[int]"), pd.Series, np.integer) @@ -129,12 +129,12 @@ def test_add_pd_series() -> None: ) -def test_add_pd_index() -> None: - """Test pd.Series[bool] + pandas index""" - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_add_pd_series() -> None: + """Test pd.Series[bool] + pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[bool]"), pd.Series, np.bool_) check(assert_type(left + i, "pd.Series[int]"), pd.Series, np.integer) diff --git a/tests/series/arithmetic/bool/test_mul.py b/tests/series/arithmetic/bool/test_mul.py index 9b3c96ee1..c7e76e917 100644 --- a/tests/series/arithmetic/bool/test_mul.py +++ b/tests/series/arithmetic/bool/test_mul.py @@ -36,7 +36,7 @@ def test_mul_py_scalar() -> None: def test_mul_py_sequence() -> None: - """Test pd.Series[bool] * Python native sequence""" + """Test pd.Series[bool] * Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left * b, "pd.Series[bool]"), pd.Series, np.bool_) @@ -63,7 +63,7 @@ def test_mul_py_sequence() -> None: def test_mul_numpy_array() -> None: - """Test pd.Series[bool] * numpy array""" + """Test pd.Series[bool] * numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,8 +99,38 @@ def test_mul_numpy_array() -> None: ) +def test_mul_pd_index() -> None: + """Test pd.Series[bool] * pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left * b, "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(left * i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left * f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left * c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b * left, "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(i * left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f * left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.mul(b), "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(left.mul(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.mul(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.mul(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rmul(b), "pd.Series[bool]"), pd.Series, np.bool_) + check(assert_type(left.rmul(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rmul(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rmul(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_mul_pd_series() -> None: - """Test pd.Series[bool] * pandas series""" + """Test pd.Series[bool] * pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/bool/test_sub.py b/tests/series/arithmetic/bool/test_sub.py index c5f0e1ec0..6517e253f 100644 --- a/tests/series/arithmetic/bool/test_sub.py +++ b/tests/series/arithmetic/bool/test_sub.py @@ -46,7 +46,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Series[bool] - Python native sequence""" + """Test pd.Series[bool] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] if TYPE_CHECKING_INVALID_USAGE: @@ -77,7 +77,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Series[bool] - numpy array""" + """Test pd.Series[bool] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -117,12 +117,12 @@ def test_sub_numpy_array() -> None: ) -def test_sub_pd_series() -> None: - """Test pd.Series[bool] - pandas series""" - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_sub_pd_index() -> None: + """Test pd.Series[bool] - pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) if TYPE_CHECKING_INVALID_USAGE: _0 = left - b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] @@ -151,12 +151,12 @@ def test_sub_pd_series() -> None: ) -def test_sub_pd_index() -> None: - """Test pd.Series[bool] - pandas index""" - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_sub_pd_series() -> None: + """Test pd.Series[bool] - pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) if TYPE_CHECKING_INVALID_USAGE: _0 = left - b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] diff --git a/tests/series/arithmetic/bool/test_truediv.py b/tests/series/arithmetic/bool/test_truediv.py index 1bcc8008e..41c0e1a52 100644 --- a/tests/series/arithmetic/bool/test_truediv.py +++ b/tests/series/arithmetic/bool/test_truediv.py @@ -66,7 +66,7 @@ def test_truediv_py_scalar() -> None: def test_truediv_py_sequence() -> None: - """Test pd.Series[bool] / Python native sequence""" + """Test pd.Series[bool] / Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left / b, "pd.Series[float]"), pd.Series, np.floating) @@ -111,7 +111,7 @@ def test_truediv_py_sequence() -> None: def test_truediv_numpy_array() -> None: - """Test pd.Series[bool] / numpy array""" + """Test pd.Series[bool] / numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -171,8 +171,62 @@ def test_truediv_numpy_array() -> None: ) +def test_truediv_pd_index() -> None: + """Test pd.Series[bool] / pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + if TYPE_CHECKING_INVALID_USAGE: + _1 = b / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.truediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.truediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rtruediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rtruediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rdiv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rdiv(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_truediv_pd_series() -> None: - """Test pd.Series[bool] / pandas series""" + """Test pd.Series[bool] / pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/complex/test_add.py b/tests/series/arithmetic/complex/test_add.py index e92ea5cea..4e0338979 100644 --- a/tests/series/arithmetic/complex/test_add.py +++ b/tests/series/arithmetic/complex/test_add.py @@ -42,7 +42,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[complex] + Python native sequence""" + """Test pd.Series[complex] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Series[complex]"), pd.Series, np.complexfloating) @@ -75,7 +75,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Series[complex] + numpy array""" + """Test pd.Series[complex] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -119,12 +119,12 @@ def test_add_numpy_array() -> None: ) -def test_add_pd_series() -> None: - """Test pd.Series[complex] + pandas series""" - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_add_pd_index() -> None: + """Test pd.Series[complex] + pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[complex]"), pd.Series, np.complexfloating) check(assert_type(left + i, "pd.Series[complex]"), pd.Series, np.complexfloating) @@ -155,12 +155,12 @@ def test_add_pd_series() -> None: ) -def test_add_pd_index() -> None: - """Test pd.Series[complex] + pandas index""" - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_add_pd_series() -> None: + """Test pd.Series[complex] + pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[complex]"), pd.Series, np.complexfloating) check(assert_type(left + i, "pd.Series[complex]"), pd.Series, np.complexfloating) diff --git a/tests/series/arithmetic/complex/test_mul.py b/tests/series/arithmetic/complex/test_mul.py index 206e1b82c..e36a822c6 100644 --- a/tests/series/arithmetic/complex/test_mul.py +++ b/tests/series/arithmetic/complex/test_mul.py @@ -42,7 +42,7 @@ def test_mul_py_scalar() -> None: def test_mul_py_sequence() -> None: - """Test pd.Series[complex] * Python native sequence""" + """Test pd.Series[complex] * Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left * b, "pd.Series[complex]"), pd.Series, np.complexfloating) @@ -75,7 +75,7 @@ def test_mul_py_sequence() -> None: def test_mul_numpy_array() -> None: - """Test pd.Series[complex] * numpy array""" + """Test pd.Series[complex] * numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -119,8 +119,44 @@ def test_mul_numpy_array() -> None: ) +def test_mul_pd_index() -> None: + """Test pd.Series[complex] * pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left * b, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left * i, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left * f, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left * c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(i * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(f * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(c * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.mul(b), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.mul(i), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.mul(f), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.mul(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check( + assert_type(left.rmul(b), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rmul(i), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rmul(f), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rmul(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_mul_pd_series() -> None: - """Test pd.Series[complex] * pandas series""" + """Test pd.Series[complex] * pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/complex/test_sub.py b/tests/series/arithmetic/complex/test_sub.py index b1daa4541..a58c31ae3 100644 --- a/tests/series/arithmetic/complex/test_sub.py +++ b/tests/series/arithmetic/complex/test_sub.py @@ -44,7 +44,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Series[complex] - Python native sequence""" + """Test pd.Series[complex] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Series[complex]"), pd.Series, np.complexfloating) @@ -77,7 +77,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Series[complex] - numpy array""" + """Test pd.Series[complex] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -121,8 +121,44 @@ def test_sub_numpy_array() -> None: ) +def test_sub_pd_index() -> None: + """Test pd.Series[complex] - pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left - b, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left - i, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left - f, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left - c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(i - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(f - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(c - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.sub(b), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.sub(i), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.sub(f), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.sub(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check( + assert_type(left.rsub(b), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rsub(i), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rsub(f), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rsub(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_sub_pd_series() -> None: - """Test pd.Series[complex] - pandas series""" + """Test pd.Series[complex] - pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/complex/test_truediv.py b/tests/series/arithmetic/complex/test_truediv.py index 38a8b9096..9d564659c 100644 --- a/tests/series/arithmetic/complex/test_truediv.py +++ b/tests/series/arithmetic/complex/test_truediv.py @@ -84,7 +84,7 @@ def test_truediv_py_scalar() -> None: def test_truediv_py_sequence() -> None: - """Test pd.Series[complex] / Python native sequence""" + """Test pd.Series[complex] / Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left / b, "pd.Series[complex]"), pd.Series, np.complexfloating) @@ -159,7 +159,7 @@ def test_truediv_py_sequence() -> None: def test_truediv_numpy_array() -> None: - """Test pd.Series[complex] / numpy array""" + """Test pd.Series[complex] / numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -249,8 +249,86 @@ def test_truediv_numpy_array() -> None: ) +def test_truediv_pd_index() -> None: + """Test pd.Series[complex] / pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left / b, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left / i, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left / f, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left / c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(i / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(f / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(c / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check( + assert_type(left.truediv(b), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.truediv(i), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.truediv(f), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.truediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check(assert_type(left.div(b), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.div(i), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.div(f), "pd.Series[complex]"), pd.Series, np.complexfloating) + check(assert_type(left.div(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check( + assert_type(left.rtruediv(b), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.rtruediv(i), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.rtruediv(f), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + check( + assert_type(left.rtruediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check( + assert_type(left.rdiv(b), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rdiv(i), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rdiv(f), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + check( + assert_type(left.rdiv(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_truediv_pd_series() -> None: - """Test pd.Series[complex] / pandas series""" + """Test pd.Series[complex] / pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/float/test_add.py b/tests/series/arithmetic/float/test_add.py index 5126f8d79..6318ebf24 100644 --- a/tests/series/arithmetic/float/test_add.py +++ b/tests/series/arithmetic/float/test_add.py @@ -36,7 +36,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[float] + Python native sequence""" + """Test pd.Series[float] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Series[float]"), pd.Series, np.floating) @@ -63,7 +63,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Series[float] + numpy array""" + """Test pd.Series[float] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,12 +99,12 @@ def test_add_numpy_array() -> None: ) -def test_add_pd_series() -> None: - """Test pd.Series[float] + pandas series""" - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_add_pd_index() -> None: + """Test pd.Series[float] + pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[float]"), pd.Series, np.floating) check(assert_type(left + i, "pd.Series[float]"), pd.Series, np.floating) @@ -129,12 +129,12 @@ def test_add_pd_series() -> None: ) -def test_add_pd_index() -> None: - """Test pd.Series[float] + pandas index""" - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_add_pd_series() -> None: + """Test pd.Series[float] + pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[float]"), pd.Series, np.floating) check(assert_type(left + i, "pd.Series[float]"), pd.Series, np.floating) diff --git a/tests/series/arithmetic/float/test_floordiv.py b/tests/series/arithmetic/float/test_floordiv.py new file mode 100644 index 000000000..2eedc4ef3 --- /dev/null +++ b/tests/series/arithmetic/float/test_floordiv.py @@ -0,0 +1,178 @@ +from typing import Any + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([1.2, 2.4, 3.6]) # left operand + + +def test_floordiv_py_scalar() -> None: + """Test pd.Series[float] // Python native scalars""" + b, i, f, c = True, 1, 1.0, 1j + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_py_sequence() -> None: + """Test pd.Series[float] // Python native sequences""" + b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_numpy_array() -> None: + """Test pd.Series[float] // numpy arrays""" + b = np.array([True, False, True], np.bool_) + i = np.array([2, 3, 5], np.int64) + f = np.array([1.0, 2.0, 3.0], np.float64) + c = np.array([1.1j, 2.2j, 4.1j], np.complex128) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // b, Never) + check(assert_type(left // i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // c, Never) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rfloordiv__` cannot override. At runtime, they lead to + # errors or pd.Series. + assert_type(b // left, "npt.NDArray[np.int8]") + check(i // left, pd.Series, np.floating) + check(f // left, pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(c // left, Any) + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_pd_index() -> None: + """Test pd.Series[float] // pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_pd_series() -> None: + """Test pd.Series[float] // pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] diff --git a/tests/series/arithmetic/float/test_mul.py b/tests/series/arithmetic/float/test_mul.py index 9472d5335..f4afe08d2 100644 --- a/tests/series/arithmetic/float/test_mul.py +++ b/tests/series/arithmetic/float/test_mul.py @@ -36,7 +36,7 @@ def test_mul_py_scalar() -> None: def test_mul_py_sequence() -> None: - """Test pd.Series[float] * Python native sequence""" + """Test pd.Series[float] * Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left * b, "pd.Series[float]"), pd.Series, np.floating) @@ -63,7 +63,7 @@ def test_mul_py_sequence() -> None: def test_mul_numpy_array() -> None: - """Test pd.Series[float] * numpy array""" + """Test pd.Series[float] * numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,8 +99,38 @@ def test_mul_numpy_array() -> None: ) +def test_mul_pd_index() -> None: + """Test pd.Series[float] * pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left * b, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left * i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left * f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left * c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b * left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(i * left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f * left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.mul(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.mul(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.mul(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.mul(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rmul(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rmul(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rmul(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rmul(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_mul_pd_series() -> None: - """Test pd.Series[float] * pandas series""" + """Test pd.Series[float] * pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/float/test_sub.py b/tests/series/arithmetic/float/test_sub.py index d4722b3f1..afad8dab5 100644 --- a/tests/series/arithmetic/float/test_sub.py +++ b/tests/series/arithmetic/float/test_sub.py @@ -38,7 +38,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Series[float] - Python native sequence""" + """Test pd.Series[float] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Series[float]"), pd.Series, np.floating) @@ -65,7 +65,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Series[float] - numpy array""" + """Test pd.Series[float] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -101,8 +101,38 @@ def test_sub_numpy_array() -> None: ) +def test_sub_pd_index() -> None: + """Test pd.Series[float] - pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left - b, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left - i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left - f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left - c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b - left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(i - left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f - left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.sub(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.sub(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.sub(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.sub(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rsub(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rsub(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rsub(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rsub(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_sub_pd_series() -> None: - """Test pd.Series[float] - pandas series""" + """Test pd.Series[float] - pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/float/test_truediv.py b/tests/series/arithmetic/float/test_truediv.py index fc0dc9023..3add54e9e 100644 --- a/tests/series/arithmetic/float/test_truediv.py +++ b/tests/series/arithmetic/float/test_truediv.py @@ -54,7 +54,7 @@ def test_truediv_py_scalar() -> None: def test_truediv_py_sequence() -> None: - """Test pd.Series[float] / Python native sequence""" + """Test pd.Series[float] / Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left / b, "pd.Series[float]"), pd.Series, np.floating) @@ -99,7 +99,7 @@ def test_truediv_py_sequence() -> None: def test_truediv_numpy_array() -> None: - """Test pd.Series[float] / numpy array""" + """Test pd.Series[float] / numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -153,8 +153,56 @@ def test_truediv_numpy_array() -> None: ) +def test_truediv_pd_index() -> None: + """Test pd.Series[float] / pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left / b, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(i / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.truediv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.truediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.truediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.truediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check(assert_type(left.div(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rtruediv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rtruediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rtruediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rtruediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check(assert_type(left.rdiv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rdiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rdiv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rdiv(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_truediv_pd_series() -> None: - """Test pd.Series[float] / pandas series""" + """Test pd.Series[float] / pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/int/test_add.py b/tests/series/arithmetic/int/test_add.py index cac8eadb6..8f544374a 100644 --- a/tests/series/arithmetic/int/test_add.py +++ b/tests/series/arithmetic/int/test_add.py @@ -36,7 +36,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[int] + Python native sequence""" + """Test pd.Series[int] + Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left + b, "pd.Series[int]"), pd.Series, np.integer) @@ -63,7 +63,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Series[int] + numpy array""" + """Test pd.Series[int] + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,12 +99,12 @@ def test_add_numpy_array() -> None: ) -def test_add_pd_series() -> None: - """Test pd.Series[int] + pandas series""" - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_add_pd_index() -> None: + """Test pd.Series[int] + pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[int]"), pd.Series, np.integer) check(assert_type(left + i, "pd.Series[int]"), pd.Series, np.integer) @@ -129,12 +129,12 @@ def test_add_pd_series() -> None: ) -def test_add_pd_index() -> None: - """Test pd.Series[int] + pandas index""" - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_add_pd_series() -> None: + """Test pd.Series[int] + pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) check(assert_type(left + b, "pd.Series[int]"), pd.Series, np.integer) check(assert_type(left + i, "pd.Series[int]"), pd.Series, np.integer) diff --git a/tests/series/arithmetic/int/test_floordiv.py b/tests/series/arithmetic/int/test_floordiv.py new file mode 100644 index 000000000..0504d1074 --- /dev/null +++ b/tests/series/arithmetic/int/test_floordiv.py @@ -0,0 +1,178 @@ +from typing import Any + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([1, 2, 3]) # left operand + + +def test_floordiv_py_scalar() -> None: + """Test pd.Series[int] // Python native scalars""" + b, i, f, c = True, 1, 1.0, 1j + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_py_sequence() -> None: + """Test pd.Series[int] // Python native sequences""" + b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_numpy_array() -> None: + """Test pd.Series[int] // numpy arrays""" + b = np.array([True, False, True], np.bool_) + i = np.array([2, 3, 5], np.int64) + f = np.array([1.0, 2.0, 3.0], np.float64) + c = np.array([1.1j, 2.2j, 4.1j], np.complex128) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // b, Never) + check(assert_type(left // i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // c, Never) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rfloordiv__` cannot override. At runtime, they lead to + # errors or pd.Series. + assert_type(b // left, "npt.NDArray[np.int8]") + check(i // left, pd.Series, np.integer) + check(f // left, pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(c // left, Any) + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_pd_index() -> None: + """Test pd.Series[int] // pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_floordiv_pd_series() -> None: + """Test pd.Series[int] // pandas Series""" + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left // f, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _2 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(i // left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f // left, "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + _3 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.floordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rfloordiv(f), "pd.Series[float]"), pd.Series, np.floating) + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] diff --git a/tests/series/arithmetic/int/test_mul.py b/tests/series/arithmetic/int/test_mul.py index 2018de06e..b15d91256 100644 --- a/tests/series/arithmetic/int/test_mul.py +++ b/tests/series/arithmetic/int/test_mul.py @@ -36,7 +36,7 @@ def test_mul_py_scalar() -> None: def test_mul_py_sequence() -> None: - """Test pd.Series[int] * Python native sequence""" + """Test pd.Series[int] * Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left * b, "pd.Series[int]"), pd.Series, np.integer) @@ -63,7 +63,7 @@ def test_mul_py_sequence() -> None: def test_mul_numpy_array() -> None: - """Test pd.Series[int] * numpy array""" + """Test pd.Series[int] * numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -99,8 +99,38 @@ def test_mul_numpy_array() -> None: ) +def test_mul_pd_index() -> None: + """Test pd.Series[int] * pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left * b, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left * i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left * f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left * c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b * left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(i * left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f * left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c * left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.mul(b), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.mul(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.mul(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.mul(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rmul(b), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rmul(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rmul(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rmul(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_mul_pd_series() -> None: - """Test pd.Series[int] * pandas series""" + """Test pd.Series[int] * pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/int/test_sub.py b/tests/series/arithmetic/int/test_sub.py index 75fc96a62..28bcdd4f0 100644 --- a/tests/series/arithmetic/int/test_sub.py +++ b/tests/series/arithmetic/int/test_sub.py @@ -38,7 +38,7 @@ def test_sub_py_scalar() -> None: def test_sub_py_sequence() -> None: - """Test pd.Series[int] - Python native sequence""" + """Test pd.Series[int] - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left - b, "pd.Series[int]"), pd.Series, np.integer) @@ -65,7 +65,7 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Series[int] - numpy array""" + """Test pd.Series[int] - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -101,8 +101,38 @@ def test_sub_numpy_array() -> None: ) +def test_sub_pd_index() -> None: + """Test pd.Series[int] - pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left - b, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left - i, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left - f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left - c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b - left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(i - left, "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(f - left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c - left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.sub(b), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.sub(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.sub(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.sub(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rsub(b), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rsub(i), "pd.Series[int]"), pd.Series, np.integer) + check(assert_type(left.rsub(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rsub(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_sub_pd_series() -> None: - """Test pd.Series[int] - pandas series""" + """Test pd.Series[int] - pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/int/test_truediv.py b/tests/series/arithmetic/int/test_truediv.py index a6d7f2a37..f9f665408 100644 --- a/tests/series/arithmetic/int/test_truediv.py +++ b/tests/series/arithmetic/int/test_truediv.py @@ -54,7 +54,7 @@ def test_truediv_py_scalar() -> None: def test_truediv_py_sequence() -> None: - """Test pd.Series[int] / Python native sequence""" + """Test pd.Series[int] / Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left / b, "pd.Series[float]"), pd.Series, np.floating) @@ -99,7 +99,7 @@ def test_truediv_py_sequence() -> None: def test_truediv_numpy_array() -> None: - """Test pd.Series[int] / numpy array""" + """Test pd.Series[int] / numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -153,8 +153,56 @@ def test_truediv_numpy_array() -> None: ) +def test_truediv_pd_index() -> None: + """Test pd.Series[int] / pandas Indexes""" + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left / b, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / i, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / f, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left / c, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(b / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(i / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(f / left, "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(c / left, "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.truediv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.truediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.truediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.truediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check(assert_type(left.div(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(f), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.div(c), "pd.Series[complex]"), pd.Series, np.complexfloating) + + check(assert_type(left.rtruediv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rtruediv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rtruediv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rtruediv(c), "pd.Series[complex]"), + pd.Series, + np.complexfloating, + ) + + check(assert_type(left.rdiv(b), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rdiv(i), "pd.Series[float]"), pd.Series, np.floating) + check(assert_type(left.rdiv(f), "pd.Series[float]"), pd.Series, np.floating) + check( + assert_type(left.rdiv(c), "pd.Series[complex]"), pd.Series, np.complexfloating + ) + + def test_truediv_pd_series() -> None: - """Test pd.Series[int] / pandas series""" + """Test pd.Series[int] / pandas Series""" b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) f = pd.Series([1.0, 2.0, 3.0]) diff --git a/tests/series/arithmetic/str/test_add.py b/tests/series/arithmetic/str/test_add.py index 9ac84ea71..d9b2ec6fd 100644 --- a/tests/series/arithmetic/str/test_add.py +++ b/tests/series/arithmetic/str/test_add.py @@ -40,7 +40,7 @@ def test_add_py_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[str] + Python native sequence""" + """Test pd.Series[str] + Python native sequences""" i = [3, 5, 8] r0 = ["a", "bc", "def"] r1 = tuple(r0) @@ -67,7 +67,7 @@ def test_add_py_sequence() -> None: def test_add_numpy_array() -> None: - """Test pd.Series[str] + numpy array""" + """Test pd.Series[str] + numpy arrays""" i = np.array([3, 5, 8], np.int64) r0 = np.array(["a", "bc", "def"], np.str_) @@ -100,10 +100,10 @@ def test_add_numpy_array() -> None: check(assert_type(left.radd(r0), "pd.Series[str]"), pd.Series, str) -def test_add_pd_series() -> None: - """Test pd.Series[str] + pandas series""" - i = pd.Series([3, 5, 8]) - r0 = pd.Series(["a", "bc", "def"]) +def test_add_pd_index() -> None: + """Test pd.Series[str] + pandas Indexes""" + i = pd.Index([3, 5, 8]) + r0 = pd.Index(["a", "bc", "def"]) if TYPE_CHECKING_INVALID_USAGE: _0 = left + i # type: ignore[operator] # pyright: ignore[reportOperatorIssue] @@ -122,10 +122,10 @@ def test_add_pd_series() -> None: check(assert_type(left.radd(r0), "pd.Series[str]"), pd.Series, str) -def test_add_pd_index() -> None: - """Test pd.Series[str] + pandas index""" - i = pd.Index([3, 5, 8]) - r0 = pd.Index(["a", "bc", "def"]) +def test_add_pd_series() -> None: + """Test pd.Series[str] + pandas Series""" + i = pd.Series([3, 5, 8]) + r0 = pd.Series(["a", "bc", "def"]) if TYPE_CHECKING_INVALID_USAGE: _0 = left + i # type: ignore[operator] # pyright: ignore[reportOperatorIssue] diff --git a/tests/series/arithmetic/test_add.py b/tests/series/arithmetic/test_add.py index d06367c13..b1094ed71 100644 --- a/tests/series/arithmetic/test_add.py +++ b/tests/series/arithmetic/test_add.py @@ -40,7 +40,7 @@ def test_add_i_py_scalar() -> None: def test_add_i_py_sequence() -> None: - """Test pd.Series[Any] (int) + Python native sequence""" + """Test pd.Series[Any] (int) + Python native sequences""" # mypy believe it is already list[Any], whereas pyright gives list[bool | int | complex] a = cast(list[Any], [True, 3, 5j]) # type: ignore[redundant-cast] b = [True, False, True] @@ -74,7 +74,7 @@ def test_add_i_py_sequence() -> None: def test_add_i_numpy_array() -> None: - """Test pd.Series[Any] (int) + numpy array""" + """Test pd.Series[Any] (int) + numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -117,13 +117,13 @@ def test_add_i_numpy_array() -> None: check(assert_type(left_i.radd(c), pd.Series), pd.Series) -def test_add_i_pd_series() -> None: - """Test pd.Series[Any] (int) + pandas series""" - a = pd.DataFrame({"a": [1, 2, 3]})["a"] - b = pd.Series([True, False, True]) - i = pd.Series([2, 3, 5]) - f = pd.Series([1.0, 2.0, 3.0]) - c = pd.Series([1.1j, 2.2j, 4.1j]) +def test_add_i_pd_index() -> None: + """Test pd.Series[Any] (int) + pandas Indexes""" + a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) check(assert_type(left_i + a, pd.Series), pd.Series) check(assert_type(left_i + b, pd.Series), pd.Series) @@ -150,13 +150,13 @@ def test_add_i_pd_series() -> None: check(assert_type(left_i.radd(c), pd.Series), pd.Series) -def test_add_i_pd_index() -> None: - """Test pd.Series[Any] (int) + pandas index""" - a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] - b = pd.Index([True, False, True]) - i = pd.Index([2, 3, 5]) - f = pd.Index([1.0, 2.0, 3.0]) - c = pd.Index([1.1j, 2.2j, 4.1j]) +def test_add_i_pd_series() -> None: + """Test pd.Series[Any] (int) + pandas Series""" + a = pd.DataFrame({"a": [1, 2, 3]})["a"] + b = pd.Series([True, False, True]) + i = pd.Series([2, 3, 5]) + f = pd.Series([1.0, 2.0, 3.0]) + c = pd.Series([1.1j, 2.2j, 4.1j]) check(assert_type(left_i + a, pd.Series), pd.Series) check(assert_type(left_i + b, pd.Series), pd.Series) diff --git a/tests/series/arithmetic/test_mul.py b/tests/series/arithmetic/test_mul.py index 71cc4962d..f89633416 100644 --- a/tests/series/arithmetic/test_mul.py +++ b/tests/series/arithmetic/test_mul.py @@ -38,7 +38,7 @@ def test_mul_py_scalar() -> None: def test_mul_py_sequence() -> None: - """Test pd.Series[Any] (int) * Python native sequence""" + """Test pd.Series[Any] (int) * Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left_i * b, pd.Series), pd.Series) @@ -63,7 +63,7 @@ def test_mul_py_sequence() -> None: def test_mul_numpy_array() -> None: - """Test pd.Series[Any] (int) * numpy array""" + """Test pd.Series[Any] (int) * numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -106,8 +106,41 @@ def test_mul_numpy_array() -> None: check(assert_type(left_i.rmul(c), pd.Series), pd.Series) +def test_mul_pd_index() -> None: + """Test pd.Series[Any] (int) * pandas Indexes""" + a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left_i * a, pd.Series), pd.Series) + check(assert_type(left_i * b, pd.Series), pd.Series) + check(assert_type(left_i * i, pd.Series), pd.Series) + check(assert_type(left_i * f, pd.Series), pd.Series) + check(assert_type(left_i * c, pd.Series), pd.Series) + + check(assert_type(a * left_i, pd.Series), pd.Series) + check(assert_type(b * left_i, pd.Series), pd.Series) + check(assert_type(i * left_i, pd.Series), pd.Series) + check(assert_type(f * left_i, pd.Series), pd.Series) + check(assert_type(c * left_i, pd.Series), pd.Series) + + check(assert_type(left_i.mul(a), pd.Series), pd.Series) + check(assert_type(left_i.mul(b), pd.Series), pd.Series) + check(assert_type(left_i.mul(i), pd.Series), pd.Series) + check(assert_type(left_i.mul(f), pd.Series), pd.Series) + check(assert_type(left_i.mul(c), pd.Series), pd.Series) + + check(assert_type(left_i.rmul(a), pd.Series), pd.Series) + check(assert_type(left_i.rmul(b), pd.Series), pd.Series) + check(assert_type(left_i.rmul(i), pd.Series), pd.Series) + check(assert_type(left_i.rmul(f), pd.Series), pd.Series) + check(assert_type(left_i.rmul(c), pd.Series), pd.Series) + + def test_mul_pd_series() -> None: - """Test pd.Series[Any] (int) * pandas series""" + """Test pd.Series[Any] (int) * pandas Series""" a = pd.DataFrame({"a": [1, 2, 3]})["a"] b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) diff --git a/tests/series/arithmetic/test_sub.py b/tests/series/arithmetic/test_sub.py index 56f2380d8..21398e881 100644 --- a/tests/series/arithmetic/test_sub.py +++ b/tests/series/arithmetic/test_sub.py @@ -2,10 +2,7 @@ datetime, timedelta, ) -from typing import ( - TYPE_CHECKING, - Any, -) +from typing import Any import numpy as np import pandas as pd @@ -16,9 +13,6 @@ check, ) -if TYPE_CHECKING: - from pandas.core.series import TimedeltaSeries # noqa: F401 - anchor = datetime(2025, 8, 18) # left operands @@ -53,7 +47,7 @@ def test_sub_i_py_scalar() -> None: def test_sub_i_py_sequence() -> None: - """Test pd.Series[Any] (int) - Python native sequence""" + """Test pd.Series[Any] (int) - Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left_i - b, pd.Series), pd.Series) @@ -78,7 +72,7 @@ def test_sub_i_py_sequence() -> None: def test_sub_i_numpy_array() -> None: - """Test pd.Series[Any] (int) - numpy array""" + """Test pd.Series[Any] (int) - numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -121,8 +115,41 @@ def test_sub_i_numpy_array() -> None: check(assert_type(left_i.rsub(c), pd.Series), pd.Series) +def test_sub_i_pd_index() -> None: + """Test pd.Series[Any] (int) - pandas Indexes""" + a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left_i - a, pd.Series), pd.Series) + check(assert_type(left_i - b, pd.Series), pd.Series) + check(assert_type(left_i - i, pd.Series), pd.Series) + check(assert_type(left_i - f, pd.Series), pd.Series) + check(assert_type(left_i - c, pd.Series), pd.Series) + + check(assert_type(a - left_i, pd.Series), pd.Series) + check(assert_type(b - left_i, pd.Series), pd.Series) + check(assert_type(i - left_i, pd.Series), pd.Series) + check(assert_type(f - left_i, pd.Series), pd.Series) + check(assert_type(c - left_i, pd.Series), pd.Series) + + check(assert_type(left_i.sub(a), pd.Series), pd.Series) + check(assert_type(left_i.sub(b), pd.Series), pd.Series) + check(assert_type(left_i.sub(i), pd.Series), pd.Series) + check(assert_type(left_i.sub(f), pd.Series), pd.Series) + check(assert_type(left_i.sub(c), pd.Series), pd.Series) + + check(assert_type(left_i.rsub(a), pd.Series), pd.Series) + check(assert_type(left_i.rsub(b), pd.Series), pd.Series) + check(assert_type(left_i.rsub(i), pd.Series), pd.Series) + check(assert_type(left_i.rsub(f), pd.Series), pd.Series) + check(assert_type(left_i.rsub(c), pd.Series), pd.Series) + + def test_sub_i_pd_series() -> None: - """Test pd.Series[Any] (int) - pandas series""" + """Test pd.Series[Any] (int) - pandas Series""" a = pd.DataFrame({"a": [1, 2, 3]})["a"] b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) @@ -159,7 +186,7 @@ def test_sub_ts_py_datetime() -> None: s = anchor a = [s + timedelta(minutes=m) for m in range(3)] - check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left_ts - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: # Series[Any] (Timestamp) - Sequence[datetime] should work, see pandas-dev/pandas#62353 _1 = left_ts - a # type: ignore[operator] # pyright: ignore[reportOperatorIssue] @@ -182,8 +209,12 @@ def test_sub_ts_py_datetime() -> None: # Sequence[datetime] - Series[Any] (Timedelta) should work, see pandas-dev/pandas#62353 _7 = a - left_td # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(left_ts.sub(a), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check( + assert_type(left_ts.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left_ts.sub(a), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) # Series[Any] (Timedelta).sub(datetime or Sequence[datetime]) fails at runtime, # which cannot be revealed by our static type checking # left_td.sub(s) @@ -200,8 +231,8 @@ def test_sub_ts_numpy_datetime() -> None: s = np.datetime64(anchor) a = np.array([s + np.timedelta64(m, "m") for m in range(3)], np.datetime64) - check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(left_ts - a, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left_ts - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left_ts - a, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) # Series[Any] (Timedelta) - np.datetime64 or np.typing.NDArray[np.datetime64] # fails at runtime, # which cannot be revealed by our static type checking @@ -225,8 +256,12 @@ def test_sub_ts_numpy_datetime() -> None: pd.Timestamp, ) - check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(left_ts.sub(a), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check( + assert_type(left_ts.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left_ts.sub(a), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) # Series[Any] (Timedelta).sub(np.datetime64 or np.typing.NDArray[np.datetime64]) # fails at runtime, # which cannot be revealed by our static type checking @@ -244,7 +279,7 @@ def test_sub_ts_pd_datetime() -> None: s = pd.Timestamp(anchor) a = pd.Series([s + pd.Timedelta(minutes=m) for m in range(3)]) - check(assert_type(left_ts - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left_ts - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left_ts - a, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) # Series[Any] (Timedelta) - Timestamp or Series[Timestamp] # fails at runtime, @@ -257,7 +292,9 @@ def test_sub_ts_pd_datetime() -> None: check(assert_type(s - left_td, pd.Series), pd.Series, pd.Timestamp) check(assert_type(a - left_td, pd.Series), pd.Series, pd.Timestamp) - check(assert_type(left_ts.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check( + assert_type(left_ts.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) check( assert_type(left_ts.sub(a), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta ) diff --git a/tests/series/arithmetic/test_truediv.py b/tests/series/arithmetic/test_truediv.py index e0f0cbf87..9baa2c49b 100644 --- a/tests/series/arithmetic/test_truediv.py +++ b/tests/series/arithmetic/test_truediv.py @@ -50,7 +50,7 @@ def test_truediv_py_scalar() -> None: def test_truediv_py_sequence() -> None: - """Test pd.Series[Any] (int) / Python native sequence""" + """Test pd.Series[Any] (int) / Python native sequences""" b, i, f, c = [True, False, True], [2, 3, 5], [1.0, 2.0, 3.0], [1j, 1j, 4j] check(assert_type(left_i / b, pd.Series), pd.Series) @@ -85,7 +85,7 @@ def test_truediv_py_sequence() -> None: def test_truediv_numpy_array() -> None: - """Test pd.Series[Any] (int) / numpy array""" + """Test pd.Series[Any] (int) / numpy arrays""" b = np.array([True, False, True], np.bool_) i = np.array([2, 3, 5], np.int64) f = np.array([1.0, 2.0, 3.0], np.float64) @@ -138,8 +138,53 @@ def test_truediv_numpy_array() -> None: check(assert_type(left_i.rdiv(c), pd.Series), pd.Series) +def test_truediv_pd_index() -> None: + """Test pd.Series[Any] (int) / pandas Indexes""" + a = pd.MultiIndex.from_tuples([(1,), (2,), (3,)]).levels[0] + b = pd.Index([True, False, True]) + i = pd.Index([2, 3, 5]) + f = pd.Index([1.0, 2.0, 3.0]) + c = pd.Index([1.1j, 2.2j, 4.1j]) + + check(assert_type(left_i / a, pd.Series), pd.Series) + check(assert_type(left_i / b, pd.Series), pd.Series) + check(assert_type(left_i / i, pd.Series), pd.Series) + check(assert_type(left_i / f, pd.Series), pd.Series) + check(assert_type(left_i / c, pd.Series), pd.Series) + + check(assert_type(a / left_i, pd.Series), pd.Series) + check(assert_type(b / left_i, pd.Series), pd.Series) + check(assert_type(i / left_i, pd.Series), pd.Series) + check(assert_type(f / left_i, pd.Series), pd.Series) + check(assert_type(c / left_i, pd.Series), pd.Series) + + check(assert_type(left_i.truediv(a), pd.Series), pd.Series) + check(assert_type(left_i.truediv(b), pd.Series), pd.Series) + check(assert_type(left_i.truediv(i), pd.Series), pd.Series) + check(assert_type(left_i.truediv(f), pd.Series), pd.Series) + check(assert_type(left_i.truediv(c), pd.Series), pd.Series) + + check(assert_type(left_i.div(a), pd.Series), pd.Series) + check(assert_type(left_i.div(b), pd.Series), pd.Series) + check(assert_type(left_i.div(i), pd.Series), pd.Series) + check(assert_type(left_i.div(f), pd.Series), pd.Series) + check(assert_type(left_i.div(c), pd.Series), pd.Series) + + check(assert_type(left_i.rtruediv(a), pd.Series), pd.Series) + check(assert_type(left_i.rtruediv(b), pd.Series), pd.Series) + check(assert_type(left_i.rtruediv(i), pd.Series), pd.Series) + check(assert_type(left_i.rtruediv(f), pd.Series), pd.Series) + check(assert_type(left_i.rtruediv(c), pd.Series), pd.Series) + + check(assert_type(left_i.rdiv(a), pd.Series), pd.Series) + check(assert_type(left_i.rdiv(b), pd.Series), pd.Series) + check(assert_type(left_i.rdiv(i), pd.Series), pd.Series) + check(assert_type(left_i.rdiv(f), pd.Series), pd.Series) + check(assert_type(left_i.rdiv(c), pd.Series), pd.Series) + + def test_truediv_pd_series() -> None: - """Test pd.Series[Any] (int) / pandas series""" + """Test pd.Series[Any] (int) / pandas Series""" a = pd.DataFrame({"a": [1, 2, 3]})["a"] b = pd.Series([True, False, True]) i = pd.Series([2, 3, 5]) diff --git a/tests/series/arithmetic/timedelta/__init__.py b/tests/series/arithmetic/timedelta/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/series/arithmetic/timedelta/test_add.py b/tests/series/arithmetic/timedelta/test_add.py new file mode 100644 index 000000000..4aee2bd02 --- /dev/null +++ b/tests/series/arithmetic/timedelta/test_add.py @@ -0,0 +1,148 @@ +from datetime import ( + datetime, + timedelta, +) + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import assert_type + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([pd.Timedelta(1, "s")]) # left operand + + +def test_add_py_scalar() -> None: + """Test pd.Series[pd.Timedelta] + Python native scalars""" + s = datetime(2025, 8, 20) + d = timedelta(seconds=1) + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_numpy_scalar() -> None: + """Test pd.Series[pd.Timedelta] + numpy scalars""" + s = np.datetime64("2025-08-20") + d = np.timedelta64(1, "s") + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_pd_scalar() -> None: + """Test pd.Series[pd.Timedelta] + pandas scalars""" + s = pd.Timestamp("2025-08-20") + d = pd.Timedelta(seconds=1) + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_py_sequence() -> None: + """Test pd.Series[pd.Timedelta] + Python native sequences""" + s = [datetime(2025, 8, 20)] + d = [timedelta(seconds=1)] + + if TYPE_CHECKING_INVALID_USAGE: + # Series[Timedelta] + Sequence[datetime] should work, see pandas-dev/pandas#62353 + _0 = left + s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + # Series[Timedelta] + Sequence[timedelta] should work, see pandas-dev/pandas#62353 + _a = left + d # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _1 = s + left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _b = d + left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_numpy_array() -> None: + """Test pd.Series[pd.Timedelta] + numpy arrays""" + s = np.array([np.datetime64("2025-08-20")], np.datetime64) + d = np.array([np.timedelta64(1, "s")], np.timedelta64) + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__radd__` cannot override. At runtime, they return + # `Series`. + check(assert_type(s + left, "npt.NDArray[np.datetime64]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "npt.NDArray[np.timedelta64]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_pd_index() -> None: + """Test pd.Series[pd.Timedelta] + pandas Indexes""" + s = pd.Index([pd.Timestamp("2025-08-20")]) + d = pd.Index([pd.Timedelta(seconds=1)]) + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_add_pd_series() -> None: + """Test pd.Series[pd.Timedelta] + pandas Series""" + s = pd.Series([pd.Timestamp("2025-08-20")]) + d = pd.Series([pd.Timedelta(seconds=1)]) + + check(assert_type(left + s, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left + d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d + left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.add(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.add(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.radd(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.radd(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) diff --git a/tests/series/arithmetic/timedelta/test_floordiv.py b/tests/series/arithmetic/timedelta/test_floordiv.py new file mode 100644 index 000000000..bb267d583 --- /dev/null +++ b/tests/series/arithmetic/timedelta/test_floordiv.py @@ -0,0 +1,294 @@ +from datetime import ( + datetime, + timedelta, +) +from typing import Any + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([pd.Timedelta(1, "s")]) # left operand + + +def test_floordiv_py_scalar() -> None: + """Test pd.Series[pd.Timedelta] // Python native scalars""" + b, i, f, c = True, 1, 1.0, 1j + s, d = datetime(2025, 9, 24), timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left // f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left // s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // d, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d // left, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.floordiv(i), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(left.floordiv(f), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(b) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(i) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(f) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(c) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + +def test_floordiv_py_sequence() -> None: + """Test pd.Series[pd.Timedelta] // Python native sequences""" + b, i, f, c = [True], [2], [1.5], [1.7j] + s, d = [datetime(2025, 9, 24)], [timedelta(seconds=1)] + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left // f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left // s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // d, "pd.Series[int]"), pd.Series, int) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d // left, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.floordiv(i), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(left.floordiv(f), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + +def test_floordiv_numpy_array() -> None: + """Test pd.Series[pd.Timedelta] // numpy arrays""" + b = np.array([True], np.bool_) + i = np.array([2], np.int64) + f = np.array([1.5], np.float64) + c = np.array([1.7j], np.complex128) + s = np.array([datetime(2025, 9, 24)], np.datetime64) + d = np.array([timedelta(seconds=1)], np.timedelta64) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // b, Never) + check(assert_type(left // i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left // f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left // c, Never) + assert_type(left // s, Never) + check(assert_type(left // d, "pd.Series[int]"), pd.Series, np.integer) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rfloordiv__` cannot override. At runtime, they lead to + # errors or pd.Series. + if TYPE_CHECKING_INVALID_USAGE: + assert_type(b // left, "npt.NDArray[np.int8]") + assert_type(i // left, "npt.NDArray[np.int64]") + assert_type(f // left, "npt.NDArray[np.float64]") + assert_type(c // left, Any) + assert_type(s // left, Any) + check(assert_type(d // left, "npt.NDArray[np.int64]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.floordiv(i), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(left.floordiv(f), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + +def test_floordiv_pd_scalar() -> None: + """Test pd.Series[pd.Timedelta] // pandas scalars""" + s, d = pd.Timestamp(2025, 9, 24), pd.Timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // d, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + _1 = s // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d // left, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + +def test_floordiv_pd_index() -> None: + """Test pd.Series[pd.Timedelta] // pandas Indexes""" + b = pd.Index([True]) + i = pd.Index([2]) + f = pd.Index([1.5]) + c = pd.Index([1.7j]) + s, d = pd.Index([datetime(2025, 9, 24)]), pd.Index([timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left // f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left // s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // d, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d // left, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.floordiv(i), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(left.floordiv(f), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + +def test_floordiv_pd_series() -> None: + """Test pd.Series[pd.Timedelta] // pandas Series""" + b = pd.Series([True]) + i = pd.Series([2]) + f = pd.Series([1.5]) + c = pd.Series([1.7j]) + s, d = pd.Series([datetime(2025, 9, 24)]), pd.Series([timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left // b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left // f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left // c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left // s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left // d, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s // left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d // left, "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.floordiv(i), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(left.floordiv(f), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + if TYPE_CHECKING_INVALID_USAGE: + left.floordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.floordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.floordiv(d), "pd.Series[int]"), pd.Series, np.integer) + + if TYPE_CHECKING_INVALID_USAGE: + left.rfloordiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rfloordiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rfloordiv(d), "pd.Series[int]"), pd.Series, np.integer) diff --git a/tests/series/arithmetic/timedelta/test_mul.py b/tests/series/arithmetic/timedelta/test_mul.py new file mode 100644 index 000000000..8f83ca19e --- /dev/null +++ b/tests/series/arithmetic/timedelta/test_mul.py @@ -0,0 +1,228 @@ +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + PD_LTE_23, + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([pd.Timedelta(1, "s")]) # left operand + + +def test_mul_py_scalar() -> None: + """Test pd.Series[pd.Timedelta] * Python native scalars""" + b, i, f, c = True, 1, 1.0, 1j + + # pandas-dev/pandas#62316 + if PD_LTE_23: + check(assert_type(left * b, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _0 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check(assert_type(b * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(i * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(f * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = c * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check( + assert_type(left.mul(b), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check(assert_type(left.mul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.mul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.mul(c) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + + if PD_LTE_23: + check( + assert_type(left.rmul(b), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check(assert_type(left.rmul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.rmul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rmul(c) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_mul_py_sequence() -> None: + """Test pd.Series[pd.Timedelta] * Python native sequences""" + b, i, f, c = [True], [2], [1.5], [1.7j] + + # pandas-dev/pandas#62316 + if PD_LTE_23: + check(assert_type(left * b, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _0 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check(assert_type(b * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(i * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(f * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = c * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check( + assert_type(left.mul(b), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check(assert_type(left.mul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.mul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.mul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + if PD_LTE_23: + check( + assert_type(left.rmul(b), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check(assert_type(left.rmul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.rmul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rmul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_mul_numpy_array() -> None: + """Test pd.Series[pd.Timedelta] * numpy arrays""" + b = np.array([True], np.bool_) + i = np.array([2], np.int64) + f = np.array([1.5], np.float64) + c = np.array([1.7j], np.complex128) + + # pandas-dev/pandas#62316 + if PD_LTE_23: + check(assert_type(left * b, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left * c, Never) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rmul__` cannot override. At runtime, they return + # `Series` with the correct element type. + if PD_LTE_23: + check(assert_type(b * left, "npt.NDArray[np.bool_]"), pd.Series, pd.Timedelta) + check(assert_type(i * left, "npt.NDArray[np.int64]"), pd.Series, pd.Timedelta) + check(assert_type(f * left, "npt.NDArray[np.float64]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + # We made it Never, but numpy takes over + assert_type(c * left, "npt.NDArray[np.complex128]") + + if PD_LTE_23: + check( + assert_type(left.mul(b), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check(assert_type(left.mul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.mul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.mul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + if PD_LTE_23: + check( + assert_type(left.rmul(b), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check(assert_type(left.rmul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.rmul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rmul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_mul_pd_index() -> None: + """Test pd.Series[pd.Timedelta] * pandas Indexes""" + b = pd.Index([True]) + i = pd.Index([2]) + f = pd.Index([1.5]) + c = pd.Index([1.7j]) + + # pandas-dev/pandas#62316 + if PD_LTE_23: + check(assert_type(left * b, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _0 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check(assert_type(b * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(i * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(f * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = c * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check( + assert_type(left.mul(b), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check(assert_type(left.mul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.mul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.mul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + if PD_LTE_23: + check( + assert_type(left.rmul(b), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check(assert_type(left.rmul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.rmul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rmul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_mul_pd_series() -> None: + """Test pd.Series[pd.Timedelta] * pandas Series""" + b = pd.Series([True]) + i = pd.Series([2]) + f = pd.Series([1.5]) + c = pd.Series([1.7j]) + + # pandas-dev/pandas#62316 + if PD_LTE_23: + check(assert_type(left * b, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left * f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _0 = left * c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check(assert_type(b * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(i * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(f * left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = c * left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if PD_LTE_23: + check( + assert_type(left.mul(b), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check(assert_type(left.mul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.mul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.mul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + if PD_LTE_23: + check( + assert_type(left.rmul(b), "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check(assert_type(left.rmul(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.rmul(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rmul(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] diff --git a/tests/series/arithmetic/timedelta/test_sub.py b/tests/series/arithmetic/timedelta/test_sub.py new file mode 100644 index 000000000..c50abed21 --- /dev/null +++ b/tests/series/arithmetic/timedelta/test_sub.py @@ -0,0 +1,163 @@ +from datetime import ( + datetime, + timedelta, +) + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([pd.Timedelta(1, "s")]) # left operand + + +def test_sub_py_scalar() -> None: + """Test pd.Series[pd.Timedelta] - Python native scalars""" + s = datetime(2025, 8, 20) + d = timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s - left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_numpy_scalar() -> None: + """Test pd.Series[pd.Timedelta] - numpy scalars""" + s = np.datetime64("2025-08-20") + d = np.timedelta64(1, "s") + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s - left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_pd_scalar() -> None: + """Test pd.Series[pd.Timedelta] - pandas scalars""" + s = pd.Timestamp("2025-08-20") + d = pd.Timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s - left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_py_sequence() -> None: + """Test pd.Series[pd.Timedelta] - Python native sequences""" + s = [datetime(2025, 8, 20)] + d = [timedelta(seconds=1)] + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + # Series[Timedelta] - Sequence[timedelta] should work, see pandas-dev/pandas#62353 + _a = left - d # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + _1 = s - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _b = d - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_numpy_array() -> None: + """Test pd.Series[pd.Timedelta] - numpy arrays""" + s = np.array([np.datetime64("2025-08-20")], np.datetime64) + d = np.array([np.timedelta64(1, "s")], np.timedelta64) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left - s, Never) + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rsub__` cannot override. At runtime, they return + # `Series`. + check(assert_type(s - left, "npt.NDArray[np.datetime64]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "npt.NDArray[np.timedelta64]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_pd_index() -> None: + """Test pd.Series[pd.Timedelta] - pandas Indexes""" + s = pd.Index([pd.Timestamp("2025-08-20")]) + d = pd.Index([pd.Timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s - left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + +def test_sub_pd_series() -> None: + """Test pd.Series[pd.Timedelta] - pandas Series""" + s = pd.Series([pd.Timestamp("2025-08-20")]) + d = pd.Series([pd.Timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left - s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left - d, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(s - left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(d - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + left.sub(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.sub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + check(assert_type(left.rsub(d), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) diff --git a/tests/series/arithmetic/timedelta/test_truediv.py b/tests/series/arithmetic/timedelta/test_truediv.py new file mode 100644 index 000000000..1c8a59864 --- /dev/null +++ b/tests/series/arithmetic/timedelta/test_truediv.py @@ -0,0 +1,367 @@ +from datetime import ( + datetime, + timedelta, +) +from typing import Any + +import numpy as np +from numpy import typing as npt # noqa: F401 +import pandas as pd +from typing_extensions import ( + Never, + assert_type, +) + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, +) + +left = pd.Series([pd.Timedelta(1, "s")]) # left operand + + +def test_truediv_py_scalar() -> None: + """Test pd.Series[pd.Timedelta] / Python native scalars""" + b, i, f, c = True, 1, 1.0, 1j + s, d = datetime(2025, 9, 24), timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left / f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left / c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left / s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / d, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d / left, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.truediv(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left.truediv(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.div(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.div(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(i) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(f) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(c) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(i) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(f) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(c) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) + + +def test_truediv_py_sequence() -> None: + """Test pd.Series[pd.Timedelta] / Python native sequences""" + b, i, f, c = [True], [2], [1.5], [1.7j] + s, d = [datetime(2025, 9, 24)], [timedelta(seconds=1)] + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left / f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left / c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left / s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / d, "pd.Series[float]"), pd.Series, float) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d / left, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.truediv(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left.truediv(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.div(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.div(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) + + +def test_truediv_numpy_array() -> None: + """Test pd.Series[pd.Timedelta] / numpy arrays""" + b = np.array([True], np.bool_) + i = np.array([2], np.int64) + f = np.array([1.5], np.float64) + c = np.array([1.7j], np.complex128) + s = np.array([datetime(2025, 9, 24)], np.datetime64) + d = np.array([timedelta(seconds=1)], np.timedelta64) + + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left / b, Never) + check(assert_type(left / i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left / f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + assert_type(left / c, Never) + assert_type(left / s, Never) + check(assert_type(left / d, "pd.Series[float]"), pd.Series, np.floating) + + # `numpy` typing gives the corresponding `ndarray`s in the static type + # checking, where our `__rtruediv__` cannot override. At runtime, they lead to + # errors or pd.Series. + if TYPE_CHECKING_INVALID_USAGE: + assert_type(b / left, "npt.NDArray[np.float64]") + assert_type(i / left, "npt.NDArray[np.float64]") + assert_type(f / left, "npt.NDArray[np.float64]") + assert_type(c / left, "npt.NDArray[np.complex128]") + assert_type(s / left, Any) + check(assert_type(d / left, "npt.NDArray[np.float64]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.truediv(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left.truediv(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.div(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.div(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) + + +def test_truediv_pd_scalar() -> None: + """Test pd.Series[pd.Timedelta] / pandas scalars""" + s, d = pd.Timestamp(2025, 9, 24), pd.Timedelta(seconds=1) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / d, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + _1 = s / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d / left, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(s) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) + + +def test_truediv_pd_index() -> None: + """Test pd.Series[pd.Timedelta] / pandas Indexes""" + b = pd.Index([True]) + i = pd.Index([2]) + f = pd.Index([1.5]) + c = pd.Index([1.7j]) + s, d = pd.Index([datetime(2025, 9, 24)]), pd.Index([timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left / f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left / c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left / s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / d, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d / left, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.truediv(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left.truediv(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.div(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.div(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) + + +def test_truediv_pd_series() -> None: + """Test pd.Series[pd.Timedelta] / pandas Series""" + b = pd.Series([True]) + i = pd.Series([2]) + f = pd.Series([1.5]) + c = pd.Series([1.7j]) + s, d = pd.Series([datetime(2025, 9, 24)]), pd.Series([timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left / b # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / i, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left / f, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _1 = left / c # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _2 = left / s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left / d, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + _3 = b / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _4 = i / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _5 = f / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _6 = c / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + _7 = s / left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d / left, "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check( + assert_type(left.truediv(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(left.truediv(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + if TYPE_CHECKING_INVALID_USAGE: + left.truediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.truediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.truediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.div(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(i), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left.div(f), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.div(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.div(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.div(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rtruediv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rtruediv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rtruediv(d), "pd.Series[float]"), pd.Series, np.floating) + + if TYPE_CHECKING_INVALID_USAGE: + left.rdiv(b) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(i) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(f) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(c) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + left.rdiv(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.rdiv(d), "pd.Series[float]"), pd.Series, np.floating) diff --git a/tests/series/arithmetic/timestamp/test_add.py b/tests/series/arithmetic/timestamp/test_add.py index 7e308b4f6..3efdffe82 100644 --- a/tests/series/arithmetic/timestamp/test_add.py +++ b/tests/series/arithmetic/timestamp/test_add.py @@ -86,7 +86,7 @@ def test_add_pd_scalar() -> None: def test_add_py_sequence() -> None: - """Test pd.Series[pd.Timestamp] + Python native sequence""" + """Test pd.Series[pd.Timestamp] + Python native sequences""" s = [datetime(2025, 8, 20)] d = [timedelta(seconds=1)] @@ -100,15 +100,15 @@ def test_add_py_sequence() -> None: if TYPE_CHECKING_INVALID_USAGE: left.add(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] - left.add(d) + check(assert_type(left.add(d), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) if TYPE_CHECKING_INVALID_USAGE: left.radd(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] - left.radd(d) + check(assert_type(left.radd(d), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) def test_add_numpy_array() -> None: - """Test pd.Series[pd.Timestamp] + numpy array""" + """Test pd.Series[pd.Timestamp] + numpy arrays""" s = np.array([np.datetime64("2025-08-20")], np.datetime64) d = np.array([np.timedelta64(1, "s")], np.timedelta64) @@ -134,6 +134,28 @@ def test_add_numpy_array() -> None: check(assert_type(left.radd(d), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) +def test_add_pd_index() -> None: + """Test pd.Series[pd.Timestamp] + pandas Indexes""" + s = pd.Index([pd.Timestamp("2025-08-20")]) + d = pd.Index([pd.Timedelta(seconds=1)]) + + if TYPE_CHECKING_INVALID_USAGE: + _0 = left + s # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(left + d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + if TYPE_CHECKING_INVALID_USAGE: + _1 = s + left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + check(assert_type(d + left, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + if TYPE_CHECKING_INVALID_USAGE: + left.add(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.add(d), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + if TYPE_CHECKING_INVALID_USAGE: + left.radd(s) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + check(assert_type(left.radd(d), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + def test_add_pd_series() -> None: """Test pd.Series[pd.Timestamp] + pandas Series""" s = pd.Series([pd.Timestamp("2025-08-20")]) diff --git a/tests/series/arithmetic/timestamp/test_sub.py b/tests/series/arithmetic/timestamp/test_sub.py index 182d836fc..c680e30eb 100644 --- a/tests/series/arithmetic/timestamp/test_sub.py +++ b/tests/series/arithmetic/timestamp/test_sub.py @@ -2,7 +2,6 @@ datetime, timedelta, ) -from typing import TYPE_CHECKING import numpy as np from numpy import typing as npt # noqa: F401 @@ -14,9 +13,6 @@ check, ) -if TYPE_CHECKING: - from pandas.core.series import TimedeltaSeries # noqa: F401 - left = pd.Series([pd.Timestamp(2025, 8, 20)]) # left operand @@ -25,17 +21,17 @@ def test_sub_py_scalar() -> None: s = datetime(2025, 8, 20) d = timedelta(seconds=1) - check(assert_type(left - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(s - left, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(s - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: _ = d - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - check(assert_type(left.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(left.rsub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.rsub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: left.rsub(d) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] @@ -45,17 +41,17 @@ def test_sub_numpy_scalar() -> None: s = np.datetime64("2025-08-20") d = np.timedelta64(1, "s") - check(assert_type(left - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(s - left, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(s - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: _ = d - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - check(assert_type(left.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(left.rsub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.rsub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: left.rsub(d) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] @@ -65,23 +61,23 @@ def test_sub_pd_scalar() -> None: s = pd.Timestamp("2025-08-20") d = pd.Timedelta(seconds=1) - check(assert_type(left - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(s - left, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(s - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: _ = d - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - check(assert_type(left.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(left.rsub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.rsub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: left.rsub(d) # type: ignore[call-overload] # pyright: ignore[reportArgumentType,reportCallIssue] def test_sub_py_sequence() -> None: - """Test pd.Series[pd.Timestamp] - Python native sequence""" + """Test pd.Series[pd.Timestamp] - Python native sequences""" s = [datetime(2025, 8, 20)] d = [timedelta(seconds=1)] @@ -103,11 +99,11 @@ def test_sub_py_sequence() -> None: def test_sub_numpy_array() -> None: - """Test pd.Series[pd.Timestamp] - numpy array""" + """Test pd.Series[pd.Timestamp] - numpy arrays""" s = np.array([np.datetime64("2025-08-20")], np.datetime64) d = np.array([np.timedelta64(1, "s")], np.timedelta64) - check(assert_type(left - s, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) # `numpy` typing gives the corresponding `ndarray`s in the static type @@ -117,10 +113,30 @@ def test_sub_numpy_array() -> None: if TYPE_CHECKING_INVALID_USAGE: assert_type(d - left, "npt.NDArray[np.timedelta64]") - check(assert_type(left.sub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + check(assert_type(left.rsub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + left.rsub(d) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] + + +def test_sub_pd_index() -> None: + """Test pd.Series[pd.Timestamp] - pandas Indexes""" + s = pd.Index([pd.Timestamp("2025-08-20")]) + d = pd.Index([pd.Timedelta(seconds=1)]) + + check(assert_type(left - s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + check(assert_type(s - left, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + if TYPE_CHECKING_INVALID_USAGE: + _ = d - left # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + + check(assert_type(left.sub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check(assert_type(left - d, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type(left.rsub(s), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(left.rsub(s), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) if TYPE_CHECKING_INVALID_USAGE: left.rsub(d) # type: ignore[arg-type] # pyright: ignore[reportArgumentType,reportCallIssue] diff --git a/tests/series/test_agg.py b/tests/series/test_agg.py new file mode 100644 index 000000000..bd1d2ec21 --- /dev/null +++ b/tests/series/test_agg.py @@ -0,0 +1,83 @@ +import numpy as np +import pandas as pd +from typing_extensions import assert_type + +from tests import ( + TYPE_CHECKING_INVALID_USAGE, + check, + pytest_warns_bounded, +) + + +def test_agg_any_float() -> None: + series = pd.DataFrame({"A": [1.0, float("nan"), 2.0]})["A"] + check(assert_type(series.mean(), float), np.float64) + check(assert_type(series.median(), float), np.float64) + check(assert_type(series.std(), float), np.float64) + + +def test_agg_bool() -> None: + series = pd.Series([True, False, True]) + check(assert_type(series.mean(), float), np.float64) + check(assert_type(series.median(), float), np.float64) + check(assert_type(series.std(), float), np.float64) + + +def test_agg_int() -> None: + series = pd.Series([3, 1, 2]) + check(assert_type(series.mean(), float), np.float64) + check(assert_type(series.median(), float), np.float64) + check(assert_type(series.std(), float), np.float64) + + +def test_agg_float() -> None: + series = pd.Series([3.0, float("nan"), 2.0]) + check(assert_type(series.mean(), float), np.float64) + check(assert_type(series.median(), float), np.float64) + check(assert_type(series.std(), float), np.float64) + + +def test_agg_complex() -> None: + series = pd.Series([3j, 3 + 4j, 2j]) + check(assert_type(series, "pd.Series[complex]"), pd.Series, np.complex128) + + check(assert_type(series.mean(), complex), np.complex128) + with pytest_warns_bounded( + np.exceptions.ComplexWarning, + r"Casting complex values to real discards the imaginary part", + ): + check(assert_type(series.median(), float), np.float64) + with ( + pytest_warns_bounded( + np.exceptions.ComplexWarning, + r"Casting complex values to real discards the imaginary part", + ), + pytest_warns_bounded(RuntimeWarning, r"invalid value encountered in sqrt"), + ): + check(assert_type(series.std(), np.float64), np.float64) + + +def test_agg_str() -> None: + series = pd.Series(["1", "a", "🐼"]) + if TYPE_CHECKING_INVALID_USAGE: + series.mean() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue] + series.median() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue] + series.std() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue] + + +def test_agg_ts() -> None: + series = pd.Series(pd.to_datetime(["2025-09-18", "2025-09-18", "2025-09-18"])) + check(assert_type(series, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) + + check(assert_type(series.mean(), pd.Timestamp), pd.Timestamp) + check(assert_type(series.median(), pd.Timestamp), pd.Timestamp) + check(assert_type(series.std(), pd.Timedelta), pd.Timedelta) + + +def test_agg_td() -> None: + series = pd.Series(pd.to_timedelta(["1 days", "2 days", "3 days"])) + check(assert_type(series, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + check(assert_type(series.mean(), pd.Timedelta), pd.Timedelta) + check(assert_type(series.median(), pd.Timedelta), pd.Timedelta) + check(assert_type(series.std(), pd.Timedelta), pd.Timedelta) diff --git a/tests/series/test_cumul.py b/tests/series/test_cumul.py index 5c1980a46..fd98cf243 100644 --- a/tests/series/test_cumul.py +++ b/tests/series/test_cumul.py @@ -49,3 +49,11 @@ def test_cumul_ts() -> None: if TYPE_CHECKING_INVALID_USAGE: series.cumprod() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue] + + +def test_cumul_td() -> None: + series = pd.Series(pd.to_timedelta(["1 days", "2 days", "3 days"])) + check(assert_type(series, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) + + if TYPE_CHECKING_INVALID_USAGE: + series.cumprod() # type: ignore[misc] # pyright: ignore[reportAttributeAccessIssue] diff --git a/tests/series/test_series.py b/tests/series/test_series.py index e5b2f5465..8160e0baa 100644 --- a/tests/series/test_series.py +++ b/tests/series/test_series.py @@ -72,10 +72,7 @@ ) if TYPE_CHECKING: - from pandas.core.series import ( - OffsetSeries, - TimedeltaSeries, - ) + from pandas.core.series import OffsetSeries from tests import ( BooleanDtypeArg, @@ -93,7 +90,6 @@ ) else: - TimedeltaSeries: TypeAlias = pd.Series OffsetSeries: TypeAlias = pd.Series if not PD_LTE_23: @@ -499,7 +495,6 @@ def test_types_rank() -> None: def test_types_mean() -> None: s = pd.Series([1, 2, 3, np.nan]) - check(assert_type(s.mean(), float), float) check( assert_type(s.groupby(level=0).mean(), "pd.Series[float]"), pd.Series, @@ -511,7 +506,6 @@ def test_types_mean() -> None: def test_types_median() -> None: s = pd.Series([1, 2, 3, np.nan]) - check(assert_type(s.median(), float), float) check( assert_type(s.groupby(level=0).median(), "pd.Series[float]"), pd.Series, @@ -745,7 +739,6 @@ def test_types_var() -> None: def test_types_std() -> None: s = pd.Series([-10, 2, 3, 10]) - s.std() s.std(axis=0, ddof=1) s.std(skipna=True, numeric_only=False) @@ -2817,58 +2810,58 @@ def test_astype_timestamp(cast_arg: TimestampDtypeArg, target_type: type) -> Non @pytest.mark.parametrize("cast_arg, target_type", ASTYPE_TIMEDELTA_ARGS, ids=repr) def test_astype_timedelta(cast_arg: TimedeltaDtypeArg, target_type: type) -> None: s = pd.Series([1, 2, 3]) - check(s.astype(cast_arg), TimedeltaSeries, target_type) + check(s.astype(cast_arg), pd.Series, target_type) if TYPE_CHECKING: - assert_type(s.astype("timedelta64[Y]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[M]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[W]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[D]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[h]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[m]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[s]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[ms]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[us]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[μs]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[ns]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[ps]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[fs]"), "TimedeltaSeries") - assert_type(s.astype("timedelta64[as]"), "TimedeltaSeries") + assert_type(s.astype("timedelta64[Y]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[M]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[W]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[D]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[h]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[m]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[s]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[ms]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[us]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[μs]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[ns]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[ps]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[fs]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("timedelta64[as]"), "pd.Series[pd.Timedelta]") # numpy timedelta64 type codes - assert_type(s.astype("m8[Y]"), "TimedeltaSeries") - assert_type(s.astype("m8[M]"), "TimedeltaSeries") - assert_type(s.astype("m8[W]"), "TimedeltaSeries") - assert_type(s.astype("m8[D]"), "TimedeltaSeries") - assert_type(s.astype("m8[h]"), "TimedeltaSeries") - assert_type(s.astype("m8[m]"), "TimedeltaSeries") - assert_type(s.astype("m8[s]"), "TimedeltaSeries") - assert_type(s.astype("m8[ms]"), "TimedeltaSeries") - assert_type(s.astype("m8[us]"), "TimedeltaSeries") - assert_type(s.astype("m8[μs]"), "TimedeltaSeries") - assert_type(s.astype("m8[ns]"), "TimedeltaSeries") - assert_type(s.astype("m8[ps]"), "TimedeltaSeries") - assert_type(s.astype("m8[fs]"), "TimedeltaSeries") - assert_type(s.astype("m8[as]"), "TimedeltaSeries") + assert_type(s.astype("m8[Y]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[M]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[W]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[D]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[h]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[m]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[s]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[ms]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[us]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[μs]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[ns]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[ps]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[fs]"), "pd.Series[pd.Timedelta]") + assert_type(s.astype("m8[as]"), "pd.Series[pd.Timedelta]") # numpy timedelta64 type codes - assert_type(s.astype(" 3, pd.NA), "pd.Series[int]"), pd.Series, np.float64) -def test_timedelta_div() -> None: - series = pd.Series([pd.Timedelta(days=1)]) - delta = datetime.timedelta(1) - - check(assert_type(series / delta, "pd.Series[float]"), pd.Series, float) - check(assert_type(series / [delta], "pd.Series[float]"), pd.Series, float) - check(assert_type(series / 1, "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(series / [1], "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(series // delta, "pd.Series[int]"), pd.Series, np.longlong) - check(assert_type(series // [delta], "pd.Series[int]"), pd.Series, int) - check(assert_type(series // 1, "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type(series // [1], "TimedeltaSeries"), pd.Series, pd.Timedelta) - - check(assert_type(delta / series, "pd.Series[float]"), pd.Series, float) - check(assert_type([delta] / series, "pd.Series[float]"), pd.Series, float) - check(assert_type(delta // series, "pd.Series[int]"), pd.Series, np.longlong) - check(assert_type([delta] // series, "pd.Series[int]"), pd.Series, np.signedinteger) - - if TYPE_CHECKING_INVALID_USAGE: - 1 / series # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - [1] / series # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - 1 // series # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - [1] // series # type: ignore[operator] # pyright: ignore[reportOperatorIssue] - - def test_rank() -> None: check( assert_type(pd.Series([1, 2]).rank(), "pd.Series[float]"), pd.Series, np.float64 @@ -3321,7 +3289,7 @@ def test_timedeltaseries_operators() -> None: pd.Timestamp, ) check( - assert_type(series + datetime.timedelta(1), TimedeltaSeries), + assert_type(series + datetime.timedelta(1), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) @@ -3331,7 +3299,7 @@ def test_timedeltaseries_operators() -> None: pd.Timestamp, ) check( - assert_type(series - datetime.timedelta(1), TimedeltaSeries), + assert_type(series - datetime.timedelta(1), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) @@ -3483,7 +3451,7 @@ def test_diff() -> None: pd.Series( [datetime.datetime.now().date(), datetime.datetime.now().date()] ).diff(), - "TimedeltaSeries", + "pd.Series[pd.Timedelta]", ), pd.Series, pd.Timedelta, @@ -3492,7 +3460,7 @@ def test_diff() -> None: # timestamp -> timedelta times = pd.Series([pd.Timestamp(0), pd.Timestamp(1)]) check( - assert_type(times.diff(), "TimedeltaSeries"), + assert_type(times.diff(), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, index_to_check_for_type=-1, @@ -3500,7 +3468,8 @@ def test_diff() -> None: # timedelta -> timedelta64 check( assert_type( - pd.Series([pd.Timedelta(0), pd.Timedelta(1)]).diff(), "TimedeltaSeries" + pd.Series([pd.Timedelta(0), pd.Timedelta(1)]).diff(), + "pd.Series[pd.Timedelta]", ), pd.Series, pd.Timedelta, @@ -3581,22 +3550,22 @@ def test_operator_constistency() -> None: # created for #748 s = pd.Series([1, 2, 3]) check( - assert_type(s * np.timedelta64(1, "s"), "TimedeltaSeries"), + assert_type(s * np.timedelta64(1, "s"), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) check( - assert_type(np.timedelta64(1, "s") * s, "TimedeltaSeries"), + assert_type(np.timedelta64(1, "s") * s, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) check( - assert_type(s.mul(np.timedelta64(1, "s")), "TimedeltaSeries"), + assert_type(s.mul(np.timedelta64(1, "s")), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) check( - assert_type(s.rmul(np.timedelta64(1, "s")), "TimedeltaSeries"), + assert_type(s.rmul(np.timedelta64(1, "s")), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta, ) @@ -3892,7 +3861,7 @@ def test_series_items() -> None: def test_cumsum_timedelta() -> None: s = pd.Series(pd.to_timedelta([1, 2, 3], "h")) - check(assert_type(s.cumsum(), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(s.cumsum(), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) check( assert_type(pd.Timestamp(0) + s.cumsum(), "pd.Series[pd.Timestamp]"), pd.Series, diff --git a/tests/test_natype.py b/tests/test_natype.py index e4a02055f..bef677d66 100644 --- a/tests/test_natype.py +++ b/tests/test_natype.py @@ -43,7 +43,7 @@ def test_arithmetic() -> None: # __rmul__ check(assert_type(s_int * na, pd.Series), pd.Series) - check(assert_type(idx_int * na, "pd.Index[int]"), pd.Index) + check(assert_type(idx_int * na, pd.Index), pd.Index) check(assert_type(1 * na, NAType), NAType) # __matmul__ diff --git a/tests/test_scalars.py b/tests/test_scalars.py index 9a8f95035..e537f0d0c 100644 --- a/tests/test_scalars.py +++ b/tests/test_scalars.py @@ -42,10 +42,8 @@ from pandas.core.series import ( OffsetSeries, PeriodSeries, - TimedeltaSeries, ) else: - TimedeltaSeries: TypeAlias = pd.Series PeriodSeries: TypeAlias = pd.Series OffsetSeries: TypeAlias = pd.Series @@ -538,7 +536,9 @@ def test_timedelta_add_sub() -> None: check(assert_type(td + as_timedelta64, pd.Timedelta), pd.Timedelta) check(assert_type(td + as_timedelta_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check( - assert_type(td + as_timedelta_series, TimedeltaSeries), pd.Series, pd.Timedelta + assert_type(td + as_timedelta_series, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, ) check(assert_type(td + as_period_index, pd.PeriodIndex), pd.PeriodIndex) check(assert_type(td + as_datetime_index, pd.DatetimeIndex), pd.DatetimeIndex) @@ -578,7 +578,9 @@ def test_timedelta_add_sub() -> None: ) check(assert_type(as_timedelta_index + td, pd.TimedeltaIndex), pd.TimedeltaIndex) check( - assert_type(as_timedelta_series + td, TimedeltaSeries), pd.Series, pd.Timedelta + assert_type(as_timedelta_series + td, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, ) check(assert_type(as_period_index + td, pd.PeriodIndex), pd.PeriodIndex) check(assert_type(as_datetime_index + td, pd.DatetimeIndex), pd.DatetimeIndex) @@ -611,7 +613,9 @@ def test_timedelta_add_sub() -> None: check(assert_type(td - as_timedelta64, pd.Timedelta), pd.Timedelta) check(assert_type(td - as_timedelta_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check( - assert_type(td - as_timedelta_series, TimedeltaSeries), pd.Series, pd.Timedelta + assert_type(td - as_timedelta_series, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, ) check( assert_type(td - as_ndarray_td64, npt.NDArray[np.timedelta64]), @@ -643,7 +647,9 @@ def test_timedelta_add_sub() -> None: ) check(assert_type(as_timedelta_index - td, pd.TimedeltaIndex), pd.TimedeltaIndex) check( - assert_type(as_timedelta_series - td, TimedeltaSeries), pd.Series, pd.Timedelta + assert_type(as_timedelta_series - td, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, ) check(assert_type(as_period_index - td, pd.PeriodIndex), pd.PeriodIndex) check(assert_type(as_datetime_index - td, pd.DatetimeIndex), pd.DatetimeIndex) @@ -697,8 +703,16 @@ def test_timedelta_mul_div() -> None: np.ndarray, np.timedelta64, ) - check(assert_type(td * mp_series_int, TimedeltaSeries), pd.Series, pd.Timedelta) - check(assert_type(td * md_series_float, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(td * mp_series_int, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(td * md_series_float, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) check(assert_type(td * md_int64_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check(assert_type(td * md_float_index, pd.TimedeltaIndex), pd.TimedeltaIndex) @@ -714,8 +728,16 @@ def test_timedelta_mul_div() -> None: np.ndarray, np.timedelta64, ) - check(assert_type(mp_series_int * td, TimedeltaSeries), pd.Series, pd.Timedelta) - check(assert_type(md_series_float * td, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(mp_series_int * td, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(md_series_float * td, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) check(assert_type(md_int64_index * td, pd.TimedeltaIndex), pd.TimedeltaIndex) check(assert_type(md_float_index * td, pd.TimedeltaIndex), pd.TimedeltaIndex) @@ -733,8 +755,16 @@ def test_timedelta_mul_div() -> None: np.ndarray, np.timedelta64, ) - check(assert_type(td // mp_series_int, TimedeltaSeries), pd.Series, pd.Timedelta) - check(assert_type(td // md_series_float, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(td // mp_series_int, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(td // md_series_float, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) check(assert_type(td // md_int64_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check(assert_type(td // md_float_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check( @@ -771,8 +801,16 @@ def test_timedelta_mul_div() -> None: np.ndarray, np.timedelta64, ) - check(assert_type(td / mp_series_int, TimedeltaSeries), pd.Series, pd.Timedelta) - check(assert_type(td / md_series_float, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(td / mp_series_int, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) + check( + assert_type(td / md_series_float, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) check(assert_type(td / md_int64_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check(assert_type(td / md_float_index, pd.TimedeltaIndex), pd.TimedeltaIndex) check(assert_type(td / md_timedelta_series, "pd.Series[float]"), pd.Series, float) @@ -813,8 +851,14 @@ def test_timedelta_mod_abs_unary() -> None: ) int_series = pd.Series([1, 2, 3], dtype=int) float_series = pd.Series([1.2, 2.2, 3.4], dtype=float) - check(assert_type(td % int_series, TimedeltaSeries), pd.Series, pd.Timedelta) - check(assert_type(td % float_series, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(td % int_series, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) + check( + assert_type(td % float_series, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) check(assert_type(td % i_idx, pd.TimedeltaIndex), pd.TimedeltaIndex) check( @@ -1143,7 +1187,11 @@ def test_timestamp_add_sub() -> None: as_timedelta_index = pd.to_timedelta([1, 2, 3], unit="D") as_timedelta_series = pd.Series(as_timedelta_index) - check(assert_type(as_timedelta_series, TimedeltaSeries), pd.Series, pd.Timedelta) + check( + assert_type(as_timedelta_series, "pd.Series[pd.Timedelta]"), + pd.Series, + pd.Timedelta, + ) as_np_ndarray_td64 = np_td64_arr check(assert_type(ts + as_pd_timedelta, pd.Timestamp), pd.Timestamp) @@ -1811,7 +1859,7 @@ def test_period_add_subtract() -> None: as_period = pd.Period("2012-1-1", freq="D") scale = 24 * 60 * 60 * 10**9 as_td_series = pd.Series(pd.timedelta_range(scale, scale, freq="D")) - check(assert_type(as_td_series, TimedeltaSeries), pd.Series, pd.Timedelta) + check(assert_type(as_td_series, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) as_period_series = pd.Series(as_period_index) check(assert_type(as_period_series, PeriodSeries), pd.Series, pd.Period) as_timedelta_idx = pd.timedelta_range(scale, scale, freq="D") diff --git a/tests/test_timefuncs.py b/tests/test_timefuncs.py index a52c38329..354be303b 100644 --- a/tests/test_timefuncs.py +++ b/tests/test_timefuncs.py @@ -50,12 +50,11 @@ ) if TYPE_CHECKING: - from pandas.core.series import ( + from pandas.core.series import ( # noqa: F401 IntervalSeries, OffsetSeries, + PeriodSeries, ) - from pandas.core.series import PeriodSeries # noqa: F401 - from pandas.core.series import TimedeltaSeries # noqa: F401 if not PD_LTE_23: from pandas.errors import Pandas4Warning # type: ignore[attr-defined] # pyright: ignore # isort: skip @@ -188,34 +187,9 @@ def test_timedelta_series_string() -> None: def test_timestamp_timedelta_series_arithmetic() -> None: ts1 = pd.to_datetime(pd.Series(["2022-03-05", "2022-03-06"])) check(assert_type(ts1.iloc[0], pd.Timestamp), pd.Timestamp) - td1 = pd.to_timedelta([2, 3], "seconds") - ts2 = pd.to_datetime(pd.Series(["2022-03-08", "2022-03-10"])) - r1 = ts1 - ts2 - check(assert_type(r1, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) - r2 = r1 / td1 - check(assert_type(r2, "pd.Series[float]"), pd.Series, float) - r3 = r1 - td1 - check(assert_type(r3, "TimedeltaSeries"), pd.Series, pd.Timedelta) - r4 = pd.Timedelta(5, "days") / r1 - check(assert_type(r4, "pd.Series[float]"), pd.Series, float) sb = pd.Series([1, 2]) == pd.Series([1, 3]) check(assert_type(sb, "pd.Series[bool]"), pd.Series, np.bool_) - # https://github.com/pandas-dev/pandas/issues/62316 - if PD_LTE_23: - r5 = sb * r1 - check(assert_type(r5, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) - - r6 = r1 * 4 - check(assert_type(r6, "TimedeltaSeries"), pd.Series, pd.Timedelta) - - tsp1 = pd.Timestamp("2022-03-05") - dt1 = dt.datetime(2022, 9, 1, 12, 5, 30) - r7 = ts1 - tsp1 - check(assert_type(r7, "TimedeltaSeries"), pd.Series, pd.Timedelta) - r8 = ts1 - dt1 - check(assert_type(r8, "TimedeltaSeries"), pd.Series, pd.Timedelta) - def test_timestamp_dateoffset_arithmetic() -> None: ts = pd.Timestamp("2022-03-18") @@ -304,11 +278,7 @@ def test_timestamp_plus_timedelta_series() -> None: def test_timedelta_series_mult() -> None: df = pd.DataFrame({"x": [1, 3, 5], "y": [2, 2, 6]}) std = (df["x"] < df["y"]) * pd.Timedelta(10, "minutes") - check( - assert_type(std, "TimedeltaSeries"), - pd.Series, - pd.Timedelta, - ) + check(assert_type(std, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) def test_timedelta_series_sum() -> None: @@ -332,9 +302,9 @@ def test_fail_on_adding_two_timestamps() -> None: s1 = pd.Series(pd.to_datetime(["2022-05-01", "2022-06-01"])) s2 = pd.Series(pd.to_datetime(["2022-05-15", "2022-06-15"])) if TYPE_CHECKING_INVALID_USAGE: - ssum: pd.Series = s1 + s2 # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + ssum = s1 + s2 # type: ignore[operator] # pyright: ignore[reportOperatorIssue] ts = pd.Timestamp("2022-06-30") - tsum: pd.Series = s1 + ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue] + tsum = s1 + ts # type: ignore[operator] # pyright: ignore[reportOperatorIssue] def test_dtindex_tzinfo() -> None: @@ -369,16 +339,14 @@ def test_to_datetime_nat() -> None: ) check( assert_type( - pd.to_datetime("2021-03-01", errors="coerce"), - "pd.Timestamp | NaTType", + pd.to_datetime("2021-03-01", errors="coerce"), "pd.Timestamp | NaTType" ), pd.Timestamp, ) check( assert_type( - pd.to_datetime("not a date", errors="coerce"), - "pd.Timestamp | NaTType", + pd.to_datetime("not a date", errors="coerce"), "pd.Timestamp | NaTType" ), NaTType, ) @@ -437,6 +405,7 @@ def test_series_dt_accessors() -> None: dt.datetime, ) s0_local = s0.dt.tz_localize("UTC") + check(assert_type(s0_local, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) check( assert_type(s0_local, "pd.Series[pd.Timestamp]"), pd.Series, @@ -579,7 +548,9 @@ def test_series_dt_accessors() -> None: i2 = pd.timedelta_range(start="1 day", periods=10) check(assert_type(i2, pd.TimedeltaIndex), pd.TimedeltaIndex) - check(assert_type(i2.to_series(), "TimedeltaSeries"), pd.Series, pd.Timedelta) + check( + assert_type(i2.to_series(), "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta + ) s2 = pd.Series(i2) @@ -630,7 +601,7 @@ def test_series_dt_accessors() -> None: pd.Timedelta, ) - # Checks for general Series other than Series[Timestamp] and TimedeltaSeries + # Checks for general Series other than Series[Timestamp] and Series[Timedelta] s4 = pd.Series([pd.Timestamp("2024-01-01"), pd.Timestamp("2024-01-02")]) @@ -657,10 +628,7 @@ def test_series_dt_accessors() -> None: pd.Timestamp, ) - s5 = cast( - "pd.Series[pd.Timedelta]", - pd.Series([pd.Timedelta("1 day"), pd.Timedelta("2 days")]), - ) + s5 = pd.Series([pd.Timedelta("1 day"), pd.Timedelta("2 days")]) check(assert_type(s5.dt.unit, TimeUnit), str) check( @@ -1073,11 +1041,21 @@ def test_series_types_to_numpy() -> None: np_1darray, dtype=np.int64, ) + check( + assert_type(td_s.to_numpy(dtype=np.timedelta64), np_1darray[np.timedelta64]), + np_1darray, + dtype=np.timedelta64, + ) check( assert_type(ts_s.to_numpy(dtype=np.int64), np_1darray[np.int64]), np_1darray, dtype=np.int64, ) + check( + assert_type(ts_s.to_numpy(dtype=np.datetime64), np_1darray[np.datetime64]), + np_1darray, + dtype=np.datetime64, + ) check( assert_type(p_s.to_numpy(dtype=np.int64), np_1darray[np.int64]), np_1darray, @@ -1249,8 +1227,8 @@ def test_to_timedelta_scalar() -> None: def test_to_timedelta_series() -> None: s = pd.Series([10, 20, 30, 40]) s2 = pd.Series(["10ms", "20ms", "30ms"]) - check(assert_type(pd.to_timedelta(s, "ms"), "TimedeltaSeries"), pd.Series) - check(assert_type(pd.to_timedelta(s2), "TimedeltaSeries"), pd.Series) + check(assert_type(pd.to_timedelta(s, "ms"), "pd.Series[pd.Timedelta]"), pd.Series) + check(assert_type(pd.to_timedelta(s2), "pd.Series[pd.Timedelta]"), pd.Series) def test_to_timedelta_index() -> None: @@ -1594,9 +1572,7 @@ def test_to_datetime_array() -> None: pd.DatetimeIndex, ) pd.to_datetime( - pd.Index([2451544.5, 2451545.5, 2451546.5]), - unit="D", - origin="julian", + pd.Index([2451544.5, 2451545.5, 2451546.5]), unit="D", origin="julian" ) check( assert_type( @@ -1732,18 +1708,12 @@ def test_timedelta64_and_arithmatic_operator() -> None: s1 = pd.Series(data=pd.date_range("1/1/2020", "2/1/2020")) s2 = pd.Series(data=pd.date_range("1/1/2021", "2/1/2021")) s3 = s2 - s1 - check(assert_type(s3, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) td1 = pd.Timedelta(1, "D") - check(assert_type(s2 - td1, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) # GH 758 s4 = s1.astype(object) check(assert_type(s4 - td1, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) td = np.timedelta64(1, "D") - check(assert_type((s1 - td), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type((s1 + td), "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) - check(assert_type((s3 - td), "TimedeltaSeries"), pd.Series, pd.Timedelta) - check(assert_type((s3 + td), "TimedeltaSeries"), pd.Series, pd.Timedelta) check(assert_type((s3 / td), "pd.Series[float]"), pd.Series, float) if TYPE_CHECKING_INVALID_USAGE: r1 = s1 * td # type: ignore[operator] # pyright: ignore[reportOperatorIssue] @@ -1758,24 +1728,6 @@ def test_timedeltaseries_add_timestampseries() -> None: check(assert_type(plus, "pd.Series[pd.Timestamp]"), pd.Series, pd.Timestamp) -def test_mean_median_std() -> None: - s = pd.Series([pd.Timedelta("1 ns"), pd.Timedelta("2 ns"), pd.Timedelta("3 ns")]) - check(assert_type(s.mean(), pd.Timedelta), pd.Timedelta) - check(assert_type(s.median(), pd.Timedelta), pd.Timedelta) - check(assert_type(s.std(), pd.Timedelta), pd.Timedelta) - - s2 = pd.Series( - [ - pd.Timestamp("2021-01-01"), - pd.Timestamp("2021-01-02"), - pd.Timestamp("2021-01-03"), - ] - ) - check(assert_type(s2.mean(), pd.Timestamp), pd.Timestamp) - check(assert_type(s2.median(), pd.Timestamp), pd.Timestamp) - check(assert_type(s2.std(), pd.Timedelta), pd.Timedelta) - - def test_timestamp_strptime_fails(): if TYPE_CHECKING_INVALID_USAGE: assert_never( @@ -1835,31 +1787,19 @@ def test_dateoffset_weekday() -> None: def test_date_range_unit(): check( - assert_type( - pd.date_range("1/1/2022", "2/1/2022", unit="s"), - pd.DatetimeIndex, - ), + assert_type(pd.date_range("1/1/2022", "2/1/2022", unit="s"), pd.DatetimeIndex), pd.DatetimeIndex, ) check( - assert_type( - pd.date_range("1/1/2022", "2/1/2022", unit="ms"), - pd.DatetimeIndex, - ), + assert_type(pd.date_range("1/1/2022", "2/1/2022", unit="ms"), pd.DatetimeIndex), pd.DatetimeIndex, ) check( - assert_type( - pd.date_range("1/1/2022", "2/1/2022", unit="us"), - pd.DatetimeIndex, - ), + assert_type(pd.date_range("1/1/2022", "2/1/2022", unit="us"), pd.DatetimeIndex), pd.DatetimeIndex, ) check( - assert_type( - pd.date_range("1/1/2022", "2/1/2022", unit="ns"), - pd.DatetimeIndex, - ), + assert_type(pd.date_range("1/1/2022", "2/1/2022", unit="ns"), pd.DatetimeIndex), pd.DatetimeIndex, ) @@ -1989,7 +1929,7 @@ def test_timestamp_sub_series() -> None: ts1 = pd.to_datetime(pd.Series(["2022-03-05", "2022-03-06"])) one_ts = ts1.iloc[0] check(assert_type(ts1.iloc[0], pd.Timestamp), pd.Timestamp) - check(assert_type(one_ts - ts1, "TimedeltaSeries"), pd.Series, pd.Timedelta) + check(assert_type(one_ts - ts1, "pd.Series[pd.Timedelta]"), pd.Series, pd.Timedelta) def test_creating_date_range() -> None: