diff --git a/docs/releases.rst b/docs/releases.rst index 88df206c..7283df71 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -17,7 +17,8 @@ Breaking changes - Serialize valid ZarrV3 metadata and require full compressor numcodec config (for :pull:`193`) By `Gustavo Hidalgo `_. -- VirtualiZarr's `ZArray`, `ChunkEntry`, and `Codec` no longer subclasses `zarr.Array`, no longer inherit from `pydantic.BaseModel` (:pull:`xxx`) +- VirtualiZarr's `ZArray`, `ChunkEntry`, and `Codec` no longer subclass + `pydantic.BaseModel` (:pull:`210`) - `ZArray`'s `__init__` signature has changed to match `zarr.Array`'s (:pull:`xxx`) diff --git a/virtualizarr/manifests/manifest.py b/virtualizarr/manifests/manifest.py index 534502aa..e153375b 100644 --- a/virtualizarr/manifests/manifest.py +++ b/virtualizarr/manifests/manifest.py @@ -54,7 +54,7 @@ def to_kerchunk(self) -> tuple[str, int, int]: return (self.path, self.offset, self.length) def dict(self) -> ChunkDictEntry: - return dataclasses.asdict(self) + return ChunkDictEntry(dataclasses.asdict(self)) class ChunkManifest: diff --git a/virtualizarr/tests/test_zarr.py b/virtualizarr/tests/test_zarr.py index 7715d245..6ba44c9b 100644 --- a/virtualizarr/tests/test_zarr.py +++ b/virtualizarr/tests/test_zarr.py @@ -7,7 +7,7 @@ from virtualizarr import ManifestArray, open_virtual_dataset from virtualizarr.manifests.manifest import ChunkManifest -from virtualizarr.zarr import dataset_to_zarr, metadata_from_zarr_json +from virtualizarr.zarr import dataset_to_zarr, metadata_from_zarr_json, ZArray @pytest.fixture @@ -78,3 +78,28 @@ def test_zarr_v3_metadata_conformance(tmpdir, vds_with_manifest_arrays: xr.Datas and len(metadata["codecs"]) > 1 and all(isconfigurable(codec) for codec in metadata["codecs"]) ) + + +def test_replace_partial(): + arr = ZArray(shape=(2, 3), chunks=(1, 1), dtype=np.dtype(" str: zarray_dict["fill_value"] = None return ujson.dumps(zarray_dict) + # ZArray.dict seems to shadow "dict", so need to use __builtins__ in the + # type signature below. def replace( self, - **kwargs: Any, + shape: tuple[int, ...] | None = None, + chunks: tuple[int, ...] | None = None, + dtype: np.dtype | str | None = None, + fill_value: FillValueT = None, + order: Literal["C", "F"] | None = None, + compressor: __builtins__["dict"] | None = None, + filters: list[dict] | None = None, + zarr_format: Literal[2, 3] | None = None, ) -> "ZArray": """ Convenience method to create a new ZArray from an existing one by altering only certain attributes. """ - return dataclasses.replace(self, **kwargs) + replacements = {} + if shape is not None: + replacements["shape"] = shape + if chunks is not None: + replacements["chunks"] = chunks + if dtype is not None: + replacements["dtype"] = dtype + if fill_value is not None: + replacements["fill_value"] = fill_value + if order is not None: + replacements["order"] = order + if compressor is not None: + replacements["compressor"] = compressor + if filters is not None: + replacements["filters"] = filters + if zarr_format is not None: + replacements["zarr_format"] = zarr_format + return dataclasses.replace(self, **replacements) def _v3_codec_pipeline(self) -> list: """