Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions xarray/backends/scipy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,18 @@ def __setitem__(self, key, value):
# TODO: Remove this after upstreaming the fixes to scipy.
class _PickleWorkaround:
flush_only_netcdf_file: type[scipy.io.netcdf_file]
_initialized: bool = False

@classmethod
def add_cls(cls, new_class: type[Any]) -> None:
setattr(cls, new_class.__name__, new_class)
new_class.__qualname__ = cls.__qualname__ + "." + new_class.__name__
# Only set the class once to ensure pickling stability.
# Each call to _open_scipy_netcdf creates a new class, but we only need
# the first one. Subsequent calls would overwrite the class definition,
# breaking pickle's class-identity check for instances created earlier.
if not cls._initialized:
setattr(cls, new_class.__name__, new_class)
new_class.__qualname__ = cls.__qualname__ + "." + new_class.__name__
cls._initialized = True


def _open_scipy_netcdf(
Expand Down
8 changes: 8 additions & 0 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2523,6 +2523,14 @@ def test_pickle_open_dataset_from_bytes(self) -> None:
with pickle.loads(pickle.dumps(roundtrip)) as unpickled:
assert_identical(unpickled, original)

def test_pickle_open_dataset_after_multiple_opens(self) -> None:
original = Dataset({"foo": ("x", [1, 2, 3])})
netcdf_bytes = bytes(original.to_netcdf(engine=self.engine))
with open_dataset(netcdf_bytes, engine=self.engine) as ds1:
with open_dataset(netcdf_bytes, engine=self.engine):
with pickle.loads(pickle.dumps(ds1)) as unpickled:
assert_identical(unpickled, original)

def test_compute_false(self) -> None:
original = create_test_data()
with pytest.raises(
Expand Down
Loading