Skip to content

Commit edd47db

Browse files
dstansbyd-v-b
andauthored
Parametrize Array with v2/v3 metadata (#3304)
* Parametrize Array with v2/v3 metadata * Try fixing docstrings * Add an AnyAsyncArray type * Add async array v2 and v3 types * Add changelog entry * Pass sub-classes through returns. * Chage release note to MarkDown --------- Co-authored-by: Davis Bennett <[email protected]>
1 parent 54dcede commit edd47db

File tree

19 files changed

+221
-229
lines changed

19 files changed

+221
-229
lines changed

changes/3304.feature.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The `Array` class can now also be parametrized in the same manner as the `AsyncArray` class, allowing Zarr format v2 and v3 `Array`s to be distinguished.
2+
New types have been added to `zarr.types` to help with this.

src/zarr/api/asynchronous.py

Lines changed: 17 additions & 36 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
@@ -37,7 +37,7 @@
3737
GroupMetadata,
3838
create_hierarchy,
3939
)
40-
from zarr.core.metadata import ArrayMetadataDict, ArrayV2Metadata, ArrayV3Metadata
40+
from zarr.core.metadata import ArrayMetadataDict, ArrayV2Metadata
4141
from zarr.errors import (
4242
ArrayNotFoundError,
4343
GroupNotFoundError,
@@ -58,9 +58,10 @@
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, AnyAsyncArray
6162

6263
# TODO: this type could use some more thought
63-
ArrayLike = AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | Array | npt.NDArray[Any]
64+
ArrayLike: TypeAlias = AnyAsyncArray | AnyArray | npt.NDArray[Any]
6465
PathLike = str
6566

6667
__all__ = [
@@ -335,7 +336,7 @@ async def open(
335336
path: str | None = None,
336337
storage_options: dict[str, Any] | None = None,
337338
**kwargs: Any, # TODO: type kwargs as valid args to open_array
338-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | AsyncGroup:
339+
) -> AnyAsyncArray | AsyncGroup:
339340
"""Convenience function to open a group or array using file-mode-like semantics.
340341
341342
Parameters
@@ -601,9 +602,7 @@ async def tree(grp: AsyncGroup, expand: bool | None = None, level: int | None =
601602
return await grp.tree(expand=expand, level=level)
602603

603604

604-
async def array(
605-
data: npt.ArrayLike | Array, **kwargs: Any
606-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
605+
async def array(data: npt.ArrayLike | AnyArray, **kwargs: Any) -> AnyAsyncArray:
607606
"""Create an array filled with `data`.
608607
609608
Parameters
@@ -919,7 +918,7 @@ async def create(
919918
storage_options: dict[str, Any] | None = None,
920919
config: ArrayConfigLike | None = None,
921920
**kwargs: Any,
922-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
921+
) -> AnyAsyncArray:
923922
"""Create an array.
924923
925924
Parameters
@@ -1106,9 +1105,7 @@ async def create(
11061105
)
11071106

11081107

1109-
async def empty(
1110-
shape: tuple[int, ...], **kwargs: Any
1111-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1108+
async def empty(shape: tuple[int, ...], **kwargs: Any) -> AnyAsyncArray:
11121109
"""Create an empty array with the specified shape. The contents will be filled with the
11131110
specified fill value or zeros if no fill value is provided.
11141111
@@ -1128,9 +1125,7 @@ async def empty(
11281125
return await create(shape=shape, **kwargs)
11291126

11301127

1131-
async def empty_like(
1132-
a: ArrayLike, **kwargs: Any
1133-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1128+
async def empty_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
11341129
"""Create an empty array like `a`. The contents will be filled with the
11351130
array's fill value or zeros if no fill value is provided.
11361131
@@ -1159,9 +1154,7 @@ async def empty_like(
11591154

11601155

11611156
# TODO: add type annotations for fill_value and kwargs
1162-
async def full(
1163-
shape: tuple[int, ...], fill_value: Any, **kwargs: Any
1164-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1157+
async def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> AnyAsyncArray:
11651158
"""Create an array, with `fill_value` being used as the default value for
11661159
uninitialized portions of the array.
11671160
@@ -1183,9 +1176,7 @@ async def full(
11831176

11841177

11851178
# TODO: add type annotations for kwargs
1186-
async def full_like(
1187-
a: ArrayLike, **kwargs: Any
1188-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1179+
async def full_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
11891180
"""Create a filled array like `a`.
11901181
11911182
Parameters
@@ -1206,9 +1197,7 @@ async def full_like(
12061197
return await full(**like_kwargs) # type: ignore[arg-type]
12071198

12081199

1209-
async def ones(
1210-
shape: tuple[int, ...], **kwargs: Any
1211-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1200+
async def ones(shape: tuple[int, ...], **kwargs: Any) -> AnyAsyncArray:
12121201
"""Create an array, with one being used as the default value for
12131202
uninitialized portions of the array.
12141203
@@ -1227,9 +1216,7 @@ async def ones(
12271216
return await create(shape=shape, fill_value=1, **kwargs)
12281217

12291218

1230-
async def ones_like(
1231-
a: ArrayLike, **kwargs: Any
1232-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1219+
async def ones_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
12331220
"""Create an array of ones like `a`.
12341221
12351222
Parameters
@@ -1256,7 +1243,7 @@ async def open_array(
12561243
path: PathLike = "",
12571244
storage_options: dict[str, Any] | None = None,
12581245
**kwargs: Any, # TODO: type kwargs as valid args to save
1259-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1246+
) -> AnyAsyncArray:
12601247
"""Open an array using file-mode-like semantics.
12611248
12621249
Parameters
@@ -1307,9 +1294,7 @@ async def open_array(
13071294
raise ArrayNotFoundError(msg) from err
13081295

13091296

1310-
async def open_like(
1311-
a: ArrayLike, path: str, **kwargs: Any
1312-
) -> AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]:
1297+
async def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyAsyncArray:
13131298
"""Open a persistent array like `a`.
13141299
13151300
Parameters
@@ -1332,9 +1317,7 @@ async def open_like(
13321317
return await open_array(path=path, **like_kwargs) # type: ignore[arg-type]
13331318

13341319

1335-
async def zeros(
1336-
shape: tuple[int, ...], **kwargs: Any
1337-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1320+
async def zeros(shape: tuple[int, ...], **kwargs: Any) -> AnyAsyncArray:
13381321
"""Create an array, with zero being used as the default value for
13391322
uninitialized portions of the array.
13401323
@@ -1353,9 +1336,7 @@ async def zeros(
13531336
return await create(shape=shape, fill_value=0, **kwargs)
13541337

13551338

1356-
async def zeros_like(
1357-
a: ArrayLike, **kwargs: Any
1358-
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
1339+
async def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
13591340
"""Create an array of zeros like `a`.
13601341
13611342
Parameters

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][].
@@ -989,7 +990,7 @@ def create_array(
989990
def from_array(
990991
store: StoreLike,
991992
*,
992-
data: Array | npt.ArrayLike,
993+
data: AnyArray | npt.ArrayLike,
993994
write_data: bool = True,
994995
name: str | None = None,
995996
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
@@ -1006,7 +1007,7 @@ def from_array(
10061007
storage_options: dict[str, Any] | None = None,
10071008
overwrite: bool = False,
10081009
config: ArrayConfigLike | None = None,
1009-
) -> Array:
1010+
) -> AnyArray:
10101011
"""Create an array from an existing array or array-like.
10111012
10121013
Parameters
@@ -1220,7 +1221,7 @@ def from_array(
12201221

12211222

12221223
# TODO: add type annotations for kwargs
1223-
def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
1224+
def empty(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
12241225
"""Create an empty array with the specified shape. The contents will be filled with the
12251226
array's fill value or zeros if no fill value is provided.
12261227
@@ -1247,7 +1248,7 @@ def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
12471248

12481249
# TODO: move ArrayLike to common module
12491250
# TODO: add type annotations for kwargs
1250-
def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
1251+
def empty_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12511252
"""Create an empty array like another array. The contents will be filled with the
12521253
array's fill value or zeros if no fill value is provided.
12531254
@@ -1273,7 +1274,7 @@ def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
12731274

12741275

12751276
# TODO: add type annotations for kwargs and fill_value
1276-
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
1277+
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> AnyArray:
12771278
"""Create an array with a default fill value.
12781279
12791280
Parameters
@@ -1295,7 +1296,7 @@ def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
12951296

12961297
# TODO: move ArrayLike to common module
12971298
# TODO: add type annotations for kwargs
1298-
def full_like(a: ArrayLike, **kwargs: Any) -> Array:
1299+
def full_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
12991300
"""Create a filled array like another array.
13001301
13011302
Parameters
@@ -1314,7 +1315,7 @@ def full_like(a: ArrayLike, **kwargs: Any) -> Array:
13141315

13151316

13161317
# TODO: add type annotations for kwargs
1317-
def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
1318+
def ones(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
13181319
"""Create an array with a fill value of one.
13191320
13201321
Parameters
@@ -1333,7 +1334,7 @@ def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
13331334

13341335

13351336
# TODO: add type annotations for kwargs
1336-
def ones_like(a: ArrayLike, **kwargs: Any) -> Array:
1337+
def ones_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
13371338
"""Create an array of ones like another array.
13381339
13391340
Parameters
@@ -1360,7 +1361,7 @@ def open_array(
13601361
path: PathLike = "",
13611362
storage_options: dict[str, Any] | None = None,
13621363
**kwargs: Any,
1363-
) -> Array:
1364+
) -> AnyArray:
13641365
"""Open an array using file-mode-like semantics.
13651366
13661367
Parameters
@@ -1402,7 +1403,7 @@ def open_array(
14021403

14031404

14041405
# TODO: add type annotations for kwargs
1405-
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
1406+
def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyArray:
14061407
"""Open a persistent array like another array.
14071408
14081409
Parameters
@@ -1423,7 +1424,7 @@ def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
14231424

14241425

14251426
# TODO: add type annotations for kwargs
1426-
def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
1427+
def zeros(shape: tuple[int, ...], **kwargs: Any) -> AnyArray:
14271428
"""Create an array with a fill value of zero.
14281429
14291430
Parameters
@@ -1442,7 +1443,7 @@ def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
14421443

14431444

14441445
# TODO: add type annotations for kwargs
1445-
def zeros_like(a: ArrayLike, **kwargs: Any) -> Array:
1446+
def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyArray:
14461447
"""Create an array of zeros like another array.
14471448
14481449
Parameters

0 commit comments

Comments
 (0)