From 40c85d721a80113d0e363427914b7ff4d70fcd64 Mon Sep 17 00:00:00 2001 From: NoiceHax Date: Sat, 15 Aug 2026 04:54:42 +0530 Subject: [PATCH 1/8] fix: no _FillValue warning for CF coordinate variables NonStringCoder.encode warns when float data is written to an integer dtype without a _FillValue. CF coordinate variables (1D variables named after their dimension) are not allowed to hold missing values, so they never need a _FillValue and the warning is misleading there. Skip the warning when the variable's dims are exactly (name,). Rounding and the dtype cast are untouched, so the encoded output is the same as before. Data variables and multidimensional auxiliary coordinates still warn. Co-authored-by: Claude --- doc/whats-new.rst | 5 +++++ xarray/coding/variables.py | 5 +++++ xarray/tests/test_conventions.py | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 0e74ca1e2fc..6c71d3bd3e6 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -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 `_. +- 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 `_. Documentation diff --git a/xarray/coding/variables.py b/xarray/coding/variables.py index 6a5deb09152..b3749fef7f9 100644 --- a/xarray/coding/variables.py +++ b/xarray/coding/variables.py @@ -635,10 +635,15 @@ 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 (1D variables with the same name as + # their dimension) are not allowed to have missing values, so + # they do not need a _FillValue. + # 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 " diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index fd76aed836b..a0aac08c918 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -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 From 57ae76ee8828f1460854ab23e3bd01dfb7eff730 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 15 Aug 2026 08:14:35 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6c71d3bd3e6..1d257d6fa45 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `_. + By `NoiceHex `_. Documentation From 97c09c0e914abcd0cc726edc5a1f50735656dd3c Mon Sep 17 00:00:00 2001 From: Chandan P <95340276+NoiceHax@users.noreply.github.com> Date: Sat, 15 Aug 2026 15:05:53 +0530 Subject: [PATCH 3/8] Fix CI on the whats-new entry The typos hook rejects the handle in the attribution line, so add it to the people's names allowlist alongside the existing entries, and restore the handle the autofix rewrote. Co-authored-by: Claude --- doc/whats-new.rst | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 1d257d6fa45..6c71d3bd3e6 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `NoiceHex `_. + By `NoiceHax `_. Documentation diff --git a/pyproject.toml b/pyproject.toml index 828bee18fa5..6fad5adacff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -424,6 +424,7 @@ Claus = "Claus" Celles = "Celles" slowy = "slowy" Commun = "Commun" +Noice = "Noice" # Tests Ome = "Ome" From f118d5f915f363d94ecf7b24984c13339060289c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 15 Aug 2026 09:36:25 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6c71d3bd3e6..1d257d6fa45 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `_. + By `NoiceHex `_. Documentation From 02801b894ebba1b359a3165fd9fe6e607047cf0b Mon Sep 17 00:00:00 2001 From: Chandan P <95340276+NoiceHax@users.noreply.github.com> Date: Sat, 15 Aug 2026 15:14:18 +0530 Subject: [PATCH 5/8] Restore the handle in the whats-new attribution The typos allowlist entry is in place now, so the hook accepts it. Co-authored-by: Claude --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 1d257d6fa45..6c71d3bd3e6 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `NoiceHex `_. + By `NoiceHax `_. Documentation From 3196b40bbddab76643ee7b543a8153b5416332de Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 15 Aug 2026 09:44:43 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6c71d3bd3e6..1d257d6fa45 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `_. + By `NoiceHex `_. Documentation From 5faa62c0bca94c071f38e995fbae6d5c95b12a20 Mon Sep 17 00:00:00 2001 From: Chandan P <95340276+NoiceHax@users.noreply.github.com> Date: Sat, 15 Aug 2026 15:23:07 +0530 Subject: [PATCH 7/8] Allowlist the rest of the handle for the typos hook The autofix was rewriting Hax to Hex in the attribution line. Noice was already allowlisted but Hax was not, so add it and restore the handle. Co-authored-by: Claude --- doc/whats-new.rst | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 1d257d6fa45..6c71d3bd3e6 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -73,7 +73,7 @@ Bug Fixes 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 `NoiceHex `_. + By `NoiceHax `_. Documentation diff --git a/pyproject.toml b/pyproject.toml index 6fad5adacff..e1b812bf087 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -425,6 +425,7 @@ Celles = "Celles" slowy = "slowy" Commun = "Commun" Noice = "Noice" +Hax = "Hax" # Tests Ome = "Ome" From d534b268a31aac0a3fc6c5050616ff51a169bfaf Mon Sep 17 00:00:00 2001 From: Deepak Cherian Date: Wed, 19 Aug 2026 14:11:39 -0600 Subject: [PATCH 8/8] Apply suggestion from @dcherian --- xarray/coding/variables.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xarray/coding/variables.py b/xarray/coding/variables.py index b3749fef7f9..42976533819 100644 --- a/xarray/coding/variables.py +++ b/xarray/coding/variables.py @@ -635,9 +635,8 @@ 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 (1D variables with the same name as - # their dimension) are not allowed to have missing values, so - # they do not need a _FillValue. + # 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)