Skip to content

Commit b133fdc

Browse files
TomAugspurgerrabernatjhammandcherian
authored
Compatibility for zarr-python 3.x (#9552)
* Remove zarr pin * Define zarr_v3 helper * zarr-v3: filters / compressors -> codecs * zarr-v3: update tests to avoid values equal to fillValue * Various test fixes * zarr_version fixes * removed open_consolidated workarounds * removed _store_version check * pass through zarr_version * fixup! zarr-v3: filters / compressors -> codecs * fixup! fixup! zarr-v3: filters / compressors -> codecs * fixup * path / key normalization in set_variables * fixes * workaround nested consolidated metadata * test: avoid fill_value * test: Adjust call counts * zarr-python 3.x Array.resize doesn't mutate * test compatibility - skip write_empty_chunks on 3.x - update patch targets * skip ZipStore with_mode * test: more fill_value avoidance * test: more fill_value avoidance * v3 compat for instrumented test * Handle zarr_version / zarr_format deprecation * wip * most Zarr tests passing * unskip tests * add custom Zarr _FillValue encoding / decoding * relax dtype comparison in test_roundtrip_empty_vlen_string_array * fix test_explicitly_omit_fill_value_via_encoding_kwarg * fix test_append_string_length_mismatch_raises * fix test_check_encoding_is_consistent_after_append for v3 * skip roundtrip_endian for zarr v3 * unskip datetimes and fix test_compressor_encoding * unskip tests * add back dtype skip * point upstream to v3 branch * Create temporary directory before using it * Avoid zarr.storage.zip on v2 * fixed close_store_on_close bug * Remove workaround, fixed upstream * Restore original `w` mode. * workaround for store closing with mode=w * typing fixes * compat * Remove unnecessary pop * fixed skip * fixup types * fixup types * [test-upstream] * Update install-upstream-wheels.sh * set use_consolidated to false when user provides consolidated=False * fix: import consolidated_metadata from package root * fix: relax instrumented store checks for v3 * Adjust 2.18.3 thresholds * skip datatree zarr tests w/ zarr 3 for now * fixed kvstore usage * typing fixes * move zarr.codecs import * fixup ignores * storage options fix, skip * fixed types * Update ci/install-upstream-wheels.sh * type fixes * whats-new * Update xarray/tests/test_backends_datatree.py * fix type import * set mapper, chunk_mapper * Pass through zarr_format * Fixup * more cleanup * revert test changes * Update xarray/backends/zarr.py * cleanup * update docstring * fix rtd * tweak --------- Co-authored-by: Ryan Abernathey <ryan.abernathey@gmail.com> Co-authored-by: Joe Hamman <joe@earthmover.io> Co-authored-by: Deepak Cherian <dcherian@users.noreply.github.com> Co-authored-by: Deepak Cherian <deepak@cherian.net>
1 parent 4798707 commit b133fdc

17 files changed

+674
-245
lines changed

ci/install-upstream-wheels.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ python -m pip install \
4545
--pre \
4646
--upgrade \
4747
pyarrow
48-
# manually install `pint` to pull in new dependencies
49-
python -m pip install --upgrade pint
48+
# manually install `pint`, `donfig`, and `crc32c` to pull in new dependencies
49+
python -m pip install --upgrade pint donfig crc32c
5050
python -m pip install \
5151
--no-deps \
5252
--upgrade \
5353
git+https://github.com/dask/dask \
5454
git+https://github.com/dask/dask-expr \
5555
git+https://github.com/dask/distributed \
56-
git+https://github.com/zarr-developers/zarr.git@main \
56+
git+https://github.com/zarr-developers/zarr \
5757
git+https://github.com/Unidata/cftime \
5858
git+https://github.com/pypa/packaging \
5959
git+https://github.com/hgrecco/pint \

doc/user-guide/io.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,8 +823,9 @@ For example:
823823
.. ipython:: python
824824
825825
import zarr
826+
from numcodecs.blosc import Blosc
826827
827-
compressor = zarr.Blosc(cname="zstd", clevel=3, shuffle=2)
828+
compressor = Blosc(cname="zstd", clevel=3, shuffle=2)
828829
ds.to_zarr("foo.zarr", encoding={"foo": {"compressor": compressor}})
829830
830831
.. note::

doc/whats-new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ New Features
3939
By `Holly Mandel <https://github.com/hollymandel>`_.
4040
- Implement handling of complex numbers (netcdf4/h5netcdf) and enums (h5netcdf) (:issue:`9246`, :issue:`3297`, :pull:`9509`).
4141
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
42+
- Support for Zarr-Python 3 (:issue:`95515`, :pull:`9552`).
43+
By `Tom Augspurger <https://github.com/TomAugspurger>`_,
44+
`Ryan Abernathey <https://github.com/rabernat>`_ and
45+
`Joe Hamman <https://github.com/jhamman>`_.
4246

4347
Breaking changes
4448
~~~~~~~~~~~~~~~~

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ dev = [
4949
"sphinx_autosummary_accessors",
5050
"xarray[complete]",
5151
]
52-
io = ["netCDF4", "h5netcdf", "scipy", 'pydap; python_version<"3.10"', "zarr<3", "fsspec", "cftime", "pooch"]
52+
io = ["netCDF4", "h5netcdf", "scipy", 'pydap; python_version<"3.10"', "zarr", "fsspec", "cftime", "pooch"]
5353
etc = ["sparse"]
5454
parallel = ["dask[complete]"]
5555
viz = ["cartopy", "matplotlib", "nc-time-axis", "seaborn"]
@@ -124,6 +124,7 @@ module = [
124124
"nc_time_axis.*",
125125
"netCDF4.*",
126126
"netcdftime.*",
127+
"numcodecs.*",
127128
"opt_einsum.*",
128129
"pint.*",
129130
"pooch.*",

xarray/backends/api.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
_normalize_path,
3434
)
3535
from xarray.backends.locks import _get_scheduler
36+
from xarray.backends.zarr import _zarr_v3
3637
from xarray.core import indexing
3738
from xarray.core.combine import (
3839
_infer_concat_order_from_positions,
@@ -1685,6 +1686,7 @@ def to_zarr(
16851686
safe_chunks: bool = True,
16861687
storage_options: dict[str, str] | None = None,
16871688
zarr_version: int | None = None,
1689+
zarr_format: int | None = None,
16881690
write_empty_chunks: bool | None = None,
16891691
chunkmanager_store_kwargs: dict[str, Any] | None = None,
16901692
) -> backends.ZarrStore | Delayed:
@@ -1703,21 +1705,28 @@ def to_zarr(
17031705
store = _normalize_path(store)
17041706
chunk_store = _normalize_path(chunk_store)
17051707

1708+
kwargs = {}
17061709
if storage_options is None:
17071710
mapper = store
17081711
chunk_mapper = chunk_store
17091712
else:
1710-
from fsspec import get_mapper
1711-
17121713
if not isinstance(store, str):
17131714
raise ValueError(
17141715
f"store must be a string to use storage_options. Got {type(store)}"
17151716
)
1716-
mapper = get_mapper(store, **storage_options)
1717-
if chunk_store is not None:
1718-
chunk_mapper = get_mapper(chunk_store, **storage_options)
1719-
else:
1717+
1718+
if _zarr_v3():
1719+
kwargs["storage_options"] = storage_options
1720+
mapper = store
17201721
chunk_mapper = chunk_store
1722+
else:
1723+
from fsspec import get_mapper
1724+
1725+
mapper = get_mapper(store, **storage_options)
1726+
if chunk_store is not None:
1727+
chunk_mapper = get_mapper(chunk_store, **storage_options)
1728+
else:
1729+
chunk_mapper = chunk_store
17211730

17221731
if encoding is None:
17231732
encoding = {}
@@ -1747,13 +1756,6 @@ def to_zarr(
17471756
# validate Dataset keys, DataArray names
17481757
_validate_dataset_names(dataset)
17491758

1750-
if zarr_version is None:
1751-
# default to 2 if store doesn't specify its version (e.g. a path)
1752-
zarr_version = int(getattr(store, "_store_version", 2))
1753-
1754-
if consolidated is None and zarr_version > 2:
1755-
consolidated = False
1756-
17571759
if mode == "r+":
17581760
already_consolidated = consolidated
17591761
consolidate_on_close = False
@@ -1773,7 +1775,9 @@ def to_zarr(
17731775
safe_chunks=safe_chunks,
17741776
stacklevel=4, # for Dataset.to_zarr()
17751777
zarr_version=zarr_version,
1778+
zarr_format=zarr_format,
17761779
write_empty=write_empty_chunks,
1780+
**kwargs,
17771781
)
17781782

17791783
if region is not None:

0 commit comments

Comments
 (0)