Skip to content

Commit

Permalink
Minor error message edits; add what's new entry
Browse files Browse the repository at this point in the history
  • Loading branch information
spencerkclark committed Dec 31, 2023
1 parent 6ebb917 commit 85f560a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 39 deletions.
4 changes: 4 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Bug fixes

- Reverse index output of bottleneck's rolling move_argmax/move_argmin functions (:issue:`8541`, :pull:`8552`).
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
- Preserve chunks when writing time-like variables to zarr by enabling lazy CF
encoding of time-like variables (:issue:`7132`, :issue:`8230`, :issue:`8432`,
:pull:`8575`). By `Spencer Clark <https://github.com/spencerkclark>`_ and
`Mattia Almansi <https://github.com/malmans2`_.


Documentation
Expand Down
77 changes: 38 additions & 39 deletions xarray/coding/times.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,42 @@ def _division(deltas, delta, floor):
return num


def _cast_to_dtype_if_safe(num: np.ndarray, dtype: np.dtype) -> np.ndarray:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="overflow")
cast_num = np.asarray(num, dtype=dtype)

if np.issubdtype(dtype, np.integer):
if not (num == cast_num).all():
if np.issubdtype(num.dtype, np.floating):
raise ValueError(
f"Not possible to cast all encoded times from "
f"{num.dtype!r} to {dtype!r} without losing precision. "
f"Consider modifying the units such that integer values "
f"can be used, or removing the units and dtype encoding, "
f"at which point xarray will make an appropriate choice."
)
else:
raise OverflowError(
f"Not possible to cast encoded times from "
f"{num.dtype!r} to {dtype!r} without overflow. Consider "
f"removing the dtype encoding, at which point xarray will "
f"make an appropriate choice, or explicitly switching to "
"a larger integer dtype."
)
else:
if np.isinf(cast_num).any():
raise OverflowError(
f"Not possible to cast encoded times from {num.dtype!r} to "
f"{dtype!r} without overflow. Consider removing the dtype "
f"encoding, at which point xarray will make an appropriate "
f"choice, or explicitly switching to a larger floating point "
f"dtype."
)

return cast_num


def encode_cf_datetime(
dates,
units: str | None = None,
Expand All @@ -690,43 +726,6 @@ def encode_cf_datetime(
return _lazily_encode_cf_datetime(dates, units, calendar, dtype)


def _cast_to_dtype_safe(num: np.ndarray, dtype: np.dtype) -> np.ndarray:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="overflow")
cast_num = np.asarray(num, dtype=dtype)

if np.issubdtype(dtype, np.integer):
if not (num == cast_num).all():
if np.issubdtype(num.dtype, np.floating):
raise ValueError(
f"Not possible to cast all encoded times from dtype "
f"{num.dtype!r} to integer dtype {dtype!r} without losing "
f"precision. Consider modifying the units such that "
f"integer values can be used, or removing the units and "
f"dtype encoding, at which point xarray will make an "
f"appropriate choice."
)
else:
raise OverflowError(
f"Not possible to cast encoded times from dtype "
f"{num.dtype!r} to dtype {dtype!r} without overflow. "
f"Consider removing the dtype encoding, at which point "
f"xarray will make an appropriate choice, or explicitly "
f"switching to a larger integer dtype."
)
else:
if np.isinf(cast_num).any():
raise OverflowError(
f"Not possible to cast encoded times from dtype {num.dtype!r} "
f"to dtype {dtype!r} without overflow. Consider removing the "
f"dtype encoding, at which point xarray will make an "
f"appropriate choice, or explicitly switching to a larger "
f"floating point dtype."
)

return cast_num


def _eagerly_encode_cf_datetime(
dates,
units: str | None = None,
Expand Down Expand Up @@ -805,7 +804,7 @@ def _eagerly_encode_cf_datetime(
num = cast_to_int_if_safe(num)

if dtype is not None:
num = _cast_to_dtype_safe(num, dtype)
num = _cast_to_dtype_if_safe(num, dtype)

if called_via_map_blocks:
return num
Expand Down Expand Up @@ -910,7 +909,7 @@ def _eagerly_encode_cf_timedelta(
num = num.values.reshape(timedeltas.shape)

if dtype is not None:
num = _cast_to_dtype_safe(num, dtype)
num = _cast_to_dtype_if_safe(num, dtype)

if called_via_map_blocks:
return num
Expand Down

0 comments on commit 85f560a

Please sign in to comment.