Skip to content

Commit 2672ab2

Browse files
committed
Parametrize Array with v2/v3 metadata
1 parent e410173 commit 2672ab2

File tree

14 files changed

+123
-93
lines changed

14 files changed

+123
-93
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
@@ -52,9 +52,12 @@
5252
from zarr.core.buffer import NDArrayLikeOrScalar
5353
from zarr.core.chunk_key_encodings import ChunkKeyEncoding
5454
from zarr.storage import StoreLike
55+
from zarr.types import AnyArray
5556

5657
# TODO: this type could use some more thought
57-
ArrayLike = AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | Array | npt.NDArray[Any]
58+
ArrayLike: TypeAlias = (
59+
AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | AnyArray | npt.NDArray[Any]
60+
)
5861
PathLike = str
5962

6063
__all__ = [
@@ -562,7 +565,7 @@ async def tree(grp: AsyncGroup, expand: bool | None = None, level: int | None =
562565

563566

564567
async def array(
565-
data: npt.ArrayLike | Array, **kwargs: Any
568+
data: npt.ArrayLike | AnyArray, **kwargs: Any
566569
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
567570
"""Create an array filled with `data`.
568571

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`.
@@ -917,7 +918,7 @@ def create_array(
917918
def from_array(
918919
store: str | StoreLike,
919920
*,
920-
data: Array | npt.ArrayLike,
921+
data: AnyArray | npt.ArrayLike,
921922
write_data: bool = True,
922923
name: str | None = None,
923924
chunks: Literal["auto", "keep"] | ChunkCoords = "keep",
@@ -934,7 +935,7 @@ def from_array(
934935
storage_options: dict[str, Any] | None = None,
935936
overwrite: bool = False,
936937
config: ArrayConfigLike | None = None,
937-
) -> Array:
938+
) -> AnyArray:
938939
"""Create an array from an existing array or array-like.
939940
940941
Parameters
@@ -1128,7 +1129,7 @@ def from_array(
11281129

11291130

11301131
# TODO: add type annotations for kwargs
1131-
def empty(shape: ChunkCoords, **kwargs: Any) -> Array:
1132+
def empty(shape: ChunkCoords, **kwargs: Any) -> AnyArray:
11321133
"""Create an empty array with the specified shape. The contents will be filled with the
11331134
array's fill value or zeros if no fill value is provided.
11341135
@@ -1155,7 +1156,7 @@ def empty(shape: ChunkCoords, **kwargs: Any) -> Array:
11551156

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

11821183

11831184
# TODO: add type annotations for kwargs and fill_value
1184-
def full(shape: ChunkCoords, fill_value: Any, **kwargs: Any) -> Array:
1185+
def full(shape: ChunkCoords, fill_value: Any, **kwargs: Any) -> AnyArray:
11851186
"""Create an array with a default fill value.
11861187
11871188
Parameters
@@ -1203,7 +1204,7 @@ def full(shape: ChunkCoords, fill_value: Any, **kwargs: Any) -> Array:
12031204

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

12231224

12241225
# TODO: add type annotations for kwargs
1225-
def ones(shape: ChunkCoords, **kwargs: Any) -> Array:
1226+
def ones(shape: ChunkCoords, **kwargs: Any) -> AnyArray:
12261227
"""Create an array with a fill value of one.
12271228
12281229
Parameters
@@ -1241,7 +1242,7 @@ def ones(shape: ChunkCoords, **kwargs: Any) -> Array:
12411242

12421243

12431244
# TODO: add type annotations for kwargs
1244-
def ones_like(a: ArrayLike, **kwargs: Any) -> Array:
1245+
def ones_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12451246
"""Create an array of ones like another array.
12461247
12471248
Parameters
@@ -1267,7 +1268,7 @@ def open_array(
12671268
path: PathLike = "",
12681269
storage_options: dict[str, Any] | None = None,
12691270
**kwargs: Any,
1270-
) -> Array:
1271+
) -> AnyArray:
12711272
"""Open an array using file-mode-like semantics.
12721273
12731274
Parameters
@@ -1303,7 +1304,7 @@ def open_array(
13031304

13041305

13051306
# TODO: add type annotations for kwargs
1306-
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
1307+
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyArray:
13071308
"""Open a persistent array like another array.
13081309
13091310
Parameters
@@ -1324,7 +1325,7 @@ def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
13241325

13251326

13261327
# TODO: add type annotations for kwargs
1327-
def zeros(shape: ChunkCoords, **kwargs: Any) -> Array:
1328+
def zeros(shape: ChunkCoords, **kwargs: Any) -> AnyArray:
13281329
"""Create an array with a fill value of zero.
13291330
13301331
Parameters
@@ -1343,7 +1344,7 @@ def zeros(shape: ChunkCoords, **kwargs: Any) -> Array:
13431344

13441345

13451346
# TODO: add type annotations for kwargs
1346-
def zeros_like(a: ArrayLike, **kwargs: Any) -> Array:
1347+
def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
13471348
"""Create an array of zeros like another array.
13481349
13491350
Parameters

src/zarr/core/array.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar
141141
from zarr.core.group import AsyncGroup
142142
from zarr.storage import StoreLike
143+
from zarr.types import AnyArray
143144

144145

145146
# Array and AsyncArray are defined in the base ``zarr`` namespace
@@ -1847,12 +1848,12 @@ def _info(
18471848

18481849
# TODO: Array can be a frozen data class again once property setters (e.g. shape) are removed
18491850
@dataclass(frozen=False)
1850-
class Array:
1851+
class Array(Generic[T_ArrayMetadata]):
18511852
"""
18521853
A Zarr array.
18531854
"""
18541855

1855-
_async_array: AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]
1856+
_async_array: AsyncArray[T_ArrayMetadata]
18561857

18571858
@classmethod
18581859
@deprecated("Use zarr.create_array instead.")
@@ -1885,7 +1886,7 @@ def create(
18851886
# runtime
18861887
overwrite: bool = False,
18871888
config: ArrayConfigLike | None = None,
1888-
) -> Array:
1889+
) -> AnyArray:
18891890
"""Creates a new Array instance from an initialized store.
18901891
18911892
.. deprecated:: 3.0.0
@@ -2014,7 +2015,7 @@ def _create(
20142015
# runtime
20152016
overwrite: bool = False,
20162017
config: ArrayConfigLike | None = None,
2017-
) -> Array:
2018+
) -> AnyArray:
20182019
"""Creates a new Array instance from an initialized store.
20192020
See :func:`Array.create` for more details.
20202021
Deprecated in favor of :func:`zarr.create_array`.
@@ -2040,14 +2041,14 @@ def _create(
20402041
config=config,
20412042
),
20422043
)
2043-
return cls(async_array)
2044+
return Array(async_array)
20442045

20452046
@classmethod
20462047
def from_dict(
20472048
cls,
20482049
store_path: StorePath,
20492050
data: dict[str, JSON],
2050-
) -> Array:
2051+
) -> AnyArray:
20512052
"""
20522053
Create a Zarr array from a dictionary.
20532054
@@ -2071,13 +2072,13 @@ def from_dict(
20712072
If the dictionary data is invalid or missing required fields for array creation.
20722073
"""
20732074
async_array = AsyncArray.from_dict(store_path=store_path, data=data)
2074-
return cls(async_array)
2075+
return Array(async_array)
20752076

