diff --git a/xarray/backends/zarr.py b/xarray/backends/zarr.py index fe004c212b6..5d6425b37a0 100644 --- a/xarray/backends/zarr.py +++ b/xarray/backends/zarr.py @@ -279,7 +279,7 @@ async def async_getitem(self, key): ) -def _determine_zarr_chunks(enc_chunks, var_chunks, ndim, name): +def _determine_zarr_chunks(enc_chunks, var_chunks, ndim, name, zarr_format): """ Given encoding chunks (possibly None or []) and variable chunks (possibly None or []). @@ -301,15 +301,18 @@ def _determine_zarr_chunks(enc_chunks, var_chunks, ndim, name): # while dask chunks can be variable sized # https://dask.pydata.org/en/latest/array-design.html#chunks if var_chunks and not enc_chunks: + if zarr_format == 3: + return tuple(var_chunks) + if any(len(set(chunks[:-1])) > 1 for chunks in var_chunks): raise ValueError( - "Zarr requires uniform chunk sizes except for final chunk. " + "Zarr v2 requires uniform chunk sizes except for final chunk. " f"Variable named {name!r} has incompatible dask chunks: {var_chunks!r}. " "Consider rechunking using `chunk()`." ) if any((chunks[0] < chunks[-1]) for chunks in var_chunks): raise ValueError( - "Final chunk of Zarr array must be the same size or smaller " + "Final chunk of a Zarr v2 array must be the same size or smaller " f"than the first. Variable named {name!r} has incompatible Dask chunks {var_chunks!r}." "Consider either rechunking using `chunk()` or instead deleting " "or modifying `encoding['chunks']`." @@ -475,6 +478,7 @@ def extract_zarr_variable_encoding( var_chunks=variable.chunks, ndim=variable.ndim, name=name, + zarr_format=zarr_format, ) if _zarr_v3() and chunks is None: chunks = "auto" @@ -853,9 +857,18 @@ def open_store_variable(self, name): ) attributes = dict(attributes) + if hasattr(zarr_array, "metadata"): + chunk_grid = zarr_array.metadata.chunk_grid + chunks = getattr(chunk_grid, "chunk_shapes", None) + # regular chunk grid + if chunks is None: + chunks = chunk_grid.chunk_shape + else: + chunks = zarr_array.chunks + encoding = { - "chunks": zarr_array.chunks, - "preferred_chunks": dict(zip(dimensions, zarr_array.chunks, strict=True)), + "chunks": chunks, + "preferred_chunks": dict(zip(dimensions, chunks, strict=True)), } if _zarr_v3():