Skip to content

Commit 32ea61d

Browse files
authored
ENH: improve error message when specifying a previously-deprecated frequen… (#62539)
1 parent 21f2ebe commit 32ea61d

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

pandas/_libs/tslibs/offsets.pyx

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5188,6 +5188,27 @@ INVALID_FREQ_ERR_MSG = "Invalid frequency: {0}"
51885188
_offset_map = {}
51895189

51905190

5191+
deprec_to_valid_alias = {
5192+
"H": "h",
5193+
"BH": "bh",
5194+
"CBH": "cbh",
5195+
"T": "min",
5196+
"S": "s",
5197+
"L": "ms",
5198+
"U": "us",
5199+
"N": "ns",
5200+
}
5201+
5202+
5203+
def raise_invalid_freq(freq: str, extra_message: str | None = None) -> None:
5204+
msg = f"Invalid frequency: {freq}."
5205+
if extra_message is not None:
5206+
msg += f" {extra_message}"
5207+
if freq in deprec_to_valid_alias:
5208+
msg += f" Did you mean {deprec_to_valid_alias[freq]}?"
5209+
raise ValueError(msg)
5210+
5211+
51915212
def _warn_about_deprecated_aliases(name: str, is_period: bool) -> str:
51925213
if name in _lite_rule_alias:
51935214
return name
@@ -5236,7 +5257,7 @@ def _validate_to_offset_alias(alias: str, is_period: bool) -> None:
52365257
if (alias.upper() != alias and
52375258
alias.lower() not in {"s", "ms", "us", "ns"} and
52385259
alias.upper().split("-")[0].endswith(("S", "E"))):
5239-
raise ValueError(INVALID_FREQ_ERR_MSG.format(alias))
5260+
raise ValueError(raise_invalid_freq(freq=alias))
52405261
if (
52415262
is_period and
52425263
alias in c_OFFSET_TO_PERIOD_FREQSTR and
@@ -5267,8 +5288,9 @@ def _get_offset(name: str) -> BaseOffset:
52675288
offset = klass._from_name(*split[1:])
52685289
except (ValueError, TypeError, KeyError) as err:
52695290
# bad prefix or suffix
5270-
raise ValueError(INVALID_FREQ_ERR_MSG.format(
5271-
f"{name}, failed to parse with error message: {repr(err)}")
5291+
raise_invalid_freq(
5292+
freq=name,
5293+
extra_message=f"Failed to parse with error message: {repr(err)}."
52725294
)
52735295
# cache
52745296
_offset_map[name] = offset
@@ -5399,9 +5421,10 @@ cpdef to_offset(freq, bint is_period=False):
53995421
else:
54005422
result = result + offset
54015423
except (ValueError, TypeError) as err:
5402-
raise ValueError(INVALID_FREQ_ERR_MSG.format(
5403-
f"{freq}, failed to parse with error message: {repr(err)}")
5404-
) from err
5424+
raise_invalid_freq(
5425+
freq=freq,
5426+
extra_message=f"Failed to parse with error message: {repr(err)}"
5427+
)
54055428

54065429
# TODO(3.0?) once deprecation of "d" is enforced, the check for it here
54075430
# can be removed
@@ -5417,7 +5440,7 @@ cpdef to_offset(freq, bint is_period=False):
54175440
result = None
54185441

54195442
if result is None:
5420-
raise ValueError(INVALID_FREQ_ERR_MSG.format(freq))
5443+
raise_invalid_freq(freq=freq)
54215444

54225445
try:
54235446
has_period_dtype_code = hasattr(result, "_period_dtype_code")

pandas/tests/tseries/offsets/test_offsets.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,11 @@ def test_offset_multiplication(
11571157
tm.assert_series_equal(resultarray, expectedarray)
11581158

11591159

1160+
def test_offset_deprecated_error():
1161+
with pytest.raises(ValueError, match="Did you mean h"):
1162+
date_range("2012-01-01", periods=3, freq="H")
1163+
1164+
11601165
def test_dateoffset_operations_on_dataframes(performance_warning):
11611166
# GH 47953
11621167
df = DataFrame({"T": [Timestamp("2019-04-30")], "D": [DateOffset(months=1)]})

0 commit comments

Comments
 (0)