Skip to content

Commit a18f0b1

Browse files
committed
Parametrize Array with v2/v3 metadata
1 parent c9eefe6 commit a18f0b1

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
@@ -1996,12 +1997,12 @@ def _info(
19961997

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

2004-
_async_array: AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]
2005+
_async_array: AsyncArray[T_ArrayMetadata]
20052006

20062007
@classmethod
20072008
@deprecated("Use zarr.create_array instead.", category=ZarrDeprecationWarning)
@@ -2034,7 +2035,7 @@ def create(
20342035
# runtime
20352036
overwrite: bool = False,
20362037
config: ArrayConfigLike | None = None,
2037-
) -> Array:
2038+
) -> AnyArray:
20382039
"""Creates a new Array instance from an initialized store.
20392040
20402041
.. deprecated:: 3.0.0
@@ -2163,7 +2164,7 @@ def _create(
21632164
# runtime
21642165
overwrite: bool = False,
21652166
config: ArrayConfigLike | None = None,
2166-
) -> Array:
2167+
) -> AnyArray:
21672168
"""Creates a new Array instance from an initialized store.
21682169
See :func:`Array.create` for more details.
21692170
Deprecated in favor of :func:`zarr.create_array`.
@@ -2189,14 +2190,14 @@ def _create(
21892190
config=config,
21902191
),
21912192
)
2192-
return cls(async_array)
2193+
return Array(async_array)
21932194

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

22252226
@classmethod
22262227
def open(
22272228
cls,
22282229
store: StoreLike,
2229-
) -> Array:
2230+
) -> AnyArray:
22302231
"""Opens an existing Array from a store.
22312232
22322233
Parameters
@@ -2240,7 +2241,7 @@ def open(
22402241
Array opened from the store.
22412242
"""
22422243
async_array = sync(AsyncArray.open(store))
2243-
return cls(async_array)
2244+
return Array(async_array)
22442245

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

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

40154013
def __repr__(self) -> str:
40164014
return f"<Array {self.store_path} shape={self.shape} dtype={self.dtype}>"
@@ -4165,7 +4163,7 @@ class ShardsConfigParam(TypedDict):
41654163
async def from_array(
41664164
store: str | StoreLike,
41674165
*,
4168-
data: Array | npt.ArrayLike,
4166+
data: AnyArray | npt.ArrayLike,
41694167
write_data: bool = True,
41704168
name: str | None = None,
41714169
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -4402,7 +4400,7 @@ async def from_array(
44024400
if isinstance(data, Array):
44034401

44044402
async def _copy_array_region(
4405-
chunk_coords: tuple[int, ...] | slice, _data: Array
4403+
chunk_coords: tuple[int, ...] | slice, _data: AnyArray
44064404
) -> None:
44074405
arr = await _data._async_array.getitem(chunk_coords)
44084406
await result.setitem(chunk_coords, arr)
@@ -4830,7 +4828,7 @@ async def create_array(
48304828

48314829

48324830
def _parse_keep_array_attr(
4833-
data: Array | npt.ArrayLike,
4831+
data: AnyArray | npt.ArrayLike,
48344832
chunks: Literal["auto", "keep"] | tuple[int, ...],
48354833
shards: ShardsLike | None | Literal["keep"],
48364834
filters: FiltersLike | Literal["keep"],
@@ -5231,7 +5229,7 @@ def _parse_data_params(
52315229

52325230

52335231
def _iter_chunk_coords(
5234-
array: Array | AsyncArray[Any],
5232+
array: AnyArray | AsyncArray[Any],
52355233
*,
52365234
origin: Sequence[int] | None = None,
52375235
selection_shape: Sequence[int] | None = None,
@@ -5262,7 +5260,7 @@ def _iter_chunk_coords(
52625260

52635261

52645262
def _iter_shard_coords(
5265-
array: Array | AsyncArray[Any],
5263+
array: AnyArray | AsyncArray[Any],
52665264
*,
52675265
origin: Sequence[int] | None = None,
52685266
selection_shape: Sequence[int] | None = None,
@@ -5293,7 +5291,7 @@ def _iter_shard_coords(
52935291

52945292

52955293
def _iter_shard_keys(
5296-
array: Array | AsyncArray[Any],
5294+
array: AnyArray | AsyncArray[Any],
52975295
*,
52985296
origin: Sequence[int] | None = None,
52995297
selection_shape: Sequence[int] | None = None,
@@ -5322,7 +5320,7 @@ def _iter_shard_keys(
53225320

53235321

53245322
def _iter_shard_regions(
5325-
array: Array | AsyncArray[Any],
5323+
array: AnyArray | AsyncArray[Any],
53265324
*,
53275325
origin: Sequence[int] | None = None,
53285326
selection_shape: Sequence[int] | None = None,
@@ -5357,7 +5355,7 @@ def _iter_shard_regions(
53575355

53585356

53595357
def _iter_chunk_regions(
5360-
array: Array | AsyncArray[Any],
5358+
array: AnyArray | AsyncArray[Any],
53615359
*,
53625360
origin: Sequence[int] | None = None,
53635361
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)