Skip to content

Commit 017d9a0

Browse files
committed
Bootstrap v3 branch with zarrita (zarr-developers#1584)
* Pull Zarrita into Zarr-Python @ 78274781ad64aef95772eb4b083f7ea9b7d03d06 No code changes to Zarrita were made. * apply zarr lint rules * zarrita -> v3 * v3/abc [wip] * use abcs plus implementation notes
1 parent a81db07 commit 017d9a0

17 files changed

+4090
-0
lines changed

zarr/v3/__init__.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from __future__ import annotations
2+
3+
from typing import Union
4+
5+
import zarr.v3.codecs # noqa: F401
6+
from zarr.v3.array import Array # noqa: F401
7+
from zarr.v3.array_v2 import ArrayV2 # noqa: F401
8+
from zarr.v3.group import Group # noqa: F401
9+
from zarr.v3.group_v2 import GroupV2 # noqa: F401
10+
from zarr.v3.metadata import RuntimeConfiguration, runtime_configuration # noqa: F401
11+
from zarr.v3.store import ( # noqa: F401
12+
LocalStore,
13+
RemoteStore,
14+
Store,
15+
StoreLike,
16+
StorePath,
17+
make_store_path,
18+
)
19+
from zarr.v3.sync import sync as _sync
20+
21+
22+
async def open_auto_async(
23+
store: StoreLike,
24+
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
25+
) -> Union[Array, ArrayV2, Group, GroupV2]:
26+
store_path = make_store_path(store)
27+
try:
28+
return await Group.open_or_array(store_path, runtime_configuration=runtime_configuration_)
29+
except KeyError:
30+
return await GroupV2.open_or_array(store_path, runtime_configuration_)
31+
32+
33+
def open_auto(
34+
store: StoreLike,
35+
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
36+
) -> Union[Array, ArrayV2, Group, GroupV2]:
37+
return _sync(
38+
open_auto_async(store, runtime_configuration_),
39+
runtime_configuration_.asyncio_loop,
40+
)

zarr/v3/abc/__init__.py

Whitespace-only changes.

zarr/v3/abc/array.py

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
from __future__ import annotations
2+
from abc import abstractproperty, abstractmethod, ABC
3+
from typing import Tuple, Any, Dict
4+
5+
import numpy as np
6+
7+
from zarr.v3.abc.store import ReadStore, WriteStore
8+
from zarr.v3.common import Selection
9+
10+
11+
class BaseArray(ABC):
12+
@abstractproperty
13+
def store_path(self) -> str: # TODO: rename to `path`?
14+
"""Path to this array in the underlying store."""
15+
...
16+
17+
@abstractproperty
18+
def dtype(self) -> np.dtype:
19+
"""Data type of the array elements.
20+
21+
Returns
22+
-------
23+
dtype
24+
array data type
25+
"""
26+
...
27+
28+
@abstractproperty
29+
def ndim(self) -> int:
30+
"""Number of array dimensions (axes).
31+
32+
Returns
33+
-------
34+
int
35+
number of array dimensions (axes)
36+
"""
37+
...
38+
39+
@abstractproperty
40+
def shape(self) -> Tuple[int, ...]:
41+
"""Array dimensions.
42+
43+
Returns
44+
-------
45+
tuple of int
46+
array dimensions
47+
"""
48+
...
49+
50+
@abstractproperty
51+
def size(self) -> int:
52+
"""Number of elements in the array.
53+
54+
Returns
55+
-------
56+
int
57+
number of elements in an array.
58+
"""
59+
60+
@abstractproperty
61+
def attrs(self) -> Dict[str, Any]:
62+
"""Array attributes.
63+
64+
Returns
65+
-------
66+
dict
67+
user defined attributes
68+
"""
69+
...
70+
71+
@abstractproperty
72+
def info(self) -> Any:
73+
"""Report some diagnostic information about the array.
74+
75+
Returns
76+
-------
77+
out
78+
"""
79+
...
80+
81+
82+
class AsynchronousArray(BaseArray):
83+
"""This class can be implemented as a v2 or v3 array"""
84+
85+
@classmethod
86+
@abstractmethod
87+
async def from_json(cls, zarr_json: Any, store: ReadStore) -> AsynchronousArray:
88+
...
89+
90+
@classmethod
91+
@abstractmethod
92+
async def open(cls, store: ReadStore) -> AsynchronousArray:
93+
...
94+
95+
@classmethod
96+
@abstractmethod
97+
async def create(cls, store: WriteStore, *, shape, **kwargs) -> AsynchronousArray:
98+
...
99+
100+
@abstractmethod
101+
async def getitem(self, selection: Selection):
102+
...
103+
104+
@abstractmethod
105+
async def setitem(self, selection: Selection, value: np.ndarray) -> None:
106+
...
107+
108+
109+
class SynchronousArray(BaseArray):
110+
"""
111+
This class can be implemented as a v2 or v3 array
112+
"""
113+
114+
@classmethod
115+
@abstractmethod
116+
def from_json(cls, zarr_json: Any, store: ReadStore) -> SynchronousArray:
117+
...
118+
119+
@classmethod
120+
@abstractmethod
121+
def open(cls, store: ReadStore) -> SynchronousArray:
122+
...
123+
124+
@classmethod
125+
@abstractmethod
126+
def create(cls, store: WriteStore, *, shape, **kwargs) -> SynchronousArray:
127+
...
128+
129+
@abstractmethod
130+
def __getitem__(self, selection: Selection): # TODO: type as np.ndarray | scalar
131+
...
132+
133+
@abstractmethod
134+
def __setitem__(self, selection: Selection, value: np.ndarray) -> None:
135+
...
136+
137+
# some day ;)
138+
# @property
139+
# def __array_api_version__(self) -> str:
140+
# return "2022.12"

zarr/v3/abc/codec.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Notes:
2+
# 1. These are missing methods described in the spec. I expected to see these method definitions:
3+
# def compute_encoded_representation_type(self, decoded_representation_type):
4+
# def encode(self, decoded_value):
5+
# def decode(self, encoded_value, decoded_representation_type):
6+
# def partial_decode(self, input_handle, decoded_representation_type, decoded_regions):
7+
# def compute_encoded_size(self, input_size):
8+
# 2. Understand why array metadata is included on all codecs
9+
10+
11+
from __future__ import annotations
12+
13+
from abc import abstractmethod, ABC
14+
from typing import TYPE_CHECKING, Optional
15+
16+
import numpy as np
17+
18+
from zarr.v3.common import BytesLike
19+
20+
21+
if TYPE_CHECKING:
22+
from zarr.v3.metadata import CoreArrayMetadata
23+
24+
25+
class Codec(ABC):
26+
supports_partial_decode: bool
27+
supports_partial_encode: bool
28+
is_fixed_size: bool
29+
array_metadata: CoreArrayMetadata
30+
31+
@abstractmethod
32+
def compute_encoded_size(self, input_byte_length: int) -> int:
33+
pass
34+
35+
def resolve_metadata(self) -> CoreArrayMetadata:
36+
return self.array_metadata
37+
38+
39+
class ArrayArrayCodec(Codec):
40+
@abstractmethod
41+
async def decode(
42+
self,
43+
chunk_array: np.ndarray,
44+
) -> np.ndarray:
45+
pass
46+
47+
@abstractmethod
48+
async def encode(
49+
self,
50+
chunk_array: np.ndarray,
51+
) -> Optional[np.ndarray]:
52+
pass
53+
54+
55+
class ArrayBytesCodec(Codec):
56+
@abstractmethod
57+
async def decode(
58+
self,
59+
chunk_array: BytesLike,
60+
) -> np.ndarray:
61+
pass
62+
63+
@abstractmethod
64+
async def encode(
65+
self,
66+
chunk_array: np.ndarray,
67+
) -> Optional[BytesLike]:
68+
pass
69+
70+
71+
class BytesBytesCodec(Codec):
72+
@abstractmethod
73+
async def decode(
74+
self,
75+
chunk_array: BytesLike,
76+
) -> BytesLike:
77+
pass
78+
79+
@abstractmethod
80+
async def encode(
81+
self,
82+
chunk_array: BytesLike,
83+
) -> Optional[BytesLike]:
84+
pass

zarr/v3/abc/group.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from __future__ import annotations
2+
3+
from abc import abstractproperty, ABC
4+
from collections.abc import MutableMapping
5+
from typing import Dict, Any
6+
7+
8+
class BaseGroup(ABC):
9+
@abstractproperty
10+
def attrs(self) -> Dict[str, Any]:
11+
"""User-defined attributes."""
12+
...
13+
14+
@abstractproperty
15+
def info(self) -> Any: # TODO: type this later
16+
"""Return diagnostic information about the group."""
17+
...
18+
19+
20+
class AsynchronousGroup(BaseGroup):
21+
pass
22+
# TODO: (considering the following api)
23+
# store_path (rename to path?)
24+
# nchildren - number of child groups + arrays
25+
# children (async iterator)
26+
# contains - check if child exists
27+
# getitem - get child
28+
# group_keys (async iterator)
29+
# groups (async iterator)
30+
# array_keys (async iterator)
31+
# arrays (async iterator)
32+
# visit
33+
# visitkeys
34+
# visitvalues
35+
# tree
36+
# create_group
37+
# require_group
38+
# create_groups
39+
# require_groups
40+
# create_dataset
41+
# require_dataset
42+
# create
43+
# empty
44+
# zeros
45+
# ones
46+
# full
47+
# array
48+
# empty_like
49+
# zeros_like
50+
# ones_like
51+
# full_like
52+
# move
53+
54+
55+
class SynchronousGroup(BaseGroup, MutableMapping):
56+
# TODO - think about if we want to keep the MutableMapping abstraction or
57+
pass
58+
# store_path (rename to path?)
59+
# __enter__
60+
# __exit__
61+
# group_keys
62+
# groups
63+
# array_keys
64+
# arrays
65+
# visit
66+
# visitkeys
67+
# visitvalues
68+
# visititems
69+
# tree
70+
# create_group
71+
# require_group
72+
# create_groups
73+
# require_groups
74+
# create_dataset
75+
# require_dataset
76+
# create
77+
# empty
78+
# zeros
79+
# ones
80+
# full
81+
# array
82+
# empty_like
83+
# zeros_like
84+
# ones_like
85+
# full_like
86+
# move

0 commit comments

Comments
 (0)