Skip to content

Commit

Permalink
Remove attrs (#1660)
Browse files Browse the repository at this point in the history
* begin removing attrs in favor of frozen dataclasses

* remove runtime_configuration from corearraymetadata; rename CodecMetadata to NamedConfig; turn chunk encoding into stand-alone functions; put codecs on ArrayMetadata instead of just CodecMetadata; add runtime_configuration parameter to codec encode / decode methods; add parsers to codecs

* add typing_extensions dependency

* remove CodecMetadatas and data_types; move basic parsers to common

* feat: base to_dict method that actually works

* Making Codec classes self-contained

* fixes

* chunk_grids

* chunk key encodings

* dry-er parse_*

* serialize to enums

* ruff

* organize imports

* rm src/zarr/v3/codecs/common.py

* cleanup error messages

* better codec evolve

* __init__ types

* add validation to RuntimeConfiguration.__init__; create a validator for c / f order; add order to ArrayV2Metadata.__init__

* import Dict at runtime

* fix parse_dimension_names

* add tests; tweak parse_name function; adjust some exception messages

* fix shapelike parser and tests; clean up imports

* typing

* improve typing

* blacken test_common

---------

Co-authored-by: Norman Rzepka <code@normanrz.com>
  • Loading branch information
d-v-b and normanrz committed Feb 19, 2024
1 parent c578963 commit 76c3450
Show file tree
Hide file tree
Showing 27 changed files with 1,812 additions and 1,243 deletions.
6 changes: 5 additions & 1 deletion pyproject.toml
Expand Up @@ -92,8 +92,12 @@ extra-dependencies = [
"coverage",
"pytest",
"pytest-cov",
"msgpack",
"lmdb",
"zstandard",
"crc32c",
"pytest-asyncio",
"mypy",
"typing_extensions"
]
features = ["extra"]

Expand Down
22 changes: 14 additions & 8 deletions src/zarr/v3/__init__.py
Expand Up @@ -3,10 +3,11 @@
from typing import Union

import zarr.v3.codecs # noqa: F401
from zarr.v3.array import Array # noqa: F401
from zarr.v3.array_v2 import ArrayV2 # noqa: F401
from zarr.v3.group import Group # noqa: F401
from zarr.v3.metadata import RuntimeConfiguration, runtime_configuration # noqa: F401
from zarr.v3.array import Array, AsyncArray # noqa: F401
from zarr.v3.array_v2 import ArrayV2
from zarr.v3.config import RuntimeConfiguration # noqa: F401
from zarr.v3.group import AsyncGroup, Group # noqa: F401
from zarr.v3.metadata import runtime_configuration # noqa: F401
from zarr.v3.store import ( # noqa: F401
StoreLike,
make_store_path,
Expand All @@ -17,19 +18,24 @@
async def open_auto_async(
store: StoreLike,
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
) -> Union[Array, ArrayV2, Group]:
) -> Union[AsyncArray, AsyncGroup]:
store_path = make_store_path(store)
try:
return await Array.open(store_path, runtime_configuration=runtime_configuration_)
return await AsyncArray.open(store_path, runtime_configuration=runtime_configuration_)
except KeyError:
return await Group.open(store_path, runtime_configuration=runtime_configuration_)
return await AsyncGroup.open(store_path, runtime_configuration=runtime_configuration_)


def open_auto(
store: StoreLike,
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
) -> Union[Array, ArrayV2, Group]:
return _sync(
object = _sync(
open_auto_async(store, runtime_configuration_),
runtime_configuration_.asyncio_loop,
)
if isinstance(object, AsyncArray):
return Array(object)
if isinstance(object, AsyncGroup):
return Group(object)
raise TypeError(f"Unexpected object type. Got {type(object)}.")
32 changes: 10 additions & 22 deletions src/zarr/v3/abc/codec.py
@@ -1,45 +1,33 @@
from __future__ import annotations

from abc import abstractmethod, ABC
from typing import TYPE_CHECKING, Optional, Type
from abc import abstractmethod
from typing import TYPE_CHECKING, Optional

import numpy as np
from zarr.v3.abc.metadata import Metadata

from zarr.v3.common import BytesLike, SliceSelection
from zarr.v3.common import ArraySpec
from zarr.v3.store import StorePath


if TYPE_CHECKING:
from zarr.v3.metadata import (
ArraySpec,
ArrayMetadata,
DataType,
CodecMetadata,
RuntimeConfiguration,
)
from typing_extensions import Self
from zarr.v3.common import BytesLike, SliceSelection
from zarr.v3.metadata import ArrayMetadata
from zarr.v3.config import RuntimeConfiguration


class Codec(ABC):
class Codec(Metadata):
is_fixed_size: bool

@classmethod
@abstractmethod
def get_metadata_class(cls) -> Type[CodecMetadata]:
pass

@classmethod
@abstractmethod
def from_metadata(cls, codec_metadata: CodecMetadata) -> Codec:
pass

@abstractmethod
def compute_encoded_size(self, input_byte_length: int, chunk_spec: ArraySpec) -> int:
pass

def resolve_metadata(self, chunk_spec: ArraySpec) -> ArraySpec:
return chunk_spec

def evolve(self, *, ndim: int, data_type: DataType) -> Codec:
def evolve(self, array_spec: ArraySpec) -> Self:
return self

def validate(self, array_metadata: ArrayMetadata) -> None:
Expand Down
44 changes: 44 additions & 0 deletions src/zarr/v3/abc/metadata.py
@@ -0,0 +1,44 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Sequence

if TYPE_CHECKING:
from typing import Dict
from typing_extensions import Self

from dataclasses import fields

from zarr.v3.common import JSON


class Metadata:
def to_dict(self) -> JSON:
"""
Recursively serialize this model to a dictionary.
This method inspects the fields of self and calls `x.to_dict()` for any fields that
are instances of `Metadata`. Sequences of `Metadata` are similarly recursed into, and
the output of that recursion is collected in a list.
"""
...
out_dict = {}
for field in fields(self):
key = field.name
value = getattr(self, key)
if isinstance(value, Metadata):
out_dict[field.name] = getattr(self, field.name).to_dict()
elif isinstance(value, str):
out_dict[key] = value
elif isinstance(value, Sequence):
out_dict[key] = [v.to_dict() if isinstance(v, Metadata) else v for v in value]
else:
out_dict[key] = value

return out_dict

@classmethod
def from_dict(cls, data: Dict[str, JSON]) -> Self:
"""
Create an instance of the model from a dictionary
"""
...

return cls(**data)

0 comments on commit 76c3450

Please sign in to comment.