From 97c8c18174a8354ced1d22b98d7a8c141c3f9c9d Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:21:46 -0800 Subject: [PATCH] Switch `.dt` to raise an `AttributeError` (#8724) * Switch `.dt` to raise an `AttributeError` Discussion at #8718 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- doc/whats-new.rst | 3 +++ xarray/core/accessor_dt.py | 6 +++++- xarray/tests/test_accessor_dt.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index dc4fb7ae722..b2c4a0b5257 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -82,6 +82,9 @@ Documentation Internal Changes ~~~~~~~~~~~~~~~~ +- ``DataArray.dt`` now raises an ``AttributeError`` rather than a ``TypeError`` + when the data isn't datetime-like. (:issue:`8718`, :pull:`8724`) + By `Maximilian Roos `_. .. _whats-new.2024.01.1: diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index 0745a72af2f..219bca90048 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -616,7 +616,11 @@ def __new__(cls, obj: T_DataArray) -> CombinedDatetimelikeAccessor: # appropriate. Since we're checking the dtypes anyway, we'll just # do all the validation here. if not _contains_datetime_like_objects(obj.variable): - raise TypeError( + # We use an AttributeError here so that `obj.dt` raises an error that + # `getattr` expects; https://github.com/pydata/xarray/issues/8718. It's a + # bit unusual in a `__new__`, but that's the only case where we use this + # class. + raise AttributeError( "'.dt' accessor only available for " "DataArray with datetime64 timedelta64 dtype or " "for arrays containing cftime datetime " diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 387929d3fe9..d751d91df5e 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -145,7 +145,7 @@ def test_not_datetime_type(self) -> None: nontime_data = self.data.copy() int_data = np.arange(len(self.data.time)).astype("int8") nontime_data = nontime_data.assign_coords(time=int_data) - with pytest.raises(TypeError, match=r"dt"): + with pytest.raises(AttributeError, match=r"dt"): nontime_data.time.dt @pytest.mark.filterwarnings("ignore:dt.weekofyear and dt.week have been deprecated") @@ -310,7 +310,7 @@ def test_not_datetime_type(self) -> None: nontime_data = self.data.copy() int_data = np.arange(len(self.data.time)).astype("int8") nontime_data = nontime_data.assign_coords(time=int_data) - with pytest.raises(TypeError, match=r"dt"): + with pytest.raises(AttributeError, match=r"dt"): nontime_data.time.dt @pytest.mark.parametrize(