Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ Bug fixes
- Allow passing both ``other`` and ``drop=True`` arguments to ``xr.DataArray.where``
and ``xr.Dataset.where`` (:pull:`6466`, :pull:`6467`).
By `Michael Delgado <https://github.com/delgadom>`_.
- Ensure dtype encoding attributes are not added or modified on variables that
contain datetime-like values prior to being passed to
:py:func:`xarray.conventions.decode_cf_variable` (:issue:`6453`,
:pull:`6489`). By `Spencer Clark <https://github.com/spencerkclark>`_.

Documentation
~~~~~~~~~~~~~
Expand Down
7 changes: 6 additions & 1 deletion xarray/conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .coding import strings, times, variables
from .coding.variables import SerializationWarning, pop_to
from .core import duck_array_ops, indexing
from .core.common import contains_cftime_datetimes
from .core.common import _contains_datetime_like_objects, contains_cftime_datetimes
from .core.pycompat import is_duck_dask_array
from .core.variable import IndexVariable, Variable, as_variable

Expand Down Expand Up @@ -340,6 +340,11 @@ def decode_cf_variable(
A variable holding the decoded equivalent of var.
"""
var = as_variable(var)

# Ensure datetime-like Variables are passed through unmodified (GH 6453)
if _contains_datetime_like_objects(var):
return var

original_dtype = var.dtype

if decode_timedelta is None:
Expand Down
5 changes: 4 additions & 1 deletion xarray/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,10 @@ def _contains_cftime_datetimes(array) -> bool:

def contains_cftime_datetimes(var) -> bool:
"""Check if an xarray.Variable contains cftime.datetime objects"""
return _contains_cftime_datetimes(var.data)
if var.dtype == np.dtype("O") and var.size > 0:
return _contains_cftime_datetimes(var.data)
else:
return False


def _contains_datetime_like_objects(var) -> bool:
Expand Down
20 changes: 20 additions & 0 deletions xarray/tests/test_conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Dataset,
SerializationWarning,
Variable,
cftime_range,
coding,
conventions,
open_dataset,
Expand Down Expand Up @@ -442,3 +443,22 @@ def test_decode_cf_variable_with_array_units(self) -> None:
v = Variable(["t"], [1, 2, 3], {"units": np.array(["foobar"], dtype=object)})
v_decoded = conventions.decode_cf_variable("test2", v)
assert_identical(v, v_decoded)


def test_decode_cf_variable_timedelta64():
variable = Variable(["time"], pd.timedelta_range("1D", periods=2))
decoded = conventions.decode_cf_variable("time", variable)
assert decoded.encoding == {}


def test_decode_cf_variable_datetime64():
variable = Variable(["time"], pd.date_range("2000", periods=2))
decoded = conventions.decode_cf_variable("time", variable)
assert decoded.encoding == {}


@requires_cftime
def test_decode_cf_variable_cftime():
variable = Variable(["time"], cftime_range("2000", periods=2))
decoded = conventions.decode_cf_variable("time", variable)
assert decoded.encoding == {}