diff --git a/ci/code_checks.sh b/ci/code_checks.sh index a9967dcb8efe6..b3a694de20103 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -504,7 +504,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.Timedelta.to_timedelta64 SA01" \ -i "pandas.Timedelta.total_seconds SA01" \ -i "pandas.Timedelta.view SA01" \ - -i "pandas.TimedeltaIndex PR01" \ -i "pandas.TimedeltaIndex.as_unit RT03,SA01" \ -i "pandas.TimedeltaIndex.ceil SA01" \ -i "pandas.TimedeltaIndex.components SA01" \ diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 4d2381ae1e5e4..5cb8c3c0f54d1 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -195,6 +195,8 @@ Removal of prior version deprecations/changes - :meth:`SeriesGroupBy.agg` no longer pins the name of the group to the input passed to the provided ``func`` (:issue:`51703`) - All arguments except ``name`` in :meth:`Index.rename` are now keyword only (:issue:`56493`) - All arguments except the first ``path``-like argument in IO writers are now keyword only (:issue:`54229`) +- Removed the "closed" and "normalize" keywords in :meth:`DatetimeIndex.__new__` (:issue:`52628`) +- Removed the "closed" and "unit" keywords in :meth:`TimedeltaIndex.__new__` (:issue:`52628`, :issue:`55499`) - All arguments in :meth:`Index.sort_values` are now keyword only (:issue:`56493`) - All arguments in :meth:`Series.to_dict` are now keyword only (:issue:`56493`) - Changed the default value of ``observed`` in :meth:`DataFrame.groupby` and :meth:`Series.groupby` to ``True`` (:issue:`51811`) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 2d773c04b8ea9..cefdc14145d1f 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -28,7 +28,6 @@ cache_readonly, doc, ) -from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.common import is_scalar from pandas.core.dtypes.dtypes import DatetimeTZDtype @@ -150,17 +149,6 @@ class DatetimeIndex(DatetimeTimedeltaMixin): inferred frequency upon creation. tz : pytz.timezone or dateutil.tz.tzfile or datetime.tzinfo or str Set the Timezone of the data. - normalize : bool, default False - Normalize start/end dates to midnight before generating date range. - - .. deprecated:: 2.1.0 - - closed : {'left', 'right'}, optional - Set whether to include `start` and `end` that are on the - boundary. The default includes boundary points on either end. - - .. deprecated:: 2.1.0 - ambiguous : 'infer', bool-ndarray, 'NaT', default 'raise' When clocks moved backward due to DST, ambiguous times may arise. For example in Central European Time (UTC+01), when going from 03:00 @@ -322,8 +310,6 @@ def __new__( data=None, freq: Frequency | lib.NoDefault = lib.no_default, tz=lib.no_default, - normalize: bool | lib.NoDefault = lib.no_default, - closed=lib.no_default, ambiguous: TimeAmbiguous = "raise", dayfirst: bool = False, yearfirst: bool = False, @@ -331,23 +317,6 @@ def __new__( copy: bool = False, name: Hashable | None = None, ) -> Self: - if closed is not lib.no_default: - # GH#52628 - warnings.warn( - f"The 'closed' keyword in {cls.__name__} construction is " - "deprecated and will be removed in a future version.", - FutureWarning, - stacklevel=find_stack_level(), - ) - if normalize is not lib.no_default: - # GH#52628 - warnings.warn( - f"The 'normalize' keyword in {cls.__name__} construction is " - "deprecated and will be removed in a future version.", - FutureWarning, - stacklevel=find_stack_level(), - ) - if is_scalar(data): cls._raise_scalar_data_error(data) diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 6a2c04b0ddf51..8af5a56f43c57 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -3,7 +3,6 @@ from __future__ import annotations from typing import TYPE_CHECKING -import warnings from pandas._libs import ( index as libindex, @@ -14,8 +13,6 @@ Timedelta, to_offset, ) -from pandas._libs.tslibs.timedeltas import disallow_ambiguous_unit -from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.common import ( is_scalar, @@ -63,12 +60,6 @@ class TimedeltaIndex(DatetimeTimedeltaMixin): ---------- data : array-like (1-dimensional), optional Optional timedelta-like data to construct index with. - unit : {'D', 'h', 'm', 's', 'ms', 'us', 'ns'}, optional - The unit of ``data``. - - .. deprecated:: 2.2.0 - Use ``pd.to_timedelta`` instead. - freq : str or pandas offset object, optional One of pandas date offset strings or corresponding objects. The string ``'infer'`` can be passed in order to set the frequency of the index as @@ -151,40 +142,16 @@ def _resolution_obj(self) -> Resolution | None: # type: ignore[override] def __new__( cls, data=None, - unit=lib.no_default, freq=lib.no_default, - closed=lib.no_default, dtype=None, copy: bool = False, name=None, ): - if closed is not lib.no_default: - # GH#52628 - warnings.warn( - f"The 'closed' keyword in {cls.__name__} construction is " - "deprecated and will be removed in a future version.", - FutureWarning, - stacklevel=find_stack_level(), - ) - - if unit is not lib.no_default: - # GH#55499 - warnings.warn( - f"The 'unit' keyword in {cls.__name__} construction is " - "deprecated and will be removed in a future version. " - "Use pd.to_timedelta instead.", - FutureWarning, - stacklevel=find_stack_level(), - ) - else: - unit = None - name = maybe_extract_name(name, data, cls) if is_scalar(data): cls._raise_scalar_data_error(data) - disallow_ambiguous_unit(unit) if dtype is not None: dtype = pandas_dtype(dtype) @@ -211,7 +178,7 @@ def __new__( # - Cases checked above all return/raise before reaching here - # tdarr = TimedeltaArray._from_sequence_not_strict( - data, freq=freq, unit=unit, dtype=dtype, copy=copy + data, freq=freq, unit=None, dtype=dtype, copy=copy ) refs = None if not copy and isinstance(data, (ABCSeries, Index)): diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index 48bbfc1a9f646..4be45e834ce31 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -35,18 +35,6 @@ class TestDatetimeIndex: - def test_closed_deprecated(self): - # GH#52628 - msg = "The 'closed' keyword" - with tm.assert_produces_warning(FutureWarning, match=msg): - DatetimeIndex([], closed=True) - - def test_normalize_deprecated(self): - # GH#52628 - msg = "The 'normalize' keyword" - with tm.assert_produces_warning(FutureWarning, match=msg): - DatetimeIndex([], normalize=True) - def test_from_dt64_unsupported_unit(self): # GH#49292 val = np.datetime64(1, "D") diff --git a/pandas/tests/indexes/timedeltas/test_constructors.py b/pandas/tests/indexes/timedeltas/test_constructors.py index 0510700bb64d7..2f97ab6be8965 100644 --- a/pandas/tests/indexes/timedeltas/test_constructors.py +++ b/pandas/tests/indexes/timedeltas/test_constructors.py @@ -15,12 +15,6 @@ class TestTimedeltaIndex: - def test_closed_deprecated(self): - # GH#52628 - msg = "The 'closed' keyword" - with tm.assert_produces_warning(FutureWarning, match=msg): - TimedeltaIndex([], closed=True) - def test_array_of_dt64_nat_raises(self): # GH#39462 nat = np.datetime64("NaT", "ns") @@ -36,14 +30,6 @@ def test_array_of_dt64_nat_raises(self): with pytest.raises(TypeError, match=msg): to_timedelta(arr) - @pytest.mark.parametrize("unit", ["Y", "y", "M"]) - def test_unit_m_y_raises(self, unit): - msg = "Units 'M', 'Y', and 'y' are no longer supported" - depr_msg = "The 'unit' keyword in TimedeltaIndex construction is deprecated" - with pytest.raises(ValueError, match=msg): - with tm.assert_produces_warning(FutureWarning, match=depr_msg): - TimedeltaIndex([1, 3, 7], unit) - def test_int64_nocopy(self): # GH#23539 check that a copy isn't made when we pass int64 data # and copy=False @@ -138,9 +124,6 @@ def test_construction_base_constructor(self): tm.assert_index_equal(pd.Index(arr), TimedeltaIndex(arr)) tm.assert_index_equal(pd.Index(np.array(arr)), TimedeltaIndex(np.array(arr))) - @pytest.mark.filterwarnings( - "ignore:The 'unit' keyword in TimedeltaIndex construction:FutureWarning" - ) def test_constructor(self): expected = TimedeltaIndex( [ @@ -162,22 +145,6 @@ def test_constructor(self): ) tm.assert_index_equal(result, expected) - expected = TimedeltaIndex( - ["0 days 00:00:00", "0 days 00:00:01", "0 days 00:00:02"] - ) - result = TimedeltaIndex(range(3), unit="s") - tm.assert_index_equal(result, expected) - expected = TimedeltaIndex( - ["0 days 00:00:00", "0 days 00:00:05", "0 days 00:00:09"] - ) - result = TimedeltaIndex([0, 5, 9], unit="s") - tm.assert_index_equal(result, expected) - expected = TimedeltaIndex( - ["0 days 00:00:00.400", "0 days 00:00:00.450", "0 days 00:00:01.200"] - ) - result = TimedeltaIndex([400, 450, 1200], unit="ms") - tm.assert_index_equal(result, expected) - def test_constructor_iso(self): # GH #21877 expected = timedelta_range("1s", periods=9, freq="s") diff --git a/pandas/tests/scalar/timedelta/test_constructors.py b/pandas/tests/scalar/timedelta/test_constructors.py index c69f572c92bf2..5509216f4daf4 100644 --- a/pandas/tests/scalar/timedelta/test_constructors.py +++ b/pandas/tests/scalar/timedelta/test_constructors.py @@ -126,30 +126,26 @@ def test_unit_parser(self, unit, np_unit, wrapper): ) # TODO(2.0): the desired output dtype may have non-nano resolution - msg = "The 'unit' keyword in TimedeltaIndex construction is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = to_timedelta(wrapper(range(5)), unit=unit) - tm.assert_index_equal(result, expected) - result = TimedeltaIndex(wrapper(range(5)), unit=unit) - tm.assert_index_equal(result, expected) - - str_repr = [f"{x}{unit}" for x in np.arange(5)] - result = to_timedelta(wrapper(str_repr)) - tm.assert_index_equal(result, expected) - result = to_timedelta(wrapper(str_repr)) - tm.assert_index_equal(result, expected) - - # scalar - expected = Timedelta(np.timedelta64(2, np_unit).astype("timedelta64[ns]")) - result = to_timedelta(2, unit=unit) - assert result == expected - result = Timedelta(2, unit=unit) - assert result == expected - - result = to_timedelta(f"2{unit}") - assert result == expected - result = Timedelta(f"2{unit}") - assert result == expected + result = to_timedelta(wrapper(range(5)), unit=unit) + tm.assert_index_equal(result, expected) + + str_repr = [f"{x}{unit}" for x in np.arange(5)] + result = to_timedelta(wrapper(str_repr)) + tm.assert_index_equal(result, expected) + result = to_timedelta(wrapper(str_repr)) + tm.assert_index_equal(result, expected) + + # scalar + expected = Timedelta(np.timedelta64(2, np_unit).astype("timedelta64[ns]")) + result = to_timedelta(2, unit=unit) + assert result == expected + result = Timedelta(2, unit=unit) + assert result == expected + + result = to_timedelta(f"2{unit}") + assert result == expected + result = Timedelta(f"2{unit}") + assert result == expected @pytest.mark.parametrize("unit", ["T", "t", "L", "l", "U", "u", "N", "n"]) def test_unit_T_L_N_U_raises(self, unit):