From f63ec87476db065a58d423670b8829abc8d1e746 Mon Sep 17 00:00:00 2001 From: Roberto Chang Date: Sat, 24 Feb 2024 21:43:19 +0900 Subject: [PATCH] date_range: set default freq to 'D' only if periods, start, or end are None (#8774) * Fixing issue #8770: Improved frequency parameter logic to set it to 'D' only if periods, start, or end are None. * Addressed feedback: Updated default argument handling in cftime_range to ensure consistency across date range functions * Update doc/whats-new.rst Co-authored-by: Mathias Hauser * Update xarray/tests/test_cftime_offsets.py Co-authored-by: Mathias Hauser * Update xarray/tests/test_cftime_offsets.py Co-authored-by: Mathias Hauser * Input argument period included in test_cftime_range_no_freq and test_date_range_no_freq following #8770 * Update doc/whats-new.rst Co-authored-by: Spencer Clark --------- Co-authored-by: Mathias Hauser Co-authored-by: Spencer Clark --- doc/whats-new.rst | 4 ++- xarray/coding/cftime_offsets.py | 8 +++-- xarray/tests/test_cftime_offsets.py | 45 ++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 80e53a5ee22..9d7eb55071b 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -37,7 +37,9 @@ Deprecations Bug fixes ~~~~~~~~~ - +- The default ``freq`` parameter in :py:meth:`xr.date_range` and :py:meth:`xr.cftime_range` is + set to ``'D'`` only if ``periods``, ``start``, or ``end`` are ``None`` (:issue:`8770`, :pull:`8774`). + By `Roberto Chang `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/coding/cftime_offsets.py b/xarray/coding/cftime_offsets.py index 556bab8504b..2e594455874 100644 --- a/xarray/coding/cftime_offsets.py +++ b/xarray/coding/cftime_offsets.py @@ -914,7 +914,7 @@ def cftime_range( start=None, end=None, periods=None, - freq="D", + freq=None, normalize=False, name=None, closed: NoDefault | SideOptions = no_default, @@ -1100,6 +1100,10 @@ def cftime_range( -------- pandas.date_range """ + + if freq is None and any(arg is None for arg in [periods, start, end]): + freq = "D" + # Adapted from pandas.core.indexes.datetimes._generate_range. if count_not_none(start, end, periods, freq) != 3: raise ValueError( @@ -1152,7 +1156,7 @@ def date_range( start=None, end=None, periods=None, - freq="D", + freq=None, tz=None, normalize=False, name=None, diff --git a/xarray/tests/test_cftime_offsets.py b/xarray/tests/test_cftime_offsets.py index a0bc678b51c..0110afe40ac 100644 --- a/xarray/tests/test_cftime_offsets.py +++ b/xarray/tests/test_cftime_offsets.py @@ -1294,7 +1294,6 @@ def test_cftime_range_name(): (None, None, 5, "YE", None), ("2000", None, None, "YE", None), (None, "2000", None, "YE", None), - ("2000", "2001", None, None, None), (None, None, None, None, None), ("2000", "2001", None, "YE", "up"), ("2000", "2001", 5, "YE", None), @@ -1733,3 +1732,47 @@ def test_cftime_range_same_as_pandas(start, end, freq): expected = date_range(start, end, freq=freq, use_cftime=False) np.testing.assert_array_equal(result, expected) + + +@pytest.mark.filterwarnings("ignore:Converting a CFTimeIndex with:") +@pytest.mark.parametrize( + "start, end, periods", + [ + ("2022-01-01", "2022-01-10", 2), + ("2022-03-01", "2022-03-31", 2), + ("2022-01-01", "2022-01-10", None), + ("2022-03-01", "2022-03-31", None), + ], +) +def test_cftime_range_no_freq(start, end, periods): + """ + Test whether cftime_range produces the same result as Pandas + when freq is not provided, but start, end and periods are. + """ + # Generate date ranges using cftime_range + result = cftime_range(start=start, end=end, periods=periods) + result = result.to_datetimeindex() + expected = pd.date_range(start=start, end=end, periods=periods) + + np.testing.assert_array_equal(result, expected) + + +@pytest.mark.parametrize( + "start, end, periods", + [ + ("2022-01-01", "2022-01-10", 2), + ("2022-03-01", "2022-03-31", 2), + ("2022-01-01", "2022-01-10", None), + ("2022-03-01", "2022-03-31", None), + ], +) +def test_date_range_no_freq(start, end, periods): + """ + Test whether date_range produces the same result as Pandas + when freq is not provided, but start, end and periods are. + """ + # Generate date ranges using date_range + result = date_range(start=start, end=end, periods=periods) + expected = pd.date_range(start=start, end=end, periods=periods) + + np.testing.assert_array_equal(result, expected)