Skip to content

Commit a378fb3

Browse files
natmokvalpmhatre1
authored andcommitted
DEPR: remove deprecated units ‘H’, ’T’, and smaller from Timedelta, TimedeltaIndex (pandas-dev#57627)
1 parent 213ade1 commit a378fb3

File tree

11 files changed

+106
-115
lines changed

11 files changed

+106
-115
lines changed

asv_bench/benchmarks/timeseries.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def setup(self):
183183
self.dt_ts = Series(5, rng3, dtype="datetime64[ns]")
184184

185185
def time_resample(self):
186-
self.dt_ts.resample("1S").last()
186+
self.dt_ts.resample("1s").last()
187187

188188

189189
class AsOf:

doc/source/whatsnew/v3.0.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ Removal of prior version deprecations/changes
208208
- Enforced deprecation of string ``A`` denoting frequency in :class:`YearEnd` and strings ``A-DEC``, ``A-JAN``, etc. denoting annual frequencies with various fiscal year ends (:issue:`57699`)
209209
- Enforced deprecation of string ``BAS`` denoting frequency in :class:`BYearBegin` and strings ``BAS-DEC``, ``BAS-JAN``, etc. denoting annual frequencies with various fiscal year starts (:issue:`57793`)
210210
- Enforced deprecation of string ``BA`` denoting frequency in :class:`BYearEnd` and strings ``BA-DEC``, ``BA-JAN``, etc. denoting annual frequencies with various fiscal year ends (:issue:`57793`)
211+
- Enforced deprecation of strings ``T``, ``L``, ``U``, and ``N`` denoting frequencies in :class:`Minute`, :class:`Second`, :class:`Milli`, :class:`Micro`, :class:`Nano` (:issue:`57627`)
212+
- Enforced deprecation of strings ``T``, ``L``, ``U``, and ``N`` denoting units in :class:`Timedelta` (:issue:`57627`)
211213
- Enforced deprecation of the behavior of :func:`concat` when ``len(keys) != len(objs)`` would truncate to the shorter of the two. Now this raises a ``ValueError`` (:issue:`43485`)
212214
- Enforced silent-downcasting deprecation for :ref:`all relevant methods <whatsnew_220.silent_downcasting>` (:issue:`54710`)
213215
- In :meth:`DataFrame.stack`, the default value of ``future_stack`` is now ``True``; specifying ``False`` will raise a ``FutureWarning`` (:issue:`55448`)

pandas/_libs/tslibs/dtypes.pyx

+5-9
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,7 @@ cdef dict c_DEPR_ABBREVS = {
313313
"H": "h",
314314
"BH": "bh",
315315
"CBH": "cbh",
316-
"T": "min",
317-
"t": "min",
318316
"S": "s",
319-
"L": "ms",
320-
"l": "ms",
321-
"U": "us",
322-
"u": "us",
323-
"N": "ns",
324-
"n": "ns",
325317
}
326318

327319

@@ -415,13 +407,17 @@ class Resolution(Enum):
415407
"""
416408
cdef:
417409
str abbrev
410+
if freq in {"T", "t", "L", "l", "U", "u", "N", "n"}:
411+
raise ValueError(
412+
f"Frequency \'{freq}\' is no longer supported."
413+
)
418414
try:
419415
if freq in c_DEPR_ABBREVS:
420416
abbrev = c_DEPR_ABBREVS[freq]
421417
warnings.warn(
422418
f"\'{freq}\' is deprecated and will be removed in a future "
423419
f"version. Please use \'{abbrev}\' "
424-
"instead of \'{freq}\'.",
420+
f"instead of \'{freq}\'.",
425421
FutureWarning,
426422
stacklevel=find_stack_level(),
427423
)

pandas/core/tools/timedeltas.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,17 @@ def to_timedelta(
112112
* 'W'
113113
* 'D' / 'days' / 'day'
114114
* 'hours' / 'hour' / 'hr' / 'h' / 'H'
115-
* 'm' / 'minute' / 'min' / 'minutes' / 'T'
115+
* 'm' / 'minute' / 'min' / 'minutes'
116116
* 's' / 'seconds' / 'sec' / 'second' / 'S'
117-
* 'ms' / 'milliseconds' / 'millisecond' / 'milli' / 'millis' / 'L'
118-
* 'us' / 'microseconds' / 'microsecond' / 'micro' / 'micros' / 'U'
119-
* 'ns' / 'nanoseconds' / 'nano' / 'nanos' / 'nanosecond' / 'N'
117+
* 'ms' / 'milliseconds' / 'millisecond' / 'milli' / 'millis'
118+
* 'us' / 'microseconds' / 'microsecond' / 'micro' / 'micros'
119+
* 'ns' / 'nanoseconds' / 'nano' / 'nanos' / 'nanosecond'
120120
121121
Must not be specified when `arg` contains strings and ``errors="raise"``.
122122
123123
.. deprecated:: 2.2.0
124-
Units 'H', 'T', 'S', 'L', 'U' and 'N' are deprecated and will be removed
125-
in a future version. Please use 'h', 'min', 's', 'ms', 'us', and 'ns'
126-
instead of 'H', 'T', 'S', 'L', 'U' and 'N'.
124+
Units 'H'and 'S' are deprecated and will be removed
125+
in a future version. Please use 'h' and 's'.
127126
128127
errors : {'raise', 'coerce'}, default 'raise'
129128
- If 'raise', then invalid parsing will raise an exception.

pandas/tests/indexes/datetimes/test_date_range.py

+5-24
Original file line numberDiff line numberDiff line change
@@ -772,30 +772,11 @@ def test_freq_dateoffset_with_relateivedelta_nanos(self):
772772
)
773773
tm.assert_index_equal(result, expected)
774774

775-
@pytest.mark.parametrize(
776-
"freq,freq_depr",
777-
[
778-
("h", "H"),
779-
("2min", "2T"),
780-
("1s", "1S"),
781-
("2ms", "2L"),
782-
("1us", "1U"),
783-
("2ns", "2N"),
784-
],
785-
)
786-
def test_frequencies_H_T_S_L_U_N_deprecated(self, freq, freq_depr):
787-
# GH#52536
788-
freq_msg = re.split("[0-9]*", freq, maxsplit=1)[1]
789-
freq_depr_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
790-
msg = (
791-
f"'{freq_depr_msg}' is deprecated and will be removed in a future version, "
792-
)
793-
f"please use '{freq_msg}' instead"
794-
795-
expected = date_range("1/1/2000", periods=2, freq=freq)
796-
with tm.assert_produces_warning(FutureWarning, match=msg):
797-
result = date_range("1/1/2000", periods=2, freq=freq_depr)
798-
tm.assert_index_equal(result, expected)
775+
@pytest.mark.parametrize("freq", ["2T", "2L", "1l", "1U", "2N", "2n"])
776+
def test_frequency_H_T_S_L_U_N_raises(self, freq):
777+
msg = f"Invalid frequency: {freq}"
778+
with pytest.raises(ValueError, match=msg):
779+
date_range("1/1/2000", periods=2, freq=freq)
799780

800781
@pytest.mark.parametrize(
801782
"freq,freq_depr",

pandas/tests/indexes/period/test_constructors.py

+10
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ def test_period_index_from_datetime_index_invalid_freq(self, freq):
6060
with pytest.raises(ValueError, match=msg):
6161
rng.to_period()
6262

63+
@pytest.mark.parametrize("freq_depr", ["2T", "1l", "2U", "n"])
64+
def test_period_index_T_L_U_N_raises(self, freq_depr):
65+
# GH#9586
66+
msg = f"Invalid frequency: {freq_depr}"
67+
68+
with pytest.raises(ValueError, match=msg):
69+
period_range("2020-01", "2020-05", freq=freq_depr)
70+
with pytest.raises(ValueError, match=msg):
71+
PeriodIndex(["2020-01", "2020-05"], freq=freq_depr)
72+
6373

6474
class TestPeriodIndex:
6575
def test_from_ordinals(self):

pandas/tests/indexes/timedeltas/test_timedelta_range.py

+38-33
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,24 @@ def test_timedelta_range(self):
4343
result = timedelta_range("0 days", freq="30min", periods=50)
4444
tm.assert_index_equal(result, expected)
4545

46-
@pytest.mark.parametrize(
47-
"depr_unit, unit",
48-
[
49-
("H", "hour"),
50-
("T", "minute"),
51-
("t", "minute"),
52-
("S", "second"),
53-
("L", "millisecond"),
54-
("l", "millisecond"),
55-
("U", "microsecond"),
56-
("u", "microsecond"),
57-
("N", "nanosecond"),
58-
("n", "nanosecond"),
59-
],
60-
)
61-
def test_timedelta_units_H_T_S_L_U_N_deprecated(self, depr_unit, unit):
46+
@pytest.mark.parametrize("depr_unit, unit", [("H", "hour"), ("S", "second")])
47+
def test_timedelta_units_H_S_deprecated(self, depr_unit, unit):
6248
# GH#52536
6349
depr_msg = (
6450
f"'{depr_unit}' is deprecated and will be removed in a future version."
6551
)
66-
6752
expected = to_timedelta(np.arange(5), unit=unit)
6853
with tm.assert_produces_warning(FutureWarning, match=depr_msg):
6954
result = to_timedelta(np.arange(5), unit=depr_unit)
7055
tm.assert_index_equal(result, expected)
7156

57+
@pytest.mark.parametrize("unit", ["T", "t", "L", "l", "U", "u", "N", "n"])
58+
def test_timedelta_unit_T_L_U_N_raises(self, unit):
59+
msg = f"invalid unit abbreviation: {unit}"
60+
61+
with pytest.raises(ValueError, match=msg):
62+
to_timedelta(np.arange(5), unit=unit)
63+
7264
@pytest.mark.parametrize(
7365
"periods, freq", [(3, "2D"), (5, "D"), (6, "19h12min"), (7, "16h"), (9, "12h")]
7466
)
@@ -78,16 +70,21 @@ def test_linspace_behavior(self, periods, freq):
7870
expected = timedelta_range(start="0 days", end="4 days", freq=freq)
7971
tm.assert_index_equal(result, expected)
8072

81-
@pytest.mark.parametrize("msg_freq, freq", [("H", "19H12min"), ("T", "19h12T")])
82-
def test_timedelta_range_H_T_deprecated(self, freq, msg_freq):
73+
def test_timedelta_range_H_deprecated(self):
8374
# GH#52536
84-
msg = f"'{msg_freq}' is deprecated and will be removed in a future version."
75+
msg = "'H' is deprecated and will be removed in a future version."
8576

8677
result = timedelta_range(start="0 days", end="4 days", periods=6)
8778
with tm.assert_produces_warning(FutureWarning, match=msg):
88-
expected = timedelta_range(start="0 days", end="4 days", freq=freq)
79+
expected = timedelta_range(start="0 days", end="4 days", freq="19H12min")
8980
tm.assert_index_equal(result, expected)
9081

82+
def test_timedelta_range_T_raises(self):
83+
msg = "Invalid frequency: T"
84+
85+
with pytest.raises(ValueError, match=msg):
86+
timedelta_range(start="0 days", end="4 days", freq="19h12T")
87+
9188
def test_errors(self):
9289
# not enough params
9390
msg = (
@@ -143,18 +140,6 @@ def test_timedelta_range_infer_freq(self):
143140
["0 days 05:03:01", "0 days 05:03:04.500000", "0 days 05:03:08"],
144141
"3500ms",
145142
),
146-
(
147-
"2.5T",
148-
"5 hours",
149-
"5 hours 8 minutes",
150-
[
151-
"0 days 05:00:00",
152-
"0 days 05:02:30",
153-
"0 days 05:05:00",
154-
"0 days 05:07:30",
155-
],
156-
"150s",
157-
),
158143
],
159144
)
160145
def test_timedelta_range_deprecated_freq(
@@ -171,3 +156,23 @@ def test_timedelta_range_deprecated_freq(
171156
expected_values, dtype="timedelta64[ns]", freq=expected_freq
172157
)
173158
tm.assert_index_equal(result, expected)
159+
160+
@pytest.mark.parametrize(
161+
"freq_depr, start, end",
162+
[
163+
(
164+
"3.5l",
165+
"05:03:01",
166+
"05:03:10",
167+
),
168+
(
169+
"2.5T",
170+
"5 hours",
171+
"5 hours 8 minutes",
172+
),
173+
],
174+
)
175+
def test_timedelta_range_removed_freq(self, freq_depr, start, end):
176+
msg = f"Invalid frequency: {freq_depr}"
177+
with pytest.raises(ValueError, match=msg):
178+
timedelta_range(start=start, end=end, freq=freq_depr)

pandas/tests/resample/test_period_index.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -982,22 +982,20 @@ def test_sum_min_count(self):
982982

983983
def test_resample_t_l_deprecated(self):
984984
# GH#52536
985-
msg_t = "'T' is deprecated and will be removed in a future version."
986-
msg_l = "'L' is deprecated and will be removed in a future version."
985+
msg_t = "Invalid frequency: T"
986+
msg_l = "Invalid frequency: L"
987987

988-
with tm.assert_produces_warning(FutureWarning, match=msg_l):
989-
rng_l = period_range(
988+
with pytest.raises(ValueError, match=msg_l):
989+
period_range(
990990
"2020-01-01 00:00:00 00:00", "2020-01-01 00:00:00 00:01", freq="L"
991991
)
992+
rng_l = period_range(
993+
"2020-01-01 00:00:00 00:00", "2020-01-01 00:00:00 00:01", freq="ms"
994+
)
992995
ser = Series(np.arange(len(rng_l)), index=rng_l)
993996

994-
rng = period_range(
995-
"2020-01-01 00:00:00 00:00", "2020-01-01 00:00:00 00:01", freq="min"
996-
)
997-
expected = Series([29999.5, 60000.0], index=rng)
998-
with tm.assert_produces_warning(FutureWarning, match=msg_t):
999-
result = ser.resample("T").mean()
1000-
tm.assert_series_equal(result, expected)
997+
with pytest.raises(ValueError, match=msg_t):
998+
ser.resample("T").mean()
1001999

10021000
@pytest.mark.parametrize(
10031001
"freq, freq_depr, freq_res, freq_depr_res, data",

pandas/tests/scalar/period/test_asfreq.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ def test_conv_annual(self):
116116
assert ival_A.asfreq("H", "E") == ival_A_to_H_end
117117
assert ival_A.asfreq("min", "s") == ival_A_to_T_start
118118
assert ival_A.asfreq("min", "E") == ival_A_to_T_end
119-
msg = "'T' is deprecated and will be removed in a future version."
120-
with tm.assert_produces_warning(FutureWarning, match=msg):
119+
msg = "Invalid frequency: T"
120+
with pytest.raises(ValueError, match=msg):
121121
assert ival_A.asfreq("T", "s") == ival_A_to_T_start
122122
assert ival_A.asfreq("T", "E") == ival_A_to_T_end
123123
msg = "'S' is deprecated and will be removed in a future version."

pandas/tests/scalar/timedelta/test_constructors.py

+19-26
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,14 @@ def test_unit_m_y_raises(self, unit):
3232
with pytest.raises(ValueError, match=msg):
3333
to_timedelta([1, 2], unit)
3434

35-
@pytest.mark.parametrize(
36-
"unit,unit_depr",
37-
[
38-
("h", "H"),
39-
("min", "T"),
40-
("s", "S"),
41-
("ms", "L"),
42-
("ns", "N"),
43-
("us", "U"),
44-
],
45-
)
46-
def test_units_H_T_S_L_N_U_deprecated(self, unit, unit_depr):
35+
@pytest.mark.parametrize("unit", ["h", "s"])
36+
def test_units_H_S_deprecated(self, unit):
4737
# GH#52536
48-
msg = f"'{unit_depr}' is deprecated and will be removed in a future version."
38+
msg = f"'{unit.upper()}' is deprecated and will be removed in a future version."
4939

5040
expected = Timedelta(1, unit=unit)
5141
with tm.assert_produces_warning(FutureWarning, match=msg):
52-
result = Timedelta(1, unit=unit_depr)
42+
result = Timedelta(1, unit=unit.upper())
5343
tm.assert_equal(result, expected)
5444

5545
@pytest.mark.parametrize(
@@ -103,13 +93,11 @@ def test_units_H_T_S_L_N_U_deprecated(self, unit, unit_depr):
10393
"microsecond",
10494
"micro",
10595
"micros",
106-
"u",
10796
"US",
10897
"Microseconds",
10998
"Microsecond",
11099
"Micro",
111100
"Micros",
112-
"U",
113101
]
114102
]
115103
+ [
@@ -120,13 +108,11 @@ def test_units_H_T_S_L_N_U_deprecated(self, unit, unit_depr):
120108
"nanosecond",
121109
"nano",
122110
"nanos",
123-
"n",
124111
"NS",
125112
"Nanoseconds",
126113
"Nanosecond",
127114
"Nano",
128115
"Nanos",
129-
"N",
130116
]
131117
],
132118
)
@@ -139,14 +125,9 @@ def test_unit_parser(self, unit, np_unit, wrapper):
139125
dtype="m8[ns]",
140126
)
141127
# TODO(2.0): the desired output dtype may have non-nano resolution
142-
msg = f"'{unit}' is deprecated and will be removed in a future version."
143-
144-
if (unit, np_unit) in (("u", "us"), ("U", "us"), ("n", "ns"), ("N", "ns")):
145-
warn = FutureWarning
146-
else:
147-
warn = FutureWarning
148-
msg = "The 'unit' keyword in TimedeltaIndex construction is deprecated"
149-
with tm.assert_produces_warning(warn, match=msg):
128+
129+
msg = "The 'unit' keyword in TimedeltaIndex construction is deprecated"
130+
with tm.assert_produces_warning(FutureWarning, match=msg):
150131
result = to_timedelta(wrapper(range(5)), unit=unit)
151132
tm.assert_index_equal(result, expected)
152133
result = TimedeltaIndex(wrapper(range(5)), unit=unit)
@@ -170,6 +151,18 @@ def test_unit_parser(self, unit, np_unit, wrapper):
170151
result = Timedelta(f"2{unit}")
171152
assert result == expected
172153

154+
@pytest.mark.parametrize("unit", ["T", "t", "L", "l", "U", "u", "N", "n"])
155+
def test_unit_T_L_N_U_raises(self, unit):
156+
msg = f"invalid unit abbreviation: {unit}"
157+
with pytest.raises(ValueError, match=msg):
158+
Timedelta(1, unit=unit)
159+
160+
with pytest.raises(ValueError, match=msg):
161+
to_timedelta(10, unit)
162+
163+
with pytest.raises(ValueError, match=msg):
164+
to_timedelta([1, 2], unit)
165+
173166

174167
def test_construct_from_kwargs_overflow():
175168
# GH#55503

pandas/tests/tslibs/test_resolution.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ def test_get_attrname_from_abbrev(freqstr, expected):
4848
assert reso.attrname == expected
4949

5050

51-
@pytest.mark.parametrize("freq", ["H", "T", "S", "L", "U", "N"])
52-
def test_units_H_T_S_L_U_N_deprecated_from_attrname_to_abbrevs(freq):
51+
@pytest.mark.parametrize("freq", ["H", "S"])
52+
def test_units_H_S_deprecated_from_attrname_to_abbrevs(freq):
5353
# GH#52536
5454
msg = f"'{freq}' is deprecated and will be removed in a future version."
5555

5656
with tm.assert_produces_warning(FutureWarning, match=msg):
5757
Resolution.get_reso_from_freqstr(freq)
58+
59+
60+
@pytest.mark.parametrize("freq", ["T", "t", "L", "U", "N", "n"])
61+
def test_reso_abbrev_T_L_U_N_raises(freq):
62+
msg = f"Frequency '{freq}' is no longer supported."
63+
with pytest.raises(ValueError, match=msg):
64+
Resolution.get_reso_from_freqstr(freq)

0 commit comments

Comments
 (0)