diff --git a/pandas-stubs/_libs/tslibs/period.pyi b/pandas-stubs/_libs/tslibs/period.pyi index 0d90395ca..38df197eb 100644 --- a/pandas-stubs/_libs/tslibs/period.pyi +++ b/pandas-stubs/_libs/tslibs/period.pyi @@ -16,9 +16,12 @@ from pandas import ( from typing_extensions import Self from pandas._libs.tslibs import NaTType -from pandas._libs.tslibs.offsets import BaseOffset +from pandas._libs.tslibs.offsets import ( + BaseOffset, +) from pandas._libs.tslibs.timestamps import Timestamp from pandas._typing import ( + PeriodFrequency, ShapeT, np_1darray, np_ndarray, @@ -63,7 +66,7 @@ class Period(PeriodMixin): value: ( Period | str | datetime.datetime | datetime.date | Timestamp | None ) = ..., - freq: str | BaseOffset | None = ..., + freq: PeriodFrequency | None = None, ordinal: int | None = ..., year: int | None = ..., month: int | None = ..., @@ -223,12 +226,12 @@ class Period(PeriodMixin): def day_of_year(self) -> int: ... @property def day_of_week(self) -> int: ... - def asfreq(self, freq: str | BaseOffset, how: _PeriodFreqHow = "end") -> Period: ... + def asfreq(self, freq: PeriodFrequency, how: _PeriodFreqHow = "end") -> Period: ... @classmethod - def now(cls, freq: str | BaseOffset = ...) -> Period: ... + def now(cls, freq: PeriodFrequency | None = None) -> Period: ... def strftime(self, fmt: str) -> str: ... def to_timestamp( self, - freq: str | BaseOffset | None = ..., + freq: PeriodFrequency | None = None, how: _PeriodToTimestampHow = "S", ) -> Timestamp: ... diff --git a/pandas-stubs/_libs/tslibs/timedeltas.pyi b/pandas-stubs/_libs/tslibs/timedeltas.pyi index 2e98b8276..4b98f70aa 100644 --- a/pandas-stubs/_libs/tslibs/timedeltas.pyi +++ b/pandas-stubs/_libs/tslibs/timedeltas.pyi @@ -24,12 +24,12 @@ from pandas import ( from typing_extensions import Self from pandas._libs.tslibs import ( - BaseOffset, NaTType, ) from pandas._libs.tslibs.period import Period from pandas._libs.tslibs.timestamps import Timestamp from pandas._typing import ( + Frequency, Just, ShapeT, TimeUnit, @@ -132,9 +132,9 @@ class Timedelta(timedelta): @property def asm8(self) -> np.timedelta64: ... # TODO: round/floor/ceil could return NaT? - def round(self, freq: str | BaseOffset) -> Self: ... - def floor(self, freq: str | BaseOffset) -> Self: ... - def ceil(self, freq: str | BaseOffset) -> Self: ... + def round(self, freq: Frequency) -> Self: ... + def floor(self, freq: Frequency) -> Self: ... + def ceil(self, freq: Frequency) -> Self: ... @property def resolution_string(self) -> str: ... # Override due to more types supported than timedelta diff --git a/pandas-stubs/_libs/tslibs/timestamps.pyi b/pandas-stubs/_libs/tslibs/timestamps.pyi index 0998b2dca..09599b36e 100644 --- a/pandas-stubs/_libs/tslibs/timestamps.pyi +++ b/pandas-stubs/_libs/tslibs/timestamps.pyi @@ -30,12 +30,12 @@ from typing_extensions import ( ) from pandas._libs.tslibs import ( - BaseOffset, Period, Tick, Timedelta, ) from pandas._typing import ( + PeriodFrequency, ShapeT, TimestampNonexistent, TimeUnit, @@ -282,7 +282,7 @@ class Timestamp(datetime, SupportsIndex): def is_year_end(self) -> bool: ... def to_pydatetime(self, warn: bool = ...) -> datetime: ... def to_datetime64(self) -> np.datetime64: ... - def to_period(self, freq: BaseOffset | str | None = ...) -> Period: ... + def to_period(self, freq: PeriodFrequency | None = ...) -> Period: ... def to_julian_date(self) -> np.float64: ... @property def asm8(self) -> np.datetime64: ... diff --git a/pandas-stubs/_typing.pyi b/pandas-stubs/_typing.pyi index 8392880df..2c72f8d56 100644 --- a/pandas-stubs/_typing.pyi +++ b/pandas-stubs/_typing.pyi @@ -56,6 +56,19 @@ from pandas.core.dtypes.dtypes import ( ) from pandas.io.formats.format import EngFormatter +from pandas.tseries.offsets import ( + Day, + Hour, + Micro, + Milli, + Minute, + MonthEnd, + Nano, + QuarterEnd, + Second, + Week, + YearEnd, +) P = ParamSpec("P") @@ -162,6 +175,20 @@ Suffixes: TypeAlias = tuple[str | None, str | None] | list[str | None] Ordered: TypeAlias = bool | None JSONSerializable: TypeAlias = PythonScalar | list | dict Frequency: TypeAlias = str | BaseOffset +PeriodFrequency: TypeAlias = ( + str + | Day + | Hour + | Minute + | Second + | Milli + | Micro + | Nano + | YearEnd + | QuarterEnd + | MonthEnd + | Week +) Axes: TypeAlias = ListLike RandomState: TypeAlias = ( diff --git a/pandas-stubs/core/arrays/period.pyi b/pandas-stubs/core/arrays/period.pyi index 0e64035d8..bf4a8a5be 100644 --- a/pandas-stubs/core/arrays/period.pyi +++ b/pandas-stubs/core/arrays/period.pyi @@ -8,6 +8,7 @@ from pandas._libs.tslibs import Timestamp from pandas._libs.tslibs.period import Period from pandas._typing import ( NpDtype, + PeriodFrequency, np_1darray, ) @@ -42,6 +43,8 @@ class PeriodArray(DatetimeLikeArrayMixin, DatelikeOps): def start_time(self) -> Timestamp: ... @property def end_time(self) -> Timestamp: ... - def to_timestamp(self, freq: str | None = ..., how: str = ...) -> Timestamp: ... + def to_timestamp( + self, freq: PeriodFrequency | None = None, how: str = ... + ) -> Timestamp: ... def asfreq(self, freq: str | None = ..., how: str = "E") -> Period: ... def astype(self, dtype, copy: bool = True): ... diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index e330064ee..7e4f5c2ff 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -79,7 +79,6 @@ from pandas._libs.lib import _NoDefaultDoNotUse from pandas._libs.missing import NAType from pandas._libs.tslibs import BaseOffset from pandas._libs.tslibs.nattype import NaTType -from pandas._libs.tslibs.offsets import DateOffset from pandas._typing import ( S2, AggFuncTypeBase, @@ -104,6 +103,7 @@ from pandas._typing import ( FillnaOptions, FloatFormatType, FormattersType, + Frequency, GroupByObjectNonScalar, HashableT, HashableT1, @@ -133,6 +133,7 @@ from pandas._typing import ( NDFrameT, NsmallestNlargestKeep, ParquetEngine, + PeriodFrequency, QuantileInterpolation, RandomState, ReadBuffer, @@ -1681,14 +1682,14 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): ) -> Self: ... def to_timestamp( self, - freq=..., + freq: PeriodFrequency | None = None, how: ToTimestampHow = ..., axis: Axis = 0, copy: _bool = True, ) -> Self: ... def to_period( self, - freq: _str | None = None, + freq: PeriodFrequency | None = None, axis: Axis = 0, copy: _bool = True, ) -> Self: ... @@ -2222,7 +2223,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): self, periods: int = 1, fill_method: None = None, - freq: DateOffset | dt.timedelta | _str | None = ..., + freq: Frequency | dt.timedelta | None = ..., fill_value: Scalar | NAType | None = ..., ) -> Self: ... def pop(self, item: _str) -> Series: ... @@ -2339,7 +2340,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): @overload def rolling( self, - window: int | str | dt.timedelta | BaseOffset | BaseIndexer, + window: int | Frequency | dt.timedelta | BaseIndexer, min_periods: int | None = ..., center: _bool = ..., on: Hashable | None = ..., @@ -2353,7 +2354,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): @overload def rolling( self, - window: int | str | dt.timedelta | BaseOffset | BaseIndexer, + window: int | Frequency | dt.timedelta | BaseIndexer, min_periods: int | None = ..., center: _bool = ..., on: Hashable | None = ..., diff --git a/pandas-stubs/core/groupby/groupby.pyi b/pandas-stubs/core/groupby/groupby.pyi index fe8bbc744..7576320ba 100644 --- a/pandas-stubs/core/groupby/groupby.pyi +++ b/pandas-stubs/core/groupby/groupby.pyi @@ -315,7 +315,7 @@ class GroupBy(BaseGroupBy[NDFrameT]): periods: int = ..., fill_method: Literal["bfill", "ffill"] | None | _NoDefaultDoNotUse = ..., limit: int | None | _NoDefaultDoNotUse = ..., - freq=..., + freq: Frequency | None = None, axis: Axis | _NoDefaultDoNotUse = ..., ) -> NDFrameT: ... @final diff --git a/pandas-stubs/core/indexes/accessors.pyi b/pandas-stubs/core/indexes/accessors.pyi index 0cc058af7..b87872d78 100644 --- a/pandas-stubs/core/indexes/accessors.pyi +++ b/pandas-stubs/core/indexes/accessors.pyi @@ -34,11 +34,12 @@ from typing_extensions import Never from pandas._libs.interval import Interval from pandas._libs.tslibs import BaseOffset -from pandas._libs.tslibs.offsets import DateOffset from pandas._libs.tslibs.period import Period from pandas._libs.tslibs.timedeltas import Timedelta from pandas._libs.tslibs.timestamps import Timestamp from pandas._typing import ( + Frequency, + PeriodFrequency, TimeAmbiguous, TimeNonexistent, TimestampConvention, @@ -178,7 +179,7 @@ _DTTimestampTimedeltaReturnType = TypeVar( class _DatetimeRoundingMethods(Generic[_DTTimestampTimedeltaReturnType]): def round( self, - freq: str | BaseOffset | None, + freq: Frequency | None, ambiguous: Literal["raise", "infer", "NaT"] | bool | np_ndarray_bool = ..., nonexistent: ( Literal["shift_forward", "shift_backward", "NaT", "raise"] @@ -188,7 +189,7 @@ class _DatetimeRoundingMethods(Generic[_DTTimestampTimedeltaReturnType]): ) -> _DTTimestampTimedeltaReturnType: ... def floor( self, - freq: str | BaseOffset | None, + freq: Frequency | None, ambiguous: Literal["raise", "infer", "NaT"] | bool | np_ndarray_bool = ..., nonexistent: ( Literal["shift_forward", "shift_backward", "NaT", "raise"] @@ -198,7 +199,7 @@ class _DatetimeRoundingMethods(Generic[_DTTimestampTimedeltaReturnType]): ) -> _DTTimestampTimedeltaReturnType: ... def ceil( self, - freq: str | BaseOffset | None, + freq: Frequency | None, ambiguous: Literal["raise", "infer", "NaT"] | bool | np_ndarray_bool = ..., nonexistent: ( Literal["shift_forward", "shift_backward", "NaT", "raise"] @@ -225,7 +226,7 @@ class _DatetimeLikeNoTZMethods( ], ): def to_period( - self, freq: str | BaseOffset | None = ... + self, freq: PeriodFrequency | None = None ) -> _DTToPeriodReturnType: ... def tz_localize( self, @@ -357,12 +358,12 @@ class _PeriodProperties( def strftime(self, date_format: str) -> _PeriodStrReturnTypes: ... def to_timestamp( self, - freq: str | DateOffset | None = ..., + freq: PeriodFrequency | None = None, how: TimestampConvention = ..., ) -> _PeriodDTAReturnTypes: ... def asfreq( self, - freq: str | DateOffset | None = ..., + freq: PeriodFrequency | None = None, how: Literal["E", "END", "FINISH", "S", "START", "BEGIN"] = ..., ) -> _PeriodPAReturnTypes: ... diff --git a/pandas-stubs/core/indexes/datetimes.pyi b/pandas-stubs/core/indexes/datetimes.pyi index 94710415a..4d30a8460 100644 --- a/pandas-stubs/core/indexes/datetimes.pyi +++ b/pandas-stubs/core/indexes/datetimes.pyi @@ -16,7 +16,6 @@ import numpy as np from pandas import ( DataFrame, Index, - Timedelta, TimedeltaIndex, Timestamp, ) @@ -25,7 +24,6 @@ from pandas.core.indexes.datetimelike import DatetimeTimedeltaMixin from pandas.core.series import Series from typing_extensions import Self -from pandas._libs.tslibs.offsets import DateOffset from pandas._typing import ( AxesData, DateAndDatetimeLike, @@ -99,14 +97,14 @@ class DatetimeIndex( @property def dtype(self) -> np.dtype | DatetimeTZDtype: ... def shift( - self, periods: int = 1, freq: DateOffset | Timedelta | str | None = None + self, periods: int = 1, freq: Frequency | timedelta | None = None ) -> Self: ... @overload def date_range( start: str | DateAndDatetimeLike, end: str | DateAndDatetimeLike, - freq: str | timedelta | Timedelta | BaseOffset | None = None, + freq: Frequency | timedelta | None = None, tz: TimeZones = None, normalize: bool = False, name: Hashable | None = None, @@ -129,7 +127,7 @@ def date_range( start: str | DateAndDatetimeLike, *, periods: int, - freq: str | timedelta | Timedelta | BaseOffset | None = None, + freq: Frequency | timedelta | None = None, tz: TimeZones = None, normalize: bool = False, name: Hashable | None = None, @@ -141,7 +139,7 @@ def date_range( *, end: str | DateAndDatetimeLike, periods: int, - freq: str | timedelta | Timedelta | BaseOffset | None = None, + freq: Frequency | timedelta | None = None, tz: TimeZones = None, normalize: bool = False, name: Hashable | None = None, @@ -153,7 +151,7 @@ def bdate_range( start: str | DateAndDatetimeLike | None = ..., end: str | DateAndDatetimeLike | None = ..., periods: int | None = ..., - freq: str | timedelta | Timedelta | BaseOffset = ..., + freq: Frequency | timedelta = ..., tz: TimeZones = ..., normalize: bool = ..., name: Hashable | None = ..., @@ -167,7 +165,7 @@ def bdate_range( end: str | DateAndDatetimeLike | None = ..., periods: int | None = ..., *, - freq: str | timedelta | Timedelta | BaseOffset, + freq: Frequency | timedelta, tz: TimeZones = ..., normalize: bool = ..., name: Hashable | None = ..., diff --git a/pandas-stubs/core/indexes/interval.pyi b/pandas-stubs/core/indexes/interval.pyi index d53d5bba2..628d588ec 100644 --- a/pandas-stubs/core/indexes/interval.pyi +++ b/pandas-stubs/core/indexes/interval.pyi @@ -19,11 +19,11 @@ from pandas._libs.interval import ( Interval as Interval, IntervalMixin, ) -from pandas._libs.tslibs.offsets import BaseOffset from pandas._typing import ( DatetimeLike, DtypeArg, FillnaOptions, + Frequency, IntervalClosedType, IntervalT, Label, @@ -329,7 +329,7 @@ def interval_range( start: _TimestampLike, end: _TimestampLike | None = ..., periods: int | None = ..., - freq: str | BaseOffset | pd.Timedelta | dt.timedelta | None = ..., + freq: Frequency | dt.timedelta | None = ..., name: Hashable = ..., closed: IntervalClosedType = ..., ) -> IntervalIndex[Interval[pd.Timestamp]]: ... @@ -339,7 +339,7 @@ def interval_range( start: None = ..., end: _TimestampLike, periods: int | None = ..., - freq: str | BaseOffset | pd.Timedelta | dt.timedelta | None = ..., + freq: Frequency | dt.timedelta | None = ..., name: Hashable = ..., closed: IntervalClosedType = ..., ) -> IntervalIndex[Interval[pd.Timestamp]]: ... @@ -348,7 +348,7 @@ def interval_range( start: _TimedeltaLike, end: _TimedeltaLike | None = ..., periods: int | None = ..., - freq: str | BaseOffset | pd.Timedelta | dt.timedelta | None = ..., + freq: Frequency | dt.timedelta | None = ..., name: Hashable = ..., closed: IntervalClosedType = ..., ) -> IntervalIndex[Interval[pd.Timedelta]]: ... @@ -358,7 +358,7 @@ def interval_range( start: None = ..., end: _TimedeltaLike, periods: int | None = ..., - freq: str | BaseOffset | pd.Timedelta | dt.timedelta | None = ..., + freq: Frequency | dt.timedelta | None = ..., name: Hashable = ..., closed: IntervalClosedType = ..., ) -> IntervalIndex[Interval[pd.Timedelta]]: ... diff --git a/pandas-stubs/core/indexes/timedeltas.pyi b/pandas-stubs/core/indexes/timedeltas.pyi index 93b74f5a6..16a865ddc 100644 --- a/pandas-stubs/core/indexes/timedeltas.pyi +++ b/pandas-stubs/core/indexes/timedeltas.pyi @@ -11,7 +11,6 @@ from typing import ( import numpy as np from pandas import ( - DateOffset, Index, Period, ) @@ -29,6 +28,7 @@ from pandas._libs import Timedelta from pandas._libs.tslibs import BaseOffset from pandas._typing import ( AxesData, + Frequency, Just, TimedeltaConvertibleTypes, np_ndarray_anyint, @@ -48,7 +48,7 @@ class TimedeltaIndex( data: ( Sequence[dt.timedelta | Timedelta | np.timedelta64 | float] | AxesData ) = ..., - freq: str | BaseOffset = ..., + freq: Frequency = ..., closed: object = ..., dtype: Literal[" Series[Timedelta]: ... - def shift(self, periods: int = 1, freq=...) -> Self: ... + def shift( + self, periods: int = 1, freq: Frequency | dt.timedelta | None = None + ) -> Self: ... @overload def timedelta_range( start: TimedeltaConvertibleTypes, end: TimedeltaConvertibleTypes, *, - freq: str | DateOffset | Timedelta | dt.timedelta | None = None, + freq: Frequency | Timedelta | dt.timedelta | None = None, name: Hashable | None = None, closed: Literal["left", "right"] | None = None, unit: None | str = ..., @@ -157,7 +159,7 @@ def timedelta_range( *, end: TimedeltaConvertibleTypes, periods: int, - freq: str | DateOffset | Timedelta | dt.timedelta | None = None, + freq: Frequency | Timedelta | dt.timedelta | None = None, name: Hashable | None = None, closed: Literal["left", "right"] | None = None, unit: None | str = ..., @@ -167,7 +169,7 @@ def timedelta_range( start: TimedeltaConvertibleTypes, *, periods: int, - freq: str | DateOffset | Timedelta | dt.timedelta | None = None, + freq: Frequency | Timedelta | dt.timedelta | None = None, name: Hashable | None = None, closed: Literal["left", "right"] | None = None, unit: None | str = ..., diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 815b949e1..396ec084d 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -110,7 +110,6 @@ from pandas._libs.lib import _NoDefaultDoNotUse from pandas._libs.missing import NAType from pandas._libs.tslibs import BaseOffset from pandas._libs.tslibs.nattype import NaTType -from pandas._libs.tslibs.offsets import DateOffset from pandas._typing import ( S1, S1_CO, @@ -146,6 +145,7 @@ from pandas._typing import ( FillnaOptions, FloatDtypeArg, FloatFormatType, + Frequency, GenericT, GenericT_co, GroupByObjectNonScalar, @@ -170,6 +170,7 @@ from pandas._typing import ( NaPosition, NsmallestNlargestKeep, ObjectDtypeArg, + PeriodFrequency, QuantileInterpolation, RandomState, ReindexMethod, @@ -1240,11 +1241,13 @@ class Series(IndexOpsMixin[S1], NDFrame): ) -> Series[S1]: ... def to_timestamp( self, - freq=..., + freq: PeriodFrequency | None = None, how: ToTimestampHow = "start", copy: _bool = True, ) -> Series[S1]: ... - def to_period(self, freq: _str | None = None, copy: _bool = True) -> DataFrame: ... + def to_period( + self, freq: PeriodFrequency | None = None, copy: _bool = True + ) -> DataFrame: ... @property def str( self, @@ -1497,7 +1500,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @final def asfreq( self, - freq: DateOffset | _str, + freq: Frequency, method: FillnaOptions | None = None, how: Literal["start", "end"] | None = None, normalize: _bool = False, @@ -1647,7 +1650,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, periods: int = 1, fill_method: None = None, - freq: DateOffset | timedelta | _str | None = None, + freq: Frequency | timedelta | None = None, ) -> Series[float]: ... @final def first_valid_index(self) -> Scalar: ... @@ -4538,7 +4541,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rolling( self, - window: int | _str | timedelta | BaseOffset | BaseIndexer, + window: int | Frequency | timedelta | BaseIndexer, min_periods: int | None = ..., center: _bool = ..., on: _str | None = ..., @@ -4551,7 +4554,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rolling( self, - window: int | _str | timedelta | BaseOffset | BaseIndexer, + window: int | Frequency | timedelta | BaseIndexer, min_periods: int | None = ..., center: _bool = ..., on: _str | None = ..., diff --git a/pandas-stubs/tseries/frequencies.pyi b/pandas-stubs/tseries/frequencies.pyi index a1f8360d1..4c1494758 100644 --- a/pandas-stubs/tseries/frequencies.pyi +++ b/pandas-stubs/tseries/frequencies.pyi @@ -8,10 +8,10 @@ from pandas import ( from pandas._typing import Frequency -from pandas.tseries.offsets import DateOffset +from pandas.tseries.offsets import BaseOffset @overload def to_offset(freq: None, is_period: bool = ...) -> None: ... @overload -def to_offset(freq: Frequency, is_period: bool = ...) -> DateOffset: ... +def to_offset(freq: Frequency, is_period: bool = ...) -> BaseOffset: ... def infer_freq(index: Series | DatetimeIndex | TimedeltaIndex) -> str | None: ... diff --git a/tests/test_timefuncs.py b/tests/test_timefuncs.py index 881863afc..7753f9850 100644 --- a/tests/test_timefuncs.py +++ b/tests/test_timefuncs.py @@ -1867,7 +1867,7 @@ def test_DatetimeIndex_sub_timedelta() -> None: def test_to_offset() -> None: check(assert_type(to_offset(None), None), type(None)) - check(assert_type(to_offset("1D"), DateOffset), DateOffset) + check(assert_type(to_offset("1D"), BaseOffset), BaseOffset) def test_timestamp_sub_series() -> None: diff --git a/tests/test_windowing.py b/tests/test_windowing.py index c8b041ce5..8abd91f9d 100644 --- a/tests/test_windowing.py +++ b/tests/test_windowing.py @@ -14,7 +14,7 @@ ) from typing_extensions import assert_type -from pandas._libs.tslibs.offsets import DateOffset +from pandas._libs.tslibs.offsets import BaseOffset from tests import ( PD_LTE_23, @@ -58,7 +58,7 @@ def test_rolling_basic_math() -> None: def test_rolling_datetime_index() -> None: offset_1d = to_offset("1D") - check(assert_type(offset_1d, DateOffset), DateOffset) + check(assert_type(offset_1d, BaseOffset), BaseOffset) check(assert_type(DF_DTI.rolling("1D"), "Rolling[DataFrame]"), Rolling, DataFrame) check(