diff --git a/xarray/tests/test_cftimeindex.py b/xarray/tests/test_cftimeindex.py index e3305887a26..8aa79be458e 100644 --- a/xarray/tests/test_cftimeindex.py +++ b/xarray/tests/test_cftimeindex.py @@ -27,6 +27,7 @@ assert_array_equal, assert_identical, has_cftime, + has_pandas_3, requires_cftime, ) @@ -960,8 +961,17 @@ def test_cftime_datetime_sub_cftimeindex(calendar): @pytest.mark.parametrize("calendar", _CFTIME_CALENDARS) def test_distant_cftime_datetime_sub_cftimeindex(calendar): a = xr.date_range("2000", periods=5, calendar=calendar, use_cftime=True) - with pytest.raises(ValueError, match="difference exceeds"): - a.date_type(1, 1, 1) - a + if not has_pandas_3: + with pytest.raises(ValueError, match="difference exceeds"): + a.date_type(1, 1, 1) - a + else: + result = a.date_type(1, 1, 1) - a + assert isinstance(result, pd.TimedeltaIndex) + assert result.unit == "us" + + # Check that we can recover original index from subtracting timedeltas + roundtrip = CFTimeIndex(a.date_type(1, 1, 1) - result.to_pytimedelta()) + assert roundtrip.equals(a) @requires_cftime diff --git a/xarray/tests/test_coding_times.py b/xarray/tests/test_coding_times.py index dc0bcf64543..475ef4252fd 100644 --- a/xarray/tests/test_coding_times.py +++ b/xarray/tests/test_coding_times.py @@ -599,7 +599,7 @@ def test_cf_timedelta(timedeltas, units, numbers) -> None: if timedeltas == "NaT": timedeltas = np.timedelta64("NaT", "ns") else: - timedeltas = pd.to_timedelta(timedeltas).to_numpy() + timedeltas = pd.to_timedelta(timedeltas).as_unit("ns").to_numpy() numbers = np.array(numbers) expected = numbers @@ -623,8 +623,9 @@ def test_cf_timedelta_2d() -> None: units = "days" numbers = np.atleast_2d([1, 2, 3]) - timedeltas = np.atleast_2d(pd.to_timedelta(["1D", "2D", "3D"]).to_numpy()) - expected = timedeltas + timedeltas = pd.to_timedelta(["1D", "2D", "3D"]).as_unit("ns") + timedeltas_2d = np.atleast_2d(timedeltas.to_numpy()) + expected = timedeltas_2d actual = decode_cf_timedelta(numbers, units) assert_array_equal(expected, actual) diff --git a/xarray/tests/test_groupby.py b/xarray/tests/test_groupby.py index e96d8b6828b..47ea2fcd2b0 100644 --- a/xarray/tests/test_groupby.py +++ b/xarray/tests/test_groupby.py @@ -3815,7 +3815,7 @@ def test_mean_with_cftime_objects_dask(): def test_groupby_bins_datetime_mean(): """Test groupby_bins with datetime mean (issue #6995)""" - times = pd.date_range("2020-01-01", "2020-02-01", freq="1h") + times = pd.date_range("2020-01-01", "2020-02-01", freq="1h", unit="ns") index = np.arange(len(times)) bins = np.arange(0, len(index), 5) @@ -3836,7 +3836,10 @@ def test_groupby_bins_mean_time_series(): ds = xr.Dataset( { "measurement": ("trial", np.arange(0, 100, 10)), - "time": ("trial", pd.date_range("20240101T1500", "20240101T1501", 10)), + "time": ( + "trial", + pd.date_range("20240101T1500", "20240101T1501", 10, unit="ns"), + ), } ) diff --git a/xarray/tests/test_interp.py b/xarray/tests/test_interp.py index 7e430bd409c..b02df976d47 100644 --- a/xarray/tests/test_interp.py +++ b/xarray/tests/test_interp.py @@ -721,7 +721,7 @@ def test_datetime(x_new, expected) -> None: da = xr.DataArray( np.arange(24), dims="time", - coords={"time": pd.date_range("2000-01-01", periods=24)}, + coords={"time": pd.date_range("2000-01-01", periods=24, unit="ns")}, ) actual = da.interp(time=x_new) @@ -739,7 +739,7 @@ def test_datetime_single_string() -> None: da = xr.DataArray( np.arange(24), dims="time", - coords={"time": pd.date_range("2000-01-01", periods=24)}, + coords={"time": pd.date_range("2000-01-01", periods=24, unit="ns")}, ) actual = da.interp(time="2000-01-01T12:00") expected = xr.DataArray(0.5) diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index 40f950d246d..3d8c3f5de2a 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -2897,7 +2897,7 @@ def test_datetime_hue(self) -> None: ds2["hue"] = pd.date_range("2000-1-1", periods=4) ds2.plot.scatter(x="A", y="B", hue="hue") - ds2["hue"] = pd.timedelta_range("-1D", periods=4, freq="D") + ds2["hue"] = pd.timedelta_range("-1D", periods=4, freq="D", unit="ns") # type: ignore[call-arg,unused-ignore] ds2.plot.scatter(x="A", y="B", hue="hue") def test_facetgrid_hue_style(self) -> None: diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py index 22f61d92e54..44a044275e2 100644 --- a/xarray/tests/test_variable.py +++ b/xarray/tests/test_variable.py @@ -74,11 +74,16 @@ def var(): ], ) def test_as_compatible_data_writeable(data): - pd.set_option("mode.copy_on_write", True) + # In pandas 3 the mode.copy_on_write option defaults to True, so the option + # setting logic can be removed once our minimum version of pandas is + # greater than or equal to 3. + if not has_pandas_3: + pd.set_option("mode.copy_on_write", True) # GH8843, ensure writeable arrays for data_vars even with # pandas copy-on-write mode assert as_compatible_data(data).flags.writeable - pd.reset_option("mode.copy_on_write") + if not has_pandas_3: + pd.reset_option("mode.copy_on_write") class VariableSubclassobjects(NamedArraySubclassobjects, ABC): @@ -225,7 +230,7 @@ def test_index_0d_timedelta64(self): x, np.timedelta64(td), np.dtype("timedelta64[us]") ) - x = self.cls(["x"], pd.to_timedelta([td])) + x = self.cls(["x"], pd.to_timedelta([td]).as_unit("ns")) self._assertIndexedLikeNDArray(x, np.timedelta64(td), "timedelta64[ns]") def test_index_0d_not_a_time(self): @@ -279,7 +284,7 @@ def test_0d_time_data(self): expected = np.datetime64("2000-01-01", "ns") assert x[0].values == expected - dt64_data = pd.date_range("1970-01-01", periods=3) + dt64_data = pd.date_range("1970-01-01", periods=3, unit="ns") @pytest.mark.parametrize( "values, unit", @@ -311,7 +316,7 @@ def test_datetime64_conversion(self, values, unit): (td64_data.values.astype("timedelta64[m]"), "s"), (td64_data.values.astype("timedelta64[s]"), "s"), (td64_data.values.astype("timedelta64[ps]"), "ns"), - (td64_data.to_pytimedelta(), "ns"), + (td64_data.to_pytimedelta(), "us" if has_pandas_3 else "ns"), ], ) def test_timedelta64_conversion(self, values, unit): @@ -1109,8 +1114,8 @@ def test_datetime64_conversion_scalar(self, values, unit): (np.timedelta64(1, "m"), "s"), (np.timedelta64(1, "D"), "s"), (np.timedelta64(1001, "ps"), "ns"), - (pd.Timedelta("1 day"), "ns"), - (timedelta(days=1), "ns"), + (pd.Timedelta("1 day").as_unit("ns"), "ns"), + (timedelta(days=1), "us" if has_pandas_3 else "ns"), ], ) def test_timedelta64_conversion_scalar(self, values, unit): @@ -1135,7 +1140,8 @@ def test_0d_datetime(self): assert v.values == np.datetime64("2000-01-01", expected_unit) # type: ignore[call-overload] @pytest.mark.parametrize( - "values, unit", [(pd.to_timedelta("1s"), "ns"), (np.timedelta64(1, "s"), "s")] + "values, unit", + [(pd.to_timedelta("1s").as_unit("ns"), "ns"), (np.timedelta64(1, "s"), "s")], ) def test_0d_timedelta(self, values, unit): # todo: check, if this test is OK @@ -3158,7 +3164,7 @@ def test_from_pint_wrapping_dask(self, Var): (np.datetime64("2000-01-01", "s"), "s"), (np.array([np.datetime64("2000-01-01", "ns")]), "ns"), (np.array([np.datetime64("2000-01-01", "s")]), "s"), - (pd.date_range("2000", periods=1), "ns"), + (pd.date_range("2000", periods=1, unit="ns"), "ns"), ( datetime(2000, 1, 1), "us" if has_pandas_3 else "ns", @@ -3167,10 +3173,17 @@ def test_from_pint_wrapping_dask(self, Var): np.array([datetime(2000, 1, 1)]), "us" if has_pandas_3 else "ns", ), - (pd.date_range("2000", periods=1, tz=pytz.timezone("America/New_York")), "ns"), + ( + pd.date_range( + "2000", periods=1, tz=pytz.timezone("America/New_York"), unit="ns" + ), + "ns", + ), ( pd.Series( - pd.date_range("2000", periods=1, tz=pytz.timezone("America/New_York")) + pd.date_range( + "2000", periods=1, tz=pytz.timezone("America/New_York"), unit="ns" + ) ), "ns", ), @@ -3245,8 +3258,8 @@ def test_pandas_two_only_datetime_conversion_warnings( (np.array([np.timedelta64(10, "ns")]), "ns"), (np.array([np.timedelta64(10, "s")]), "s"), (pd.timedelta_range("1", periods=1), "ns"), - (timedelta(days=1), "ns"), - (np.array([timedelta(days=1)]), "ns"), + (timedelta(days=1), "us" if has_pandas_3 else "ns"), + (np.array([timedelta(days=1)]), "us" if has_pandas_3 else "ns"), (pd.timedelta_range("1", periods=1).astype("timedelta64[s]"), "s"), ], ids=lambda x: f"{x}",