Skip to content

Commit 255e18e

Browse files
committed
Parametrize Array with v2/v3 metadata
1 parent be519b0 commit 255e18e

File tree

17 files changed

+139
-106
lines changed

17 files changed

+139
-106
lines changed

src/zarr/api/asynchronous.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import asyncio
44
import dataclasses
55
import warnings
6-
from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict, cast
6+
from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypeAlias, TypedDict, cast
77

88
import numpy as np
99
import numpy.typing as npt
@@ -58,9 +58,12 @@
5858
from zarr.core.chunk_key_encodings import ChunkKeyEncoding
5959
from zarr.core.metadata.v2 import CompressorLikev2
6060
from zarr.storage import StoreLike
61+
from zarr.types import AnyArray
6162

6263
# TODO: this type could use some more thought
63-
ArrayLike = AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | Array | npt.NDArray[Any]
64+
ArrayLike: TypeAlias = (
65+
AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | AnyArray | npt.NDArray[Any]
66+
)
6467
PathLike = str
6568

6669
__all__ = [
@@ -602,7 +605,7 @@ async def tree(grp: AsyncGroup, expand: bool | None = None, level: int | None =
602605

603606

604607
async def array(
605-
data: npt.ArrayLike | Array, **kwargs: Any
608+
data: npt.ArrayLike | AnyArray, **kwargs: Any
606609
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
607610
"""Create an array filled with `data`.
608611

src/zarr/api/synchronous.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
)
4141
from zarr.core.dtype import ZDTypeLike
4242
from zarr.storage import StoreLike
43+
from zarr.types import AnyArray
4344

4445
__all__ = [
4546
"array",
@@ -181,7 +182,7 @@ def open(
181182
path: str | None = None,
182183
storage_options: dict[str, Any] | None = None,
183184
**kwargs: Any, # TODO: type kwargs as valid args to async_api.open
184-
) -> Array | Group:
185+
) -> AnyArray | Group:
185186
"""Open a group or array using file-mode-like semantics.
186187
187188
Parameters
@@ -387,7 +388,7 @@ def tree(grp: Group, expand: bool | None = None, level: int | None = None) -> An
387388

388389

389390
# TODO: add type annotations for kwargs
390-
def array(data: npt.ArrayLike | Array, **kwargs: Any) -> Array:
391+
def array(data: npt.ArrayLike | AnyArray, **kwargs: Any) -> AnyArray:
391392
"""Create an array filled with `data`.
392393
393394
Parameters
@@ -652,7 +653,7 @@ def create(
652653
storage_options: dict[str, Any] | None = None,
653654
config: ArrayConfigLike | None = None,
654655
**kwargs: Any,
655-
) -> Array:
656+
) -> AnyArray:
656657
"""Create an array.
657658
658659
Parameters
@@ -836,7 +837,7 @@ def create_array(
836837
overwrite: bool = False,
837838
config: ArrayConfigLike | None = None,
838839
write_data: bool = True,
839-
) -> Array:
840+
) -> AnyArray:
840841
"""Create an array.
841842
842843
This function wraps [zarr.core.array.create_array][].
@@ -987,7 +988,7 @@ def create_array(
987988
def from_array(
988989
store: StoreLike,
989990
*,
990-
data: Array | npt.ArrayLike,
991+
data: AnyArray | npt.ArrayLike,
991992
write_data: bool = True,
992993
name: str | None = None,
993994
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -1004,7 +1005,7 @@ def from_array(
10041005
storage_options: dict[str, Any] | None = None,
10051006
overwrite: bool = False,
10061007
config: ArrayConfigLike | None = None,
1007-
) -> Array:
1008+
) -> AnyArray:
10081009
"""Create an array from an existing array or array-like.
10091010
10101011
Parameters
@@ -1203,7 +1204,7 @@ def from_array(
12031204

12041205

12051206
# TODO: add type annotations for kwargs
1206-
def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
1207+
def empty(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
12071208
"""Create an empty array with the specified shape. The contents will be filled with the
12081209
array's fill value or zeros if no fill value is provided.
12091210
@@ -1230,7 +1231,7 @@ def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
12301231

12311232
# TODO: move ArrayLike to common module
12321233
# TODO: add type annotations for kwargs
1233-
def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
1234+
def empty_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12341235
"""Create an empty array like another array. The contents will be filled with the
12351236
array's fill value or zeros if no fill value is provided.
12361237
@@ -1256,7 +1257,7 @@ def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
12561257

12571258

12581259
# TODO: add type annotations for kwargs and fill_value
1259-
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
1260+
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> AnyArray:
12601261
"""Create an array with a default fill value.
12611262
12621263
Parameters
@@ -1278,7 +1279,7 @@ def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
12781279

12791280
# TODO: move ArrayLike to common module
12801281
# TODO: add type annotations for kwargs
1281-
def full_like(a: ArrayLike, **kwargs: Any) -> Array:
1282+
def full_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12821283
"""Create a filled array like another array.
12831284
12841285
Parameters
@@ -1297,7 +1298,7 @@ def full_like(a: ArrayLike, **kwargs: Any) -> Array:
12971298

12981299

12991300
# TODO: add type annotations for kwargs
1300-
def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
1301+
def ones(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
13011302
"""Create an array with a fill value of one.
13021303
13031304
Parameters
@@ -1316,7 +1317,7 @@ def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
13161317

13171318

13181319
# TODO: add type annotations for kwargs
1319-
def ones_like(a: ArrayLike, **kwargs: Any) -> Array:
1320+
def ones_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
13201321
"""Create an array of ones like another array.
13211322
13221323
Parameters
@@ -1343,7 +1344,7 @@ def open_array(
13431344
path: PathLike = "",
13441345
storage_options: dict[str, Any] | None = None,
13451346
**kwargs: Any,
1346-
) -> Array:
1347+
) -> AnyArray:
13471348
"""Open an array using file-mode-like semantics.
13481349
13491350
Parameters
@@ -1385,7 +1386,7 @@ def open_array(
13851386

13861387

13871388
# TODO: add type annotations for kwargs
1388-
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
1389+
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyArray:
13891390
"""Open a persistent array like another array.
13901391
13911392
Parameters
@@ -1406,7 +1407,7 @@ def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
14061407

14071408

14081409
# TODO: add type annotations for kwargs
1409-
def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
1410+
def zeros(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
14101411
"""Create an array with a fill value of zero.
14111412
14121413
Parameters
@@ -1425,7 +1426,7 @@ def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
14251426

14261427

14271428
# TODO: add type annotations for kwargs
1428-
def zeros_like(a: ArrayLike, **kwargs: Any) -> Array:
1429+
def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
14291430
"""Create an array of zeros like another array.
14301431
14311432
Parameters

src/zarr/core/array.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
from zarr.codecs.sharding import ShardingCodecIndexLocation
145145
from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar
146146
from zarr.storage import StoreLike
147+
from zarr.types import AnyArray
147148

148149

149150
# Array and AsyncArray are defined in the base ``zarr`` namespace
@@ -1989,12 +1990,12 @@ def _info(
19891990

19901991
# TODO: Array can be a frozen data class again once property setters (e.g. shape) are removed
19911992
@dataclass(frozen=False)
1992-
class Array:
1993+
class Array(Generic[T_ArrayMetadata]):
19931994
"""
19941995
A Zarr array.
19951996
"""
19961997

1997-
_async_array: AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]
1998+
_async_array: AsyncArray[T_ArrayMetadata]
19981999

19992000
@classmethod
20002001
@deprecated("Use zarr.create_array instead.", category=ZarrDeprecationWarning)
@@ -2027,7 +2028,7 @@ def create(
20272028
# runtime
20282029
overwrite: bool = False,
20292030
config: ArrayConfigLike | None = None,
2030-
) -> Array:
2031+
) -> AnyArray:
20312032
"""Creates a new Array instance from an initialized store.
20322033
20332034
!!! warning "Deprecated"
@@ -2171,7 +2172,7 @@ def _create(
21712172
# runtime
21722173
overwrite: bool = False,
21732174
config: ArrayConfigLike | None = None,
2174-
) -> Array:
2175+
) -> AnyArray:
21752176
"""Creates a new Array instance from an initialized store.
21762177
Deprecated in favor of [`zarr.create_array`][].
21772178
"""
@@ -2196,14 +2197,14 @@ def _create(
21962197
config=config,
21972198
),
21982199
)
2199-
return cls(async_array)
2200+
return Array(async_array)
22002201

22012202
@classmethod
22022203
def from_dict(
22032204
cls,
22042205
store_path: StorePath,
22052206
data: dict[str, JSON],
2206-
) -> Array:
2207+
) -> AnyArray:
22072208
"""
22082209
Create a Zarr array from a dictionary.
22092210
@@ -2227,13 +2228,13 @@ def from_dict(
22272228
If the dictionary data is invalid or missing required fields for array creation.
22282229
"""
22292230
async_array = AsyncArray.from_dict(store_path=store_path, data=data)
2230-
return cls(async_array)
2231+
return Array(async_array)
22312232

22322233
@classmethod
22332234
def open(
22342235
cls,
22352236
store: StoreLike,
2236-
) -> Array:
2237+
) -> AnyArray:
22372238
"""Opens an existing Array from a store.
22382239
22392240
Parameters
@@ -2249,7 +2250,7 @@ def open(
22492250
Array opened from the store.
22502251
"""
22512252
async_array = sync(AsyncArray.open(store))
2252-
return cls(async_array)
2253+
return Array(async_array)
22532254

22542255
@property
22552256
def store(self) -> Store:
@@ -4085,7 +4086,7 @@ def append(self, data: npt.ArrayLike, axis: int = 0) -> tuple[int, ...]:
40854086
"""
40864087
return sync(self._async_array.append(data, axis=axis))
40874088

4088-
def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
4089+
def update_attributes(self, new_attributes: dict[str, JSON]) -> Self:
40894090
"""
40904091
Update the array's attributes.
40914092
@@ -4110,11 +4111,8 @@ def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
41104111
- The updated attributes will be merged with existing attributes, and any conflicts will be
41114112
overwritten by the new values.
41124113
"""
4113-
# TODO: remove this cast when type inference improves
41144114
new_array = sync(self._async_array.update_attributes(new_attributes))
4115-
# TODO: remove this cast when type inference improves
4116-
_new_array = cast("AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]", new_array)
4117-
return type(self)(_new_array)
4115+
return type(self)(new_array)
41184116

41194117
def __repr__(self) -> str:
41204118
return f"<Array {self.store_path} shape={self.shape} dtype={self.dtype}>"
@@ -4236,7 +4234,7 @@ class ShardsConfigParam(TypedDict):
42364234
async def from_array(
42374235
store: StoreLike,
42384236
*,
4239-
data: Array | npt.ArrayLike,
4237+
data: AnyArray | npt.ArrayLike,
42404238
write_data: bool = True,
42414239
name: str | None = None,
42424240
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -4478,7 +4476,7 @@ async def from_array(
44784476
if isinstance(data, Array):
44794477

44804478
async def _copy_array_region(
4481-
chunk_coords: tuple[int, ...] | slice, _data: Array
4479+
chunk_coords: tuple[int, ...] | slice, _data: AnyArray
44824480
) -> None:
44834481
arr = await _data._async_array.getitem(chunk_coords)
44844482
await result.setitem(chunk_coords, arr)
@@ -4908,7 +4906,7 @@ async def create_array(
49084906

49094907

49104908
def _parse_keep_array_attr(
4911-
data: Array | npt.ArrayLike,
4909+
data: AnyArray | npt.ArrayLike,
49124910
chunks: Literal["auto", "keep"] | tuple[int, ...],
49134911
shards: ShardsLike | None | Literal["keep"],
49144912
filters: FiltersLike | Literal["keep"],
@@ -5287,7 +5285,7 @@ def _parse_data_params(
52875285

52885286

52895287
def _iter_chunk_coords(
5290-
array: Array | AsyncArray[Any],
5288+
array: AnyArray | AsyncArray[Any],
52915289
*,
52925290
origin: Sequence[int] | None = None,
52935291
selection_shape: Sequence[int] | None = None,
@@ -5318,7 +5316,7 @@ def _iter_chunk_coords(
53185316

53195317

53205318
def _iter_shard_coords(
5321-
array: Array | AsyncArray[Any],
5319+
array: AnyArray | AsyncArray[Any],
53225320
*,
53235321
origin: Sequence[int] | None = None,
53245322
selection_shape: Sequence[int] | None = None,
@@ -5349,7 +5347,7 @@ def _iter_shard_coords(
53495347

53505348

53515349
def _iter_shard_keys(
5352-
array: Array | AsyncArray[Any],
5350+
array: AnyArray | AsyncArray[Any],
53535351
*,
53545352
origin: Sequence[int] | None = None,
53555353
selection_shape: Sequence[int] | None = None,
@@ -5378,7 +5376,7 @@ def _iter_shard_keys(
53785376

53795377

53805378
def _iter_shard_regions(
5381-
array: Array | AsyncArray[Any],
5379+
array: AnyArray | AsyncArray[Any],
53825380
*,
53835381
origin: Sequence[int] | None = None,
53845382
selection_shape: Sequence[int] | None = None,
@@ -5413,7 +5411,7 @@ def _iter_shard_regions(
54135411

54145412

54155413
def _iter_chunk_regions(
5416-
array: Array | AsyncArray[Any],
5414+
array: AnyArray | AsyncArray[Any],
54175415
*,
54185416
origin: Sequence[int] | None = None,
54195417
selection_shape: Sequence[int] | None = None,

src/zarr/core/attributes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
if TYPE_CHECKING:
99
from collections.abc import Iterator
1010

11-
from zarr.core.array import Array
1211
from zarr.core.group import Group
12+
from zarr.types import AnyArray
1313

1414

1515
class Attributes(MutableMapping[str, JSON]):
16-
def __init__(self, obj: Array | Group) -> None:
16+
def __init__(self, obj: AnyArray | Group) -> None:
1717
# key=".zattrs", read_only=False, cache=True, synchronizer=None
1818
self._obj = obj
1919

0 commit comments

Comments
 (0)