Skip to content
5 changes: 5 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ Bug Fixes
for zarr writes. Existing zarr stores written with the old ``int8`` encoding
are still read correctly. (:issue:`2937`, :pull:`11318`)
By `Evan Lyall <https://github.com/elyall>`_.
- No longer emit a ``SerializationWarning`` about a missing ``_FillValue`` when
encoding a CF coordinate variable (a 1D variable named after its dimension) to
an integer dtype. CF forbids missing values in coordinate variables, so a
``_FillValue`` is not expected there (:issue:`10305`).
By `NoiceHax <https://github.com/NoiceHax>`_.
- Raise an informative ``TypeError`` when a :py:class:`~xarray.Coordinates` object is
passed as a coordinate value, e.g. ``ds.assign_coords({"x": coords})``, instead
of silently creating a broken coordinate. Pass the object directly with
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ Celles = "Celles"
slowy = "slowy"
Commun = "Commun"
Noice = "Noice"
Hax = "Hax"

# Tests
Ome = "Ome"
Expand Down
4 changes: 4 additions & 0 deletions xarray/coding/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,14 @@ def encode(self, variable: Variable, name: T_Name = None) -> Variable:
dtype = np.dtype(encoding.pop("dtype"))
if dtype != variable.dtype:
if np.issubdtype(dtype, np.integer):
# CF coordinate variables are not allowed to have missing values, so
# they do not need a _FillValue. For simplicity we don't warn with 1D dimension coordinates.
# http://cfconventions.org/cf-conventions/cf-conventions.html#missing-data
if (
np.issubdtype(variable.dtype, np.floating)
and "_FillValue" not in variable.attrs
and "missing_value" not in variable.attrs
and dims != (name,)
):
warnings.warn(
f"saving variable {name} with floating "
Expand Down
21 changes: 21 additions & 0 deletions xarray/tests/test_conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,27 @@ def test_missing_fillvalue(self) -> None:
"invalid value encountered in cast" in msg for msg in warning_messages
)

def test_missing_fillvalue_coordinate_variable(self) -> None:
# regression test for GH10305
# CF coordinate variables cannot have missing values, so they do not
# need a _FillValue and should not warn about one being absent
v = Variable(["x"], np.array([0.0, 1.0, 2.0]), encoding={"dtype": "int16"})
with warnings.catch_warnings():
warnings.simplefilter("error")
encoded = conventions.encode_cf_variable(v, name="x")
assert encoded.dtype == np.dtype("int16")

def test_missing_fillvalue_non_coordinate_variable(self) -> None:
# data variables and multidimensional (auxiliary) coordinates may hold
# missing values, so they still warn
v = Variable(["x"], np.array([0.0, 1.0, 2.0]), encoding={"dtype": "int16"})
with pytest.warns(SerializationWarning, match="floating point data"):
conventions.encode_cf_variable(v, name="data")

v2d = Variable(["y", "x"], np.zeros((2, 3)), encoding={"dtype": "int16"})
with pytest.warns(SerializationWarning, match="floating point data"):
conventions.encode_cf_variable(v2d, name="lat")

def test_multidimensional_coordinates(self) -> None:
# regression test for GH1763
# Set up test case with coordinates that have overlapping (but not
Expand Down
Loading