Skip to content

Commit

Permalink
Fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Augspurger committed Aug 5, 2024
1 parent 04ac60e commit 0fd50e8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
3 changes: 2 additions & 1 deletion docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Breaking changes

- Serialize valid ZarrV3 metadata and require full compressor numcodec config (for :pull:`193`)
By `Gustavo Hidalgo <https://github.com/ghidalgo3>`_.
- 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`)


Expand Down
2 changes: 1 addition & 1 deletion virtualizarr/manifests/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
27 changes: 26 additions & 1 deletion virtualizarr/tests/test_zarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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("<i8"))
result = arr.replace(chunks=(2, 3))
expected = ZArray(shape=(2, 3), chunks=(2, 3), dtype=np.dtype("<i8"))
assert result == expected
assert result.shape == (2, 3)
assert result.chunks == (2, 3)

def test_replace_total():
arr = ZArray(shape=(2, 3), chunks=(1, 1), dtype=np.dtype("<i8"))
kwargs = dict(
shape=(4, 4),
chunks=(2, 2),
dtype=np.dtype("<f8"),
fill_value=-1.0,
order="F",
compressor={"id": "zlib", "level": 1},
filters=[{"id": "blosc", "clevel": 5}],
zarr_format=3,
)
result = arr.replace(**kwargs)
expected = ZArray(**kwargs)
assert result == expected
31 changes: 29 additions & 2 deletions virtualizarr/zarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import (
TYPE_CHECKING,
Any,
Dict,
Literal,
NewType,
Optional,
Expand Down Expand Up @@ -111,14 +112,40 @@ def to_kerchunk_json(self) -> 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:
"""
Expand Down

0 comments on commit 0fd50e8

Please sign in to comment.