diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 16884b41362..68c2e265faf 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -7,36 +7,7 @@ What's New .. _whats-new.2025.10.1: -v2025.10.1 (unreleased) ------------------------ - -New Features -~~~~~~~~~~~~ - - -Breaking changes -~~~~~~~~~~~~~~~~ - - -Deprecations -~~~~~~~~~~~~ - - -Bug fixes -~~~~~~~~~ - - -Documentation -~~~~~~~~~~~~~ - - -Internal Changes -~~~~~~~~~~~~~~~~ - - -.. _whats-new.2025.10.0: - -v2025.10.0 (October 6, 2025) +v2025.10.1 (October 7, 2025) ---------------------------- This release reverts a breaking change to Xarray's preferred netCDF backend. @@ -45,14 +16,19 @@ Breaking changes ~~~~~~~~~~~~~~~~ - Xarray's default engine for reading/writing netCDF files has been reverted to - prefer netCDF4, which was the default before v2025.09.1. This change - had larger implications for the ecosystem than we anticipated. We are still - considering changing the default in the future, but will be a bit more careful - about the implications. See :issue:`10657` and linked issues for discussion. - The behavior can still be customized, e.g., with + prefer netCDF4 over h5netcdf over scipy, which was the default before + v2025.09.1. This change had larger implications for the ecosystem than we + anticipated. We are still considering changing the default in the future, but + will be a bit more careful about the implications. See :issue:`10657` and + linked issues for discussion. The behavior can still be customized, e.g., with ``xr.set_options(netcdf_engine_order=['h5netcdf', 'netcdf4', 'scipy'])``. By `Stephan Hoyer `_. +New features +~~~~~~~~~~~~ + +- Coordinates are ordered to match dims when displaying Xarray objects. (:pull:`10778`). + By `Julia Signell `_. Bug fixes ~~~~~~~~~ @@ -86,9 +62,6 @@ New Features (:pull:`10624`). By `Stephan Hoyer `_. -- Coordinates are ordered to match dims when displaying Xarray objects. (:pull:`10778`). - By `Julia Signell `_. - Breaking changes ~~~~~~~~~~~~~~~~ diff --git a/xarray/backends/api.py b/xarray/backends/api.py index 3ef75dcd2b2..a6958d6ca60 100644 --- a/xarray/backends/api.py +++ b/xarray/backends/api.py @@ -416,7 +416,7 @@ def open_dataset( or subclass of xarray.backends.BackendEntrypoint, optional Engine to use when reading files. If not provided, the default engine is chosen based on available dependencies, by default preferring - "h5netcdf" over "scipy" over "netcdf4" (customizable via + "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). A custom backend class (a subclass of ``BackendEntrypoint``) can also be used. chunks : int, dict, 'auto' or None, default: None @@ -660,7 +660,7 @@ def open_dataarray( or subclass of xarray.backends.BackendEntrypoint, optional Engine to use when reading files. If not provided, the default engine is chosen based on available dependencies, by default preferring - "h5netcdf" over "scipy" over "netcdf4" (customizable via + "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). A custom backend class (a subclass of ``BackendEntrypoint``) can also be used. chunks : int, dict, 'auto' or None, default: None @@ -1450,7 +1450,7 @@ def open_mfdataset( or subclass of xarray.backends.BackendEntrypoint, optional Engine to use when reading files. If not provided, the default engine is chosen based on available dependencies, by default preferring - "h5netcdf" over "scipy" over "netcdf4" (customizable via + "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). A custom backend class (a subclass of ``BackendEntrypoint``) can also be used. data_vars : {"minimal", "different", "all"} or list of str, default: "all" diff --git a/xarray/backends/writers.py b/xarray/backends/writers.py index a1b02338dca..07745120e36 100644 --- a/xarray/backends/writers.py +++ b/xarray/backends/writers.py @@ -544,10 +544,10 @@ def save_mfdataset( Paths to the netCDF4 group in each corresponding file to which to save datasets (only works for format="NETCDF4"). The groups will be created if necessary. - engine : {"netcdf4", "scipy", "h5netcdf"}, optional + engine : {"netcdf4", "h5netcdf", "scipy"}, optional Engine to use when writing netCDF files. If not provided, the default engine is chosen based on available dependencies, by default - preferring "h5netcdf" over "scipy" over "netcdf4" (customizable via + preferring "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). compute : bool If true compute immediately, otherwise return a diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index c44c0be170e..60979e290b5 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -4168,10 +4168,10 @@ def to_netcdf( group : str, optional Path to the netCDF4 group in the given file to open (only works for format='NETCDF4'). The group(s) will be created if necessary. - engine : {"netcdf4", "scipy", "h5netcdf"}, optional + engine : {"netcdf4", "h5netcdf", "scipy"}, optional Engine to use when writing netCDF files. If not provided, the default engine is chosen based on available dependencies, by default - preferring "h5netcdf" over "scipy" over "netcdf4" (customizable via + preferring "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). encoding : dict, optional Nested dictionary with variable names as keys and dictionaries of diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index f059f41904e..8d2bded3e72 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -2055,10 +2055,10 @@ def to_netcdf( group : str, optional Path to the netCDF4 group in the given file to open (only works for format='NETCDF4'). The group(s) will be created if necessary. - engine : {"netcdf4", "scipy", "h5netcdf"}, optional + engine : {"netcdf4", "h5netcdf", "scipy"}, optional Engine to use when writing netCDF files. If not provided, the default engine is chosen based on available dependencies, by default - preferring "h5netcdf" over "scipy" over "netcdf4" (customizable via + preferring "netcdf4" over "h5netcdf" over "scipy" (customizable via ``netcdf_engine_order`` in ``xarray.set_options()``). encoding : dict, optional Nested dictionary with variable names as keys and dictionaries of diff --git a/xarray/core/options.py b/xarray/core/options.py index 6799f61348d..451070ce7b4 100644 --- a/xarray/core/options.py +++ b/xarray/core/options.py @@ -89,7 +89,7 @@ class T_Options(TypedDict): "enable_cftimeindex": True, "file_cache_maxsize": 128, "keep_attrs": "default", - "netcdf_engine_order": ("h5netcdf", "scipy", "netcdf4"), + "netcdf_engine_order": ("netcdf4", "h5netcdf", "scipy"), "warn_for_unclosed_files": False, "use_bottleneck": True, "use_flox": True, @@ -100,7 +100,7 @@ class T_Options(TypedDict): _JOIN_OPTIONS = frozenset(["inner", "outer", "left", "right", "exact"]) _DISPLAY_OPTIONS = frozenset(["text", "html"]) -_NETCDF_ENGINES = frozenset(["h5netcdf", "scipy", "netcdf4"]) +_NETCDF_ENGINES = frozenset(["netcdf4", "h5netcdf", "scipy"]) def _positive_integer(value: Any) -> bool: @@ -260,11 +260,11 @@ class set_options: * ``False`` : to always discard attrs * ``default`` : to use original logic that attrs should only be kept in unambiguous circumstances - netcdf_engine_order : sequence, default ['h5netcdf', 'scipy', 'netcdf4'] + netcdf_engine_order : sequence, default ['netcdf4', 'h5netcdf', 'scipy'] Preference order of backend engines to use when reading or writing netCDF files with ``open_dataset()`` and ``to_netcdf()`` if ``engine`` is not explicitly specified. May be any permutation or subset of - ``['h5netcdf', 'scipy', 'netcdf4']``. + ``['netcdf4', 'h5netcdf', 'scipy']``. use_bottleneck : bool, default: True Whether to use ``bottleneck`` to accelerate 1D reductions and 1D rolling reduction operations. diff --git a/xarray/tests/test_backends_api.py b/xarray/tests/test_backends_api.py index 5efb0c50d46..1c373f3a00a 100644 --- a/xarray/tests/test_backends_api.py +++ b/xarray/tests/test_backends_api.py @@ -24,20 +24,25 @@ @requires_scipy @requires_h5netcdf def test_get_default_netcdf_write_engine() -> None: + assert xr.get_options()["netcdf_engine_order"] == ("netcdf4", "h5netcdf", "scipy") + engine = get_default_netcdf_write_engine("", format=None) - assert engine == "h5netcdf" + assert engine == "netcdf4" engine = get_default_netcdf_write_engine("", format="NETCDF4") - assert engine == "h5netcdf" + assert engine == "netcdf4" engine = get_default_netcdf_write_engine("", format="NETCDF4_CLASSIC") assert engine == "netcdf4" - engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF4") + engine = get_default_netcdf_write_engine("", format="NETCDF3_CLASSIC") + assert engine == "netcdf4" + + engine = get_default_netcdf_write_engine(io.BytesIO(), format=None) assert engine == "h5netcdf" - engine = get_default_netcdf_write_engine("", format="NETCDF3_CLASSIC") - assert engine == "scipy" + engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF4") + assert engine == "h5netcdf" engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF3_CLASSIC") assert engine == "scipy" @@ -46,11 +51,21 @@ def test_get_default_netcdf_write_engine() -> None: assert engine == "netcdf4" with xr.set_options(netcdf_engine_order=["netcdf4", "scipy", "h5netcdf"]): + engine = get_default_netcdf_write_engine(io.BytesIO(), format=None) + assert engine == "scipy" + + engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF4") + assert engine == "h5netcdf" + + engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF3_CLASSIC") + assert engine == "scipy" + + with xr.set_options(netcdf_engine_order=["h5netcdf", "scipy", "netcdf4"]): engine = get_default_netcdf_write_engine("", format=None) - assert engine == "netcdf4" + assert engine == "h5netcdf" engine = get_default_netcdf_write_engine("", format="NETCDF4") - assert engine == "netcdf4" + assert engine == "h5netcdf" engine = get_default_netcdf_write_engine("", format="NETCDF4_CLASSIC") assert engine == "netcdf4" @@ -59,7 +74,7 @@ def test_get_default_netcdf_write_engine() -> None: assert engine == "h5netcdf" engine = get_default_netcdf_write_engine("", format="NETCDF3_CLASSIC") - assert engine == "netcdf4" + assert engine == "scipy" engine = get_default_netcdf_write_engine(io.BytesIO(), format="NETCDF3_CLASSIC") assert engine == "scipy" @@ -80,8 +95,8 @@ def test_default_engine_h5netcdf(monkeypatch): ValueError, match=re.escape( "cannot write NetCDF files with format='NETCDF3_CLASSIC' because " - "none of the suitable backend libraries (scipy, netCDF4) are installed" - ), + "none of the suitable backend libraries (SUITABLE_BACKENDS) are installed" + ).replace("SUITABLE_BACKENDS", r"(scipy, netCDF4)|(netCDF4, scipy)"), ): get_default_netcdf_write_engine("", format="NETCDF3_CLASSIC")