Skip to content

Commit 455b4f9

Browse files
LDeakind-v-b
andauthored
feat: add from_array_metadata_and_store to CodecPipeline (#3233)
* feat: add `from_array_metadata_and_store` to `CodecPipeline` This enables fancy `CodecPipeline` implementations like `zarrs-python` to support a broader range of Zarr arrays and to construct store wrappers on initialisation. * make `store` keyword-only Co-authored-by: Davis Bennett <davis.v.bennett@gmail.com> * changelog --------- Co-authored-by: Davis Bennett <davis.v.bennett@gmail.com>
1 parent ea4d7e9 commit 455b4f9

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

changes/3233.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add an alternate `from_array_metadata_and_store` constructor to `CodecPipeline`.

src/zarr/abc/codec.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
from collections.abc import Awaitable, Callable, Iterable
1313
from typing import Self
1414

15-
from zarr.abc.store import ByteGetter, ByteSetter
15+
from zarr.abc.store import ByteGetter, ByteSetter, Store
1616
from zarr.core.array_spec import ArraySpec
1717
from zarr.core.chunk_grids import ChunkGrid
1818
from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType
1919
from zarr.core.indexing import SelectorTuple
20+
from zarr.core.metadata import ArrayMetadata
2021

2122
__all__ = [
2223
"ArrayArrayCodec",
@@ -281,6 +282,25 @@ def from_codecs(cls, codecs: Iterable[Codec]) -> Self:
281282
"""
282283
...
283284

285+
@classmethod
286+
def from_array_metadata_and_store(cls, array_metadata: ArrayMetadata, store: Store) -> Self:
287+
"""Creates a codec pipeline from array metadata and a store path.
288+
289+
Raises NotImplementedError by default, indicating the CodecPipeline must be created with from_codecs instead.
290+
291+
Parameters
292+
----------
293+
array_metadata : ArrayMetadata
294+
store : Store
295+
296+
Returns
297+
-------
298+
Self
299+
"""
300+
raise NotImplementedError(
301+
f"'{type(cls).__name__}' does not implement CodecPipeline.from_array_metadata_and_store."
302+
)
303+
284304
@property
285305
@abstractmethod
286306
def supports_partial_decode(self) -> bool: ...

src/zarr/core/array.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,15 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
192192
raise TypeError # pragma: no cover
193193

194194

195-
def create_codec_pipeline(metadata: ArrayMetadata) -> CodecPipeline:
195+
def create_codec_pipeline(metadata: ArrayMetadata, *, store: Store | None = None) -> CodecPipeline:
196+
if store is not None:
197+
try:
198+
return get_pipeline_class().from_array_metadata_and_store(
199+
array_metadata=metadata, store=store
200+
)
201+
except NotImplementedError:
202+
pass
203+
196204
if isinstance(metadata, ArrayV3Metadata):
197205
return get_pipeline_class().from_codecs(metadata.codecs)
198206
elif isinstance(metadata, ArrayV2Metadata):
@@ -311,7 +319,11 @@ def __init__(
311319
object.__setattr__(self, "metadata", metadata_parsed)
312320
object.__setattr__(self, "store_path", store_path)
313321
object.__setattr__(self, "_config", config_parsed)
314-
object.__setattr__(self, "codec_pipeline", create_codec_pipeline(metadata=metadata_parsed))
322+
object.__setattr__(
323+
self,
324+
"codec_pipeline",
325+
create_codec_pipeline(metadata=metadata_parsed, store=store_path.store),
326+
)
315327

316328
# this overload defines the function signature when zarr_format is 2
317329
@overload

0 commit comments

Comments
 (0)