20762077
@classmethod
20772078
def open(
20782079
cls,
20792080
store: StoreLike,
2080-
) -> Array:
2081+
) -> AnyArray:
20812082
"""Opens an existing Array from a store.
20822083
20832084
Parameters
@@ -2091,7 +2092,7 @@ def open(
20912092
Array opened from the store.
20922093
"""
20932094
async_array = sync(AsyncArray.open(store))
2094-
return cls(async_array)
2095+
return Array(async_array)
20952096

20962097
@property
20972098
def store(self) -> Store:
@@ -3746,7 +3747,7 @@ def append(self, data: npt.ArrayLike, axis: int = 0) -> ChunkCoords:
37463747
"""
37473748
return sync(self._async_array.append(data, axis=axis))
37483749

3749-
def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
3750+
def update_attributes(self, new_attributes: dict[str, JSON]) -> Self:
37503751
"""
37513752
Update the array's attributes.
37523753
@@ -3771,11 +3772,8 @@ def update_attributes(self, new_attributes: dict[str, JSON]) -> Array:
37713772
- The updated attributes will be merged with existing attributes, and any conflicts will be
37723773
overwritten by the new values.
37733774
"""
3774-
# TODO: remove this cast when type inference improves
37753775
new_array = sync(self._async_array.update_attributes(new_attributes))
3776-
# TODO: remove this cast when type inference improves
3777-
_new_array = cast("AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]", new_array)
3778-
return type(self)(_new_array)
3776+
return type(self)(new_array)
37793777

37803778
def __repr__(self) -> str:
37813779
return f"<Array {self.store_path} shape={self.shape} dtype={self.dtype}>"
@@ -3932,7 +3930,7 @@ class ShardsConfigParam(TypedDict):
39323930
async def from_array(
39333931
store: str | StoreLike,
39343932
*,
3935-
data: Array | npt.ArrayLike,
3933+
data: AnyArray | npt.ArrayLike,
39363934
write_data: bool = True,
39373935
name: str | None = None,
39383936
chunks: Literal["auto", "keep"] | ChunkCoords = "keep",
@@ -4168,7 +4166,9 @@ async def from_array(
41684166
if write_data:
41694167
if isinstance(data, Array):
41704168

4171-
async def _copy_array_region(chunk_coords: ChunkCoords | slice, _data: Array) -> None:
4169+
async def _copy_array_region(
4170+
chunk_coords: ChunkCoords | slice, _data: AnyArray
4171+
) -> None:
41724172
arr = await _data._async_array.getitem(chunk_coords)
41734173
await result.setitem(chunk_coords, arr)
41744174

@@ -4595,7 +4595,7 @@ async def create_array(
45954595

45964596

45974597
def _parse_keep_array_attr(
4598-
data: Array | npt.ArrayLike,
4598+
data: AnyArray | npt.ArrayLike,
45994599
chunks: Literal["auto", "keep"] | ChunkCoords,
46004600
shards: ShardsLike | None | Literal["keep"],
46014601
filters: FiltersLike | Literal["keep"],

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)