From 3599f873d65d96488e30a47374ca36039006f8d5 Mon Sep 17 00:00:00 2001 From: Lukas Bindreiter Date: Wed, 12 Oct 2022 22:17:27 +0200 Subject: [PATCH] Update open_dataset backend to ensure compatibility with new explicit index model (#7150) * Update open_dataset backend to ensure compatibility with new explicit index model * Avoid generation of Indexes object * Add test ensuring backend compatibility with multiindices * Update xarray/tests/test_backends_api.py * Use stack to construct multi index in test * Mention open_dataset backend multi-index compatibility in whats-new * remove _create_multiindex utility function * remove pandas import * Update doc/whats-new.rst Co-authored-by: Deepak Cherian Co-authored-by: Benoit Bovy Co-authored-by: Benoit Bovy --- doc/whats-new.rst | 2 ++ xarray/backends/api.py | 2 +- xarray/tests/test_backends_api.py | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6b34f147735..52a6577b47f 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -70,6 +70,8 @@ Bug fixes :py:meth:`DataArray.to_index` for multi-index levels (convert to single index). (:issue:`6836`, :pull:`7105`) By `BenoƮt Bovy `_. +- Support for open_dataset backends that return datasets containing multi-indexes (:issue:`7139`, :pull:`7150`) + By `Lukas Bindreiter `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/backends/api.py b/xarray/backends/api.py index 3e34af08e27..13bcf046ac3 100644 --- a/xarray/backends/api.py +++ b/xarray/backends/api.py @@ -234,7 +234,7 @@ def _get_mtime(filename_or_obj): def _protect_dataset_variables_inplace(dataset, cache): for name, variable in dataset.variables.items(): - if name not in variable.dims: + if name not in dataset._indexes: # no need to protect IndexVariable objects data = indexing.CopyOnWriteArray(variable._data) if cache: diff --git a/xarray/tests/test_backends_api.py b/xarray/tests/test_backends_api.py index e14234bcaf9..efff86d7683 100644 --- a/xarray/tests/test_backends_api.py +++ b/xarray/tests/test_backends_api.py @@ -48,6 +48,25 @@ def open_dataset( assert_identical(expected, actual) +def test_multiindex() -> None: + # GH7139 + # Check that we properly handle backends that change index variables + dataset = xr.Dataset(coords={"coord1": ["A", "B"], "coord2": [1, 2]}) + dataset = dataset.stack(z=["coord1", "coord2"]) + + class MultiindexBackend(xr.backends.BackendEntrypoint): + def open_dataset( + self, + filename_or_obj, + drop_variables=None, + **kwargs, + ) -> xr.Dataset: + return dataset.copy(deep=True) + + loaded = xr.open_dataset("fake_filename", engine=MultiindexBackend) + assert_identical(dataset, loaded) + + class PassThroughBackendEntrypoint(xr.backends.BackendEntrypoint): """Access an object passed to the `open_dataset` method."""