diff --git a/pandas/_libs/tslibs/__init__.py b/pandas/_libs/tslibs/__init__.py index 965adc82df676..25e2d8ba477e0 100644 --- a/pandas/_libs/tslibs/__init__.py +++ b/pandas/_libs/tslibs/__init__.py @@ -14,12 +14,14 @@ "ints_to_pytimedelta", "Timestamp", "tz_convert_single", + "to_offset", ] from .conversion import localize_pydatetime from .nattype import NaT, NaTType, iNaT, is_null_datetimelike, nat_strings from .np_datetime import OutOfBoundsDatetime +from .offsets import to_offset from .period import IncompatibleFrequency, Period from .resolution import Resolution from .timedeltas import Timedelta, delta_to_nanoseconds, ints_to_pytimedelta diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index da8e9b4bfdd4e..e2ecb6c343b7a 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -14,6 +14,7 @@ Timestamp, delta_to_nanoseconds, iNaT, + to_offset, ) from pandas._libs.tslibs.timestamps import ( RoundTo, @@ -427,7 +428,7 @@ def _with_freq(self, freq): else: # As an internal method, we can ensure this assertion always holds assert freq == "infer" - freq = frequencies.to_offset(self.inferred_freq) + freq = to_offset(self.inferred_freq) arr = self.view() arr._freq = freq @@ -1081,7 +1082,7 @@ def freq(self): @freq.setter def freq(self, value): if value is not None: - value = frequencies.to_offset(value) + value = to_offset(value) self._validate_frequency(self, value) self._freq = value @@ -1367,7 +1368,7 @@ def _time_shift(self, periods, freq=None): """ if freq is not None and freq != self.freq: if isinstance(freq, str): - freq = frequencies.to_offset(freq) + freq = to_offset(freq) offset = periods * freq result = self + offset return result @@ -1779,7 +1780,7 @@ def maybe_infer_freq(freq): if not isinstance(freq, DateOffset): # if a passed freq is None, don't infer automatically if freq != "infer": - freq = frequencies.to_offset(freq) + freq = to_offset(freq) else: freq_infer = True freq = None diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index f11f3ad974b37..8e4ae339ae53e 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -15,6 +15,7 @@ iNaT, resolution as libresolution, timezones, + to_offset, tzconversion, ) from pandas.errors import PerformanceWarning @@ -46,7 +47,7 @@ from pandas.core.arrays._ranges import generate_regular_range import pandas.core.common as com -from pandas.tseries.frequencies import get_period_alias, to_offset +from pandas.tseries.frequencies import get_period_alias from pandas.tseries.offsets import BDay, Day, Tick _midnight = time(0, 0) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 3d4b42de01810..1b8a0b2780a7d 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -7,9 +7,12 @@ from pandas._libs.tslibs import ( NaT, NaTType, + Timedelta, + delta_to_nanoseconds, frequencies as libfrequencies, iNaT, period as libperiod, + to_offset, ) from pandas._libs.tslibs.fields import isleapyear_arr from pandas._libs.tslibs.offsets import Tick, delta_to_tick @@ -20,7 +23,6 @@ get_period_field_arr, period_asfreq_arr, ) -from pandas._libs.tslibs.timedeltas import Timedelta, delta_to_nanoseconds from pandas._typing import AnyArrayLike from pandas.util._decorators import cache_readonly @@ -45,7 +47,6 @@ from pandas.core.arrays import datetimelike as dtl import pandas.core.common as com -from pandas.tseries import frequencies from pandas.tseries.offsets import DateOffset @@ -902,7 +903,7 @@ def validate_dtype_freq(dtype, freq): IncompatibleFrequency : mismatch between dtype and freq """ if freq is not None: - freq = frequencies.to_offset(freq) + freq = to_offset(freq) if dtype is not None: dtype = pandas_dtype(dtype) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 4de105e8be364..f439f07790274 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -4,7 +4,7 @@ import numpy as np from pandas._libs import lib, tslibs -from pandas._libs.tslibs import NaT, Period, Timedelta, Timestamp, iNaT +from pandas._libs.tslibs import NaT, Period, Timedelta, Timestamp, iNaT, to_offset from pandas._libs.tslibs.conversion import precision_from_unit from pandas._libs.tslibs.fields import get_timedelta_field from pandas._libs.tslibs.timedeltas import array_to_timedelta64, parse_timedelta_unit @@ -35,7 +35,6 @@ from pandas.core.construction import extract_array from pandas.core.ops.common import unpack_zerodim_and_defer -from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import Tick diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index ff35876ab2e73..84284c581c9e5 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -20,7 +20,7 @@ import pytz from pandas._libs.interval import Interval -from pandas._libs.tslibs import NaT, Period, Timestamp, timezones +from pandas._libs.tslibs import NaT, Period, Timestamp, timezones, to_offset from pandas._libs.tslibs.offsets import BaseOffset from pandas._typing import DtypeObj, Ordered @@ -925,7 +925,6 @@ def _parse_dtype_strict(cls, freq): m = cls._match.search(freq) if m is not None: freq = m.group("freq") - from pandas.tseries.frequencies import to_offset freq = to_offset(freq) if freq is not None: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 0260f30b9e7e2..e5f5cb232fdd1 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -30,7 +30,8 @@ from pandas._config import config -from pandas._libs import Timestamp, lib +from pandas._libs import lib +from pandas._libs.tslibs import Timestamp, to_offset from pandas._typing import ( Axis, FilePathOrBuffer, @@ -106,7 +107,6 @@ from pandas.io.formats import format as fmt from pandas.io.formats.format import DataFrameFormatter, format_percentiles from pandas.io.formats.printing import pprint_thing -from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import Tick if TYPE_CHECKING: diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 4677faa6b7d24..68c55426294ef 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -6,7 +6,7 @@ import numpy as np from pandas._libs import NaT, Period, Timestamp, index as libindex, lib, tslib -from pandas._libs.tslibs import Resolution, fields, parsing, timezones +from pandas._libs.tslibs import Resolution, fields, parsing, timezones, to_offset from pandas._libs.tslibs.frequencies import get_freq_group from pandas._libs.tslibs.offsets import prefix_mapping from pandas._typing import DtypeObj, Label @@ -30,8 +30,6 @@ from pandas.core.indexes.extension import inherit_names from pandas.core.tools.times import to_time -from pandas.tseries.frequencies import to_offset - def _new_DatetimeIndex(cls, d): """ diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 7d7572973707c..1a59e066879cc 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -7,8 +7,9 @@ from pandas._config import get_option -from pandas._libs import Timedelta, Timestamp, lib +from pandas._libs import lib from pandas._libs.interval import Interval, IntervalMixin, IntervalTree +from pandas._libs.tslibs import Timedelta, Timestamp, to_offset from pandas._typing import AnyArrayLike, Label from pandas.util._decorators import Appender, Substitution, cache_readonly from pandas.util._exceptions import rewrite_exception @@ -55,7 +56,6 @@ from pandas.core.indexes.timedeltas import TimedeltaIndex, timedelta_range from pandas.core.ops import get_op_result_name -from pandas.tseries.frequencies import to_offset from pandas.tseries.offsets import DateOffset _VALID_CLOSED = {"left", "right", "both", "neither"} diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 184fae4b97416..ce3ff17814a25 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -1,6 +1,7 @@ """ implement the TimedeltaIndex """ -from pandas._libs import Timedelta, index as libindex, lib +from pandas._libs import index as libindex, lib +from pandas._libs.tslibs import Timedelta, to_offset from pandas._typing import DtypeObj, Label from pandas.util._decorators import doc @@ -24,8 +25,6 @@ ) from pandas.core.indexes.extension import inherit_names -from pandas.tseries.frequencies import to_offset - @inherit_names( ["__neg__", "__pos__", "__abs__", "total_seconds", "round", "floor", "ceil"] diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 5df80645c2b5d..32e947dc414d2 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -6,8 +6,14 @@ import numpy as np from pandas._libs import lib -from pandas._libs.tslibs import NaT, Period, Timedelta, Timestamp -from pandas._libs.tslibs.period import IncompatibleFrequency +from pandas._libs.tslibs import ( + IncompatibleFrequency, + NaT, + Period, + Timedelta, + Timestamp, + to_offset, +) from pandas._typing import TimedeltaConvertibleTypes, TimestampConvertibleTypes from pandas.compat.numpy import function as nv from pandas.errors import AbstractMethodError @@ -28,7 +34,7 @@ from pandas.core.indexes.period import PeriodIndex, period_range from pandas.core.indexes.timedeltas import TimedeltaIndex, timedelta_range -from pandas.tseries.frequencies import is_subperiod, is_superperiod, to_offset +from pandas.tseries.frequencies import is_subperiod, is_superperiod from pandas.tseries.offsets import DateOffset, Day, Nano, Tick _shared_docs_kwargs: Dict[str, str] = dict() diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index b06128052fa8f..92be2d056cfcb 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -10,6 +10,7 @@ import numpy as np +from pandas._libs.tslibs import to_offset import pandas._libs.window.aggregations as window_aggregations from pandas._typing import Axis, FrameOrSeries, Scalar from pandas.compat._optional import import_optional_dependency @@ -1977,8 +1978,6 @@ def _validate_freq(self): """ Validate & return window frequency. """ - from pandas.tseries.frequencies import to_offset - try: return to_offset(self.window) except (TypeError, ValueError) as err: diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index 631760c547985..d5a390dc34d39 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -5,8 +5,8 @@ import numpy as np +from pandas._libs.tslibs import Period, to_offset from pandas._libs.tslibs.frequencies import FreqGroup, base_and_stride, get_freq_code -from pandas._libs.tslibs.period import Period from pandas.core.dtypes.generic import ( ABCDatetimeIndex, @@ -20,12 +20,7 @@ TimeSeries_DateLocator, TimeSeries_TimedeltaFormatter, ) -from pandas.tseries.frequencies import ( - get_period_alias, - is_subperiod, - is_superperiod, - to_offset, -) +from pandas.tseries.frequencies import get_period_alias, is_subperiod, is_superperiod from pandas.tseries.offsets import DateOffset if TYPE_CHECKING: diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index d206622521816..ccd03e841a40d 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -6,17 +6,15 @@ import numpy as np import pytest -from pandas._libs.tslibs.period import IncompatibleFrequency +from pandas._libs.tslibs import IncompatibleFrequency, Period, Timestamp, to_offset from pandas.errors import PerformanceWarning import pandas as pd -from pandas import Period, PeriodIndex, Series, TimedeltaIndex, Timestamp, period_range +from pandas import PeriodIndex, Series, TimedeltaIndex, period_range import pandas._testing as tm from pandas.core import ops from pandas.core.arrays import TimedeltaArray -from pandas.tseries.frequencies import to_offset - from .common import assert_invalid_comparison # ------------------------------------------------------------------ diff --git a/pandas/tests/indexes/datetimes/test_scalar_compat.py b/pandas/tests/indexes/datetimes/test_scalar_compat.py index e5d1277aed9cd..23dedf6f86a09 100644 --- a/pandas/tests/indexes/datetimes/test_scalar_compat.py +++ b/pandas/tests/indexes/datetimes/test_scalar_compat.py @@ -6,14 +6,12 @@ import numpy as np import pytest -from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime +from pandas._libs.tslibs import OutOfBoundsDatetime, to_offset import pandas as pd from pandas import DatetimeIndex, Timestamp, date_range import pandas._testing as tm -from pandas.tseries.frequencies import to_offset - class TestDatetimeIndexOps: def test_dti_time(self): diff --git a/pandas/tests/scalar/timestamp/test_arithmetic.py b/pandas/tests/scalar/timestamp/test_arithmetic.py index eb9932f9a3a97..954301b979074 100644 --- a/pandas/tests/scalar/timestamp/test_arithmetic.py +++ b/pandas/tests/scalar/timestamp/test_arithmetic.py @@ -3,14 +3,16 @@ import numpy as np import pytest -from pandas.errors import OutOfBoundsDatetime +from pandas._libs.tslibs import ( + OutOfBoundsDatetime, + Timedelta, + Timestamp, + offsets, + to_offset, +) -from pandas import Timedelta, Timestamp import pandas._testing as tm -from pandas.tseries import offsets -from pandas.tseries.frequencies import to_offset - class TestTimestampArithmetic: def test_overflow_offset(self): diff --git a/pandas/tests/scalar/timestamp/test_unary_ops.py b/pandas/tests/scalar/timestamp/test_unary_ops.py index e657559b55d5a..388ff4ea039be 100644 --- a/pandas/tests/scalar/timestamp/test_unary_ops.py +++ b/pandas/tests/scalar/timestamp/test_unary_ops.py @@ -5,15 +5,12 @@ import pytz from pytz import utc -from pandas._libs.tslibs import conversion +from pandas._libs.tslibs import NaT, Timestamp, conversion, to_offset from pandas._libs.tslibs.frequencies import INVALID_FREQ_ERR_MSG import pandas.util._test_decorators as td -from pandas import NaT, Timestamp import pandas._testing as tm -from pandas.tseries.frequencies import to_offset - class TestTimestampUnaryOps: diff --git a/pandas/tests/tseries/frequencies/test_freq_code.py b/pandas/tests/tseries/frequencies/test_freq_code.py index f82d225f0538c..d4eb31168b20e 100644 --- a/pandas/tests/tseries/frequencies/test_freq_code.py +++ b/pandas/tests/tseries/frequencies/test_freq_code.py @@ -1,5 +1,6 @@ import pytest +from pandas._libs.tslibs import to_offset from pandas._libs.tslibs.frequencies import ( FreqGroup, _attrname_to_abbrevs, @@ -10,7 +11,6 @@ ) from pandas._libs.tslibs.resolution import Resolution as _reso -from pandas.tseries.frequencies import to_offset import pandas.tseries.offsets as offsets diff --git a/pandas/tests/tseries/frequencies/test_to_offset.py b/pandas/tests/tseries/frequencies/test_to_offset.py index d3510eaa5c749..04be0e445a3b2 100644 --- a/pandas/tests/tseries/frequencies/test_to_offset.py +++ b/pandas/tests/tseries/frequencies/test_to_offset.py @@ -2,16 +2,13 @@ import pytest -from pandas import Timedelta - -import pandas.tseries.frequencies as frequencies -import pandas.tseries.offsets as offsets +from pandas._libs.tslibs import Timedelta, offsets, to_offset @pytest.mark.parametrize( "freq_input,expected", [ - (frequencies.to_offset("10us"), offsets.Micro(10)), + (to_offset("10us"), offsets.Micro(10)), (offsets.Hour(), offsets.Hour()), ((5, "T"), offsets.Minute(5)), ("2h30min", offsets.Minute(150)), @@ -33,7 +30,7 @@ ], ) def test_to_offset(freq_input, expected): - result = frequencies.to_offset(freq_input) + result = to_offset(freq_input) assert result == expected @@ -41,7 +38,7 @@ def test_to_offset(freq_input, expected): "freqstr,expected", [("-1S", -1), ("-2SM", -2), ("-1SMS", -1), ("-5min10s", -310)] ) def test_to_offset_negative(freqstr, expected): - result = frequencies.to_offset(freqstr) + result = to_offset(freqstr) assert result.n == expected @@ -88,12 +85,12 @@ def test_to_offset_invalid(freqstr): # inputs contain regex special characters. msg = re.escape(f"Invalid frequency: {freqstr}") with pytest.raises(ValueError, match=msg): - frequencies.to_offset(freqstr) + to_offset(freqstr) def test_to_offset_no_evaluate(): with pytest.raises(ValueError, match="Could not evaluate"): - frequencies.to_offset(("", "")) + to_offset(("", "")) @pytest.mark.parametrize( @@ -108,7 +105,7 @@ def test_to_offset_no_evaluate(): ], ) def test_to_offset_whitespace(freqstr, expected): - result = frequencies.to_offset(freqstr) + result = to_offset(freqstr) assert result == expected @@ -116,13 +113,13 @@ def test_to_offset_whitespace(freqstr, expected): "freqstr,expected", [("00H 00T 01S", 1), ("-00H 03T 14S", -194)] ) def test_to_offset_leading_zero(freqstr, expected): - result = frequencies.to_offset(freqstr) + result = to_offset(freqstr) assert result.n == expected @pytest.mark.parametrize("freqstr,expected", [("+1d", 1), ("+2h30min", 150)]) def test_to_offset_leading_plus(freqstr, expected): - result = frequencies.to_offset(freqstr) + result = to_offset(freqstr) assert result.n == expected @@ -135,7 +132,7 @@ def test_to_offset_leading_plus(freqstr, expected): (dict(hours=1, minutes=-10), offsets.Minute(50)), (dict(weeks=1), offsets.Day(7)), (dict(hours=1), offsets.Hour(1)), - (dict(hours=1), frequencies.to_offset("60min")), + (dict(hours=1), to_offset("60min")), (dict(microseconds=1), offsets.Micro(1)), (dict(microseconds=0), offsets.Nano(0)), ], @@ -143,7 +140,7 @@ def test_to_offset_leading_plus(freqstr, expected): def test_to_offset_pd_timedelta(kwargs, expected): # see gh-9064 td = Timedelta(**kwargs) - result = frequencies.to_offset(td) + result = to_offset(td) assert result == expected @@ -164,5 +161,5 @@ def test_to_offset_pd_timedelta(kwargs, expected): ], ) def test_anchored_shortcuts(shortcut, expected): - result = frequencies.to_offset(shortcut) + result = to_offset(shortcut) assert result == expected diff --git a/pandas/tests/tslibs/test_api.py b/pandas/tests/tslibs/test_api.py index 908f9fa699891..bbabfed4cb976 100644 --- a/pandas/tests/tslibs/test_api.py +++ b/pandas/tests/tslibs/test_api.py @@ -40,6 +40,7 @@ def test_namespace(): "ints_to_pytimedelta", "localize_pydatetime", "tz_convert_single", + "to_offset", ] expected = set(submodules + api)