Skip to content

Commit 4075fea

Browse files
authored
BUG: bdate_range with "cbh" fails (#62873)
1 parent 77fdffd commit 4075fea

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ Categorical
961961
^^^^^^^^^^^
962962
- Bug in :class:`Categorical` where constructing from a pandas :class:`Series` or :class:`Index` with ``dtype='object'`` did not preserve the categories' dtype as ``object``; now the ``categories.dtype`` is preserved as ``object`` for these cases, while numpy arrays and Python sequences with ``dtype='object'`` continue to infer the most specific dtype (for example, ``str`` if all elements are strings) (:issue:`61778`)
963963
- Bug in :func:`Series.apply` where ``nan`` was ignored for :class:`CategoricalDtype` (:issue:`59938`)
964+
- Bug in :func:`bdate_range` raising ``ValueError`` with frequency ``freq="cbh"`` (:issue:`62849`)
964965
- Bug in :func:`testing.assert_index_equal` raising ``TypeError`` instead of ``AssertionError`` for incomparable ``CategoricalIndex`` when ``check_categorical=True`` and ``exact=False`` (:issue:`61935`)
965966
- Bug in :meth:`Categorical.astype` where ``copy=False`` would still trigger a copy of the codes (:issue:`62000`)
966967
- Bug in :meth:`DataFrame.pivot` and :meth:`DataFrame.set_index` raising an ``ArrowNotImplementedError`` for columns with pyarrow dictionary dtype (:issue:`53051`)

pandas/core/indexes/datetimes.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,12 +1133,14 @@ def bdate_range(
11331133
msg = "freq must be specified for bdate_range; use date_range instead"
11341134
raise TypeError(msg)
11351135

1136-
if isinstance(freq, str) and freq.startswith("C"):
1136+
if isinstance(freq, str) and freq.upper().startswith("C"):
1137+
msg = f"invalid custom frequency string: {freq}"
1138+
if freq == "CBH":
1139+
raise ValueError(f"{msg}, did you mean cbh?")
11371140
try:
11381141
weekmask = weekmask or "Mon Tue Wed Thu Fri"
11391142
freq = prefix_mapping[freq](holidays=holidays, weekmask=weekmask)
11401143
except (KeyError, TypeError) as err:
1141-
msg = f"invalid custom frequency string: {freq}"
11421144
raise ValueError(msg) from err
11431145
elif holidays or weekmask:
11441146
msg = (

pandas/tests/indexes/datetimes/test_date_range.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ def test_cdaterange_holidays_weekmask_requires_freqstr(self):
12161216
)
12171217

12181218
@pytest.mark.parametrize(
1219-
"freq", [freq for freq in prefix_mapping if freq.startswith("C")]
1219+
"freq", [freq for freq in prefix_mapping if freq.upper().startswith("C")]
12201220
)
12211221
def test_all_custom_freq(self, freq):
12221222
# should not raise
@@ -1280,6 +1280,39 @@ def test_data_range_custombusinessday_partial_time(self, unit):
12801280
)
12811281
tm.assert_index_equal(result, expected)
12821282

1283+
def test_cdaterange_cbh(self):
1284+
# GH#62849
1285+
result = bdate_range(
1286+
"2009-03-13",
1287+
"2009-03-15",
1288+
freq="cbh",
1289+
weekmask="Mon Wed Fri",
1290+
holidays=["2009-03-14"],
1291+
)
1292+
expected = DatetimeIndex(
1293+
[
1294+
"2009-03-13 09:00:00",
1295+
"2009-03-13 10:00:00",
1296+
"2009-03-13 11:00:00",
1297+
"2009-03-13 12:00:00",
1298+
"2009-03-13 13:00:00",
1299+
"2009-03-13 14:00:00",
1300+
"2009-03-13 15:00:00",
1301+
"2009-03-13 16:00:00",
1302+
],
1303+
dtype="datetime64[ns]",
1304+
freq="cbh",
1305+
)
1306+
tm.assert_index_equal(result, expected)
1307+
1308+
def test_cdaterange_deprecated_error_CBH(self):
1309+
# GH#62849
1310+
msg = "invalid custom frequency string: CBH, did you mean cbh?"
1311+
with pytest.raises(ValueError, match=msg):
1312+
bdate_range(
1313+
START, END, freq="CBH", weekmask="Mon Wed Fri", holidays=["2009-03-14"]
1314+
)
1315+
12831316

12841317
class TestDateRangeNonNano:
12851318
def test_date_range_reso_validation(self):

0 commit comments

Comments
 (0)