Skip to content

Commit a8ff414

Browse files
committed
Parametrize Array with v2/v3 metadata
1 parent 00e7814 commit a8ff414

File tree

15 files changed

+132
-100
lines changed

15 files changed

+132
-100
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, cast
6+
from typing import TYPE_CHECKING, Any, Literal, TypeAlias, cast
77

88
import numpy as np
99
import numpy.typing as npt
@@ -57,9 +57,12 @@
5757
from zarr.core.buffer import NDArrayLikeOrScalar
5858
from zarr.core.chunk_key_encodings import ChunkKeyEncoding
5959
from zarr.storage import StoreLike
60+
from zarr.types import AnyArray
6061

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

6568
__all__ = [
@@ -569,7 +572,7 @@ async def tree(grp: AsyncGroup, expand: bool | None = None, level: int | None =
569572

570573

571574
async def array(
572-
data: npt.ArrayLike | Array, **kwargs: Any
575+
data: npt.ArrayLike | AnyArray, **kwargs: Any
573576
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
574577
"""Create an array filled with `data`.
575578

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",
@@ -168,7 +169,7 @@ def open(
168169
path: str | None = None,
169170
storage_options: dict[str, Any] | None = None,
170171
**kwargs: Any, # TODO: type kwargs as valid args to async_api.open
171-
) -> Array | Group:
172+
) -> AnyArray | Group:
172173
"""Open a group or array using file-mode-like semantics.
173174
174175
Parameters
@@ -365,7 +366,7 @@ def tree(grp: Group, expand: bool | None = None, level: int | None = None) -> An
365366

366367

367368
# TODO: add type annotations for kwargs
368-
def array(data: npt.ArrayLike | Array, **kwargs: Any) -> Array:
369+
def array(data: npt.ArrayLike | AnyArray, **kwargs: Any) -> AnyArray:
369370
"""Create an array filled with `data`.
370371
371372
Parameters
@@ -633,7 +634,7 @@ def create(
633634
storage_options: dict[str, Any] | None = None,
634635
config: ArrayConfigLike | None = None,
635636
**kwargs: Any,
636-
) -> Array:
637+
) -> AnyArray:
637638
"""Create an array.
638639
639640
Parameters
@@ -769,7 +770,7 @@ def create_array(
769770
overwrite: bool = False,
770771
config: ArrayConfigLike | None = None,
771772
write_data: bool = True,
772-
) -> Array:
773+
) -> AnyArray:
773774
"""Create an array.
774775
775776
This function wraps :func:`zarr.core.array.create_array`.
@@ -916,7 +917,7 @@ def create_array(
916917
def from_array(
917918
store: str | StoreLike,
918919
*,
919-
data: Array | npt.ArrayLike,
920+
data: AnyArray | npt.ArrayLike,
920921
write_data: bool = True,
921922
name: str | None = None,
922923
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -933,7 +934,7 @@ def from_array(
933934
storage_options: dict[str, Any] | None = None,
934935
overwrite: bool = False,
935936
config: ArrayConfigLike | None = None,
936-
) -> Array:
937+
) -> AnyArray:
937938
"""Create an array from an existing array or array-like.
938939
939940
Parameters
@@ -1127,7 +1128,7 @@ def from_array(
11271128

11281129

11291130
# TODO: add type annotations for kwargs
1130-
def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
1131+
def empty(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
11311132
"""Create an empty array with the specified shape. The contents will be filled with the
11321133
array's fill value or zeros if no fill value is provided.
11331134
@@ -1154,7 +1155,7 @@ def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
11541155

11551156
# TODO: move ArrayLike to common module
11561157
# TODO: add type annotations for kwargs
1157-
def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
1158+
def empty_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
11581159
"""Create an empty array like another array. The contents will be filled with the
11591160
array's fill value or zeros if no fill value is provided.
11601161
@@ -1180,7 +1181,7 @@ def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
11801181

11811182

11821183
# TODO: add type annotations for kwargs and fill_value
1183-
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
1184+
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> AnyArray:
11841185
"""Create an array with a default fill value.
11851186
11861187
Parameters
@@ -1202,7 +1203,7 @@ def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
12021203

12031204
# TODO: move ArrayLike to common module
12041205
# TODO: add type annotations for kwargs
1205-
def full_like(a: ArrayLike, **kwargs: Any) -> Array:
1206+
def full_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12061207
"""Create a filled array like another array.
12071208
12081209
Parameters
@@ -1221,7 +1222,7 @@ def full_like(a: ArrayLike, **kwargs: Any) -> Array:
12211222

12221223

12231224
# TODO: add type annotations for kwargs
1224-
def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
1225+
def ones(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
12251226
"""Create an array with a fill value of one.
12261227
12271228
Parameters
@@ -1240,7 +1241,7 @@ def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
12401241

12411242

12421243
# TODO: add type annotations for kwargs
1243-
def ones_like(a: ArrayLike, **kwargs: Any) -> Array:
1244+
def ones_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12441245
"""Create an array of ones like another array.
12451246
12461247
Parameters
@@ -1266,7 +1267,7 @@ def open_array(
12661267
path: PathLike = "",
12671268
storage_options: dict[str, Any] | None = None,
12681269
**kwargs: Any,
1269-
) -> Array:
1270+
) -> AnyArray:
12701271
"""Open an array using file-mode-like semantics.
12711272
12721273
Parameters
@@ -1302,7 +1303,7 @@ def open_array(
13021303

13031304

13041305
# TODO: add type annotations for kwargs
1305-
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
1306+
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyArray:
13061307
"""Open a persistent array like another array.
13071308
13081309
Parameters
@@ -1323,7 +1324,7 @@ def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
13231324

13241325

13251326
# TODO: add type annotations for kwargs
1326-
def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
1327+
def zeros(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
13271328
"""Create an array with a fill value of zero.
13281329
13291330
Parameters
@@ -1342,7 +1343,7 @@ def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
13421343

13431344

13441345
# TODO: add type annotations for kwargs
1345-
def zeros_like(a: ArrayLike, **kwargs: Any) -> Array:
1346+
def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
13461347
"""Create an array of zeros like another array.
13471348
13481349
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.core.dtype.wrapper import TBaseDType, TBaseScalar
145145
from zarr.core.group import AsyncGroup
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
@@ -1997,12 +1998,12 @@ def _info(
19971998

19981999
# TODO: Array can be a frozen data class again once property setters (e.g. shape) are removed
19992000
@dataclass(frozen=False)
2000-
class Array:
2001+
class Array(Generic[T_ArrayMetadata]):
20012002
"""
20022003
A Zarr array.
20032004
"""
20042005

2005-
_async_array: AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]
2006+
_async_array: AsyncArray[T_ArrayMetadata]
20062007

20072008
@classmethod
20082009
@deprecated("Use zarr.create_array instead.", category=ZarrDeprecationWarning)
@@ -2035,7 +2036,7 @@ def create(
20352036
# runtime
20362037
overwrite: bool = False,
20372038
config: ArrayConfigLike | None = None,
2038-
) -> Array:
2039+
) -> AnyArray:
20392040
"""Creates a new Array instance from an initialized store.
20402041
20412042
.. deprecated:: 3.0.0
@@ -2164,7 +2165,7 @@ def _create(
21642165
# runtime
21652166
overwrite: bool = False,
21662167
config: ArrayConfigLike | None = None,
2167-
) -> Array:
2168+
) -> AnyArray:
21682169
"""Creates a new Array instance from an initialized store.
21692170
See :func:`Array.create` for more details.
21702171
Deprecated in favor of :func:`zarr.create_array`.
@@ -2190,14 +2191,14 @@ def _create(
21902191
config=config,
21912192
),
21922193
)
2193-
return cls(async_array)
2194+
return Array(async_array)
21942195

21952196
@classmethod
21962197
def from_dict(
21972198
cls,
21982199
store_path: StorePath,
21992200
data: dict[str, JSON],
2200-
) -> Array:
2201+
) -> AnyArray:
22012202
"""
22022203
Create a Zarr array from a dictionary.
22032204
@@ -2221,13 +2222,13 @@ def from_dict(
22212222
If the dictionary data is invalid or missing required fields for array creation.
22222223
"""
22232224
async_array = AsyncArray.from_dict(store_path=store_path, data=data)
2224-
return cls(async_array)
2225+
return Array(async_array)
22252226

22262227
@classmethod
22272228
def open(
22282229
cls,
22292230
store: StoreLike,
2230-
) -> Array:
2231+
) -> AnyArray:
22312232
"""Opens an existing Array from a store.
22322233
22332234
Parameters
@@ -2241,7 +2242,7 @@ def open(
22412242
Array opened from the store.
22422243
"""
22432244
async_array = sync(AsyncArray.open(store))
2244-
return cls(async_array)
2245+
return Array(async_array)
22452246

22462247
@property
22472248
def store(self) -> Store:
@@ -3982,7 +3983,7 @@ def append(self, data: npt.ArrayLike, axis: int = 0) -> tuple[int, ...]:
39823983
"""
39833984
return sync(self._async_array.append(data, axis=axis))
39843985

3985-
def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
3986+
def update_attributes(self, new_attributes: dict[str, JSON]) -> Self:
39863987
"""
39873988
Update the array's attributes.
39883989
@@ -4007,11 +4008,8 @@ def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
40074008
- The updated attributes will be merged with existing attributes, and any conflicts will be
40084009
overwritten by the new values.
40094010
"""
4010-
# TODO: remove this cast when type inference improves
40114011
new_array = sync(self._async_array.update_attributes(new_attributes))
4012-
# TODO: remove this cast when type inference improves
4013-
_new_array = cast("AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]", new_array)
4014-
return type(self)(_new_array)
4012+
return type(self)(new_array)
40154013

40164014
def __repr__(self) -> str:
40174015
return f"<Array {self.store_path} shape={self.shape} dtype={self.dtype}>"
@@ -4166,7 +4164,7 @@ class ShardsConfigParam(TypedDict):
41664164
async def from_array(
41674165
store: str | StoreLike,
41684166
*,
4169-
data: Array | npt.ArrayLike,
4167+
data: AnyArray | npt.ArrayLike,
41704168
write_data: bool = True,
41714169
name: str | None = None,
41724170
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -4403,7 +4401,7 @@ async def from_array(
44034401
if isinstance(data, Array):
44044402

44054403
async def _copy_array_region(
4406-
chunk_coords: tuple[int, ...] | slice, _data: Array
4404+
chunk_coords: tuple[int, ...] | slice, _data: AnyArray
44074405
) -> None:
44084406
arr = await _data._async_array.getitem(chunk_coords)
44094407
await result.setitem(chunk_coords, arr)
@@ -4833,7 +4831,7 @@ async def create_array(
48334831

48344832

48354833
def _parse_keep_array_attr(
4836-
data: Array | npt.ArrayLike,
4834+
data: AnyArray | npt.ArrayLike,
48374835
chunks: Literal["auto", "keep"] | tuple[int, ...],
48384836
shards: ShardsLike | None | Literal["keep"],
48394837
filters: FiltersLike | Literal["keep"],
@@ -5234,7 +5232,7 @@ def _parse_data_params(
52345232

52355233

52365234
def _iter_chunk_coords(
5237-
array: Array | AsyncArray[Any],
5235+
array: AnyArray | AsyncArray[Any],
52385236
*,
52395237
origin: Sequence[int] | None = None,
52405238
selection_shape: Sequence[int] | None = None,
@@ -5265,7 +5263,7 @@ def _iter_chunk_coords(
52655263

52665264

52675265
def _iter_shard_coords(
5268-
array: Array | AsyncArray[Any],
5266+
array: AnyArray | AsyncArray[Any],
52695267
*,
52705268
origin: Sequence[int] | None = None,
52715269
selection_shape: Sequence[int] | None = None,
@@ -5296,7 +5294,7 @@ def _iter_shard_coords(
52965294

52975295

52985296
def _iter_shard_keys(
5299-
array: Array | AsyncArray[Any],
5297+
array: AnyArray | AsyncArray[Any],
53005298
*,
53015299
origin: Sequence[int] | None = None,
53025300
selection_shape: Sequence[int] | None = None,
@@ -5325,7 +5323,7 @@ def _iter_shard_keys(
53255323

53265324

53275325
def _iter_shard_regions(
5328-
array: Array | AsyncArray[Any],
5326+
array: AnyArray | AsyncArray[Any],
53295327
*,
53305328
origin: Sequence[int] | None = None,
53315329
selection_shape: Sequence[int] | None = None,
@@ -5360,7 +5358,7 @@ def _iter_shard_regions(
53605358

53615359

53625360
def _iter_chunk_regions(
5363-
array: Array | AsyncArray[Any],
5361+
array: AnyArray | AsyncArray[Any],
53645362
*,
53655363
origin: Sequence[int] | None = None,
53665364
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)