Skip to content

Bootstrap v3 branch with zarrita #1584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions zarr/v3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from __future__ import annotations

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.group_v2 import GroupV2 # noqa: F401
from zarr.v3.metadata import RuntimeConfiguration, runtime_configuration # noqa: F401
from zarr.v3.store import ( # noqa: F401
LocalStore,
RemoteStore,
Store,
StoreLike,
StorePath,
make_store_path,
)
from zarr.v3.sync import sync as _sync


async def open_auto_async(
store: StoreLike,
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
) -> Union[Array, ArrayV2, Group, GroupV2]:
store_path = make_store_path(store)
try:
return await Group.open_or_array(store_path, runtime_configuration=runtime_configuration_)
except KeyError:
return await GroupV2.open_or_array(store_path, runtime_configuration_)


def open_auto(
store: StoreLike,
runtime_configuration_: RuntimeConfiguration = RuntimeConfiguration(),
) -> Union[Array, ArrayV2, Group, GroupV2]:
return _sync(
open_auto_async(store, runtime_configuration_),
runtime_configuration_.asyncio_loop,
)
Empty file added zarr/v3/abc/__init__.py
Empty file.
140 changes: 140 additions & 0 deletions zarr/v3/abc/array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
from __future__ import annotations
from abc import abstractproperty, abstractmethod, ABC
from typing import Tuple, Any, Dict

import numpy as np

from zarr.v3.abc.store import ReadStore, WriteStore
from zarr.v3.common import Selection


class BaseArray(ABC):
@abstractproperty
def store_path(self) -> str: # TODO: rename to `path`?
"""Path to this array in the underlying store."""
...

@abstractproperty
def dtype(self) -> np.dtype:
"""Data type of the array elements.

Returns
-------
dtype
array data type
"""
...

@abstractproperty
def ndim(self) -> int:
"""Number of array dimensions (axes).

Returns
-------
int
number of array dimensions (axes)
"""
...

@abstractproperty
def shape(self) -> Tuple[int, ...]:
"""Array dimensions.

Returns
-------
tuple of int
array dimensions
"""
...

@abstractproperty
def size(self) -> int:
"""Number of elements in the array.

Returns
-------
int
number of elements in an array.
"""

@abstractproperty
def attrs(self) -> Dict[str, Any]:
"""Array attributes.

Returns
-------
dict
user defined attributes
"""
...

@abstractproperty
def info(self) -> Any:
"""Report some diagnostic information about the array.

Returns
-------
out
"""
...


class AsynchronousArray(BaseArray):
"""This class can be implemented as a v2 or v3 array"""

@classmethod
@abstractmethod
async def from_json(cls, zarr_json: Any, store: ReadStore) -> AsynchronousArray:
...

@classmethod
@abstractmethod
async def open(cls, store: ReadStore) -> AsynchronousArray:
...

@classmethod
@abstractmethod
async def create(cls, store: WriteStore, *, shape, **kwargs) -> AsynchronousArray:
...

@abstractmethod
async def getitem(self, selection: Selection):
...

@abstractmethod
async def setitem(self, selection: Selection, value: np.ndarray) -> None:
...


class SynchronousArray(BaseArray):
"""
This class can be implemented as a v2 or v3 array
"""

@classmethod
@abstractmethod
def from_json(cls, zarr_json: Any, store: ReadStore) -> SynchronousArray:
...

@classmethod
@abstractmethod
def open(cls, store: ReadStore) -> SynchronousArray:
...

@classmethod
@abstractmethod
def create(cls, store: WriteStore, *, shape, **kwargs) -> SynchronousArray:
...

@abstractmethod
def __getitem__(self, selection: Selection): # TODO: type as np.ndarray | scalar
...

@abstractmethod
def __setitem__(self, selection: Selection, value: np.ndarray) -> None:
...

# some day ;)
# @property
# def __array_api_version__(self) -> str:
# return "2022.12"
84 changes: 84 additions & 0 deletions zarr/v3/abc/codec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Notes:
# 1. These are missing methods described in the spec. I expected to see these method definitions:
# def compute_encoded_representation_type(self, decoded_representation_type):
# def encode(self, decoded_value):
# def decode(self, encoded_value, decoded_representation_type):
# def partial_decode(self, input_handle, decoded_representation_type, decoded_regions):
# def compute_encoded_size(self, input_size):
# 2. Understand why array metadata is included on all codecs


from __future__ import annotations

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

import numpy as np

from zarr.v3.common import BytesLike


if TYPE_CHECKING:
from zarr.v3.metadata import CoreArrayMetadata


class Codec(ABC):
supports_partial_decode: bool
supports_partial_encode: bool
is_fixed_size: bool
array_metadata: CoreArrayMetadata

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

def resolve_metadata(self) -> CoreArrayMetadata:
return self.array_metadata


class ArrayArrayCodec(Codec):
@abstractmethod
async def decode(
self,
chunk_array: np.ndarray,
) -> np.ndarray:
pass

@abstractmethod
async def encode(
self,
chunk_array: np.ndarray,
) -> Optional[np.ndarray]:
pass


class ArrayBytesCodec(Codec):
@abstractmethod
async def decode(
self,
chunk_array: BytesLike,
) -> np.ndarray:
pass

@abstractmethod
async def encode(
self,
chunk_array: np.ndarray,
) -> Optional[BytesLike]:
pass


class BytesBytesCodec(Codec):
@abstractmethod
async def decode(
self,
chunk_array: BytesLike,
) -> BytesLike:
pass

@abstractmethod
async def encode(
self,
chunk_array: BytesLike,
) -> Optional[BytesLike]:
pass
86 changes: 86 additions & 0 deletions zarr/v3/abc/group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from __future__ import annotations

from abc import abstractproperty, ABC
from collections.abc import MutableMapping
from typing import Dict, Any


class BaseGroup(ABC):
@abstractproperty
def attrs(self) -> Dict[str, Any]:
"""User-defined attributes."""
...

@abstractproperty
def info(self) -> Any: # TODO: type this later
"""Return diagnostic information about the group."""
...


class AsynchronousGroup(BaseGroup):
pass
# TODO: (considering the following api)
# store_path (rename to path?)
# nchildren - number of child groups + arrays
# children (async iterator)
# contains - check if child exists
# getitem - get child
# group_keys (async iterator)
# groups (async iterator)
# array_keys (async iterator)
# arrays (async iterator)
# visit
# visitkeys
# visitvalues
# tree
# create_group
# require_group
# create_groups
# require_groups
# create_dataset
# require_dataset
# create
# empty
# zeros
# ones
# full
# array
# empty_like
# zeros_like
# ones_like
# full_like
# move


class SynchronousGroup(BaseGroup, MutableMapping):
# TODO - think about if we want to keep the MutableMapping abstraction or
pass
# store_path (rename to path?)
# __enter__
# __exit__
# group_keys
# groups
# array_keys
# arrays
# visit
# visitkeys
# visitvalues
# visititems
# tree
# create_group
# require_group
# create_groups
# require_groups
# create_dataset
# require_dataset
# create
# empty
# zeros
# ones
# full
# array
# empty_like
# zeros_like
# ones_like
# full_like
# move
Loading