From 8b7efd975a86b0946293226034a8c50c32202958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20F=C3=A9rauge?= Date: Mon, 4 May 2026 14:53:14 +0200 Subject: [PATCH 1/3] TST: cover default engine selection in to_cfradial2 * A test 'tests/io/test_cfradial2.py::test_to_cfradial2_selects_default_engine' was added to cover default engine selection in 'to_cfradial2'. --- tests/io/test_cfradial2.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/io/test_cfradial2.py b/tests/io/test_cfradial2.py index 698a68ee..8fa92c72 100644 --- a/tests/io/test_cfradial2.py +++ b/tests/io/test_cfradial2.py @@ -8,6 +8,7 @@ import xradar as xd from xradar.io.backends import cfradial2 as cf2 +from xradar.io.export import cfradial2 as export_cf2 def _write_institutional_cfradial2(outfile): @@ -138,6 +139,37 @@ def test_open_cfradial2_invalid_path(): xd.io.open_cfradial2_datatree("missing-cfradial2-file.nc") +@pytest.mark.parametrize( + ("available", "expected_engine"), + [ + ("netCDF4", "netcdf4"), + ("h5netcdf", "h5netcdf"), + ], +) +def test_to_cfradial2_selects_default_engine( + monkeypatch, tmp_path, available, expected_engine +): + # build a tiny DataTree with the minimum structure needed for export, and a root history attribute since export appends to it + dtree = xr.DataTree.from_dict({"/": xr.Dataset(attrs={"history": ""})}) + + # monkeypatch has_import to simulate different available engines, and ensure that the expected one is selected when engine=None + monkeypatch.setattr(export_cf2, "has_import", lambda name: name == available) + + # monkeypatch DataTree.to_netcdf to avoid writing a real file and let the test intercept the `engine` argument + seen = {} + + def _capture_to_netcdf(self, filename, engine=None, **kwargs): + seen["engine"] = engine + + monkeypatch.setattr(xr.DataTree, "to_netcdf", _capture_to_netcdf, raising=True) + + # call to_cfradial2 with engine=None, which should trigger the default engine selection logic + export_cf2.to_cfradial2(dtree, tmp_path / "out.nc", engine=None) + + # does the intercepted call to to_netcdf have the expected engine ? + assert seen["engine"] == expected_engine + + @pytest.mark.parametrize( ("name", "expected"), [ From 830f81d38faf02594799f7bca06f0dc545951bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20F=C3=A9rauge?= Date: Mon, 4 May 2026 15:44:24 +0200 Subject: [PATCH 2/3] FIX: correct engine assignment in to_cfradial2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Two typos in file ‘xradar/io/export/cfradial2.py’ were corrected in order to enable default engine selection. --- xradar/io/export/cfradial2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xradar/io/export/cfradial2.py b/xradar/io/export/cfradial2.py index 019aa7d6..66ab8b1b 100644 --- a/xradar/io/export/cfradial2.py +++ b/xradar/io/export/cfradial2.py @@ -58,9 +58,9 @@ def to_cfradial2(dtree, filename, engine=None, timestep=None): """ if engine is None: if has_import("netCDF4"): - engine == "netcdf4" + engine = "netcdf4" elif has_import("h5netcdf"): - engine == "h5netcdf" + engine = "h5netcdf" else: raise ImportError( "xradar: ``netCDF4`` or ``h5netcdf`` needed to perform this operation." From 7e332f8cf655531bb10f914c721566fc7a01faaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20F=C3=A9rauge?= Date: Tue, 5 May 2026 16:11:36 +0200 Subject: [PATCH 3/3] DOC: add history.md entry for default engine fix in to_cfradial2 --- docs/history.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/history.md b/docs/history.md index 9b28eb15..633f5e2d 100644 --- a/docs/history.md +++ b/docs/history.md @@ -2,6 +2,7 @@ ## Development +* FIX: ensure `to_cfradial2` correctly selects the default storage engine when none is provided, ({pull}`378`) by [@chfer](https://github.com/chfer) * DOC: Add projection comparison and cartopy map examples to ``Georeference_TargetCRS`` notebook by [@syedhamidali](https://github.com/syedhamidali) * DOC: Add full-form descriptions for all supported radar formats in README.md by [@syedhamidali](https://github.com/syedhamidali) * ADD: India Meteorological Department (IMD) radar NetCDF reader (``IMDBackendEntrypoint``, ``open_imd_datatree``). IMD stores one sweep per file; ``open_imd_datatree`` accepts a single file or a list of files to assemble a multi-sweep volume ({issue}`368`, {pull}`367`) by [@syedhamidali](https://github.com/syedhamidali)