Skip to content

Commit b564ae6

Browse files
committed
rename (Async)Array.create to _create
1 parent e24bdeb commit b564ae6

17 files changed

+258
-315
lines changed

src/zarr/api/asynchronous.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ async def save_array(
425425
shape = arr.shape
426426
chunks = getattr(arr, "chunks", None) # for array-likes with chunks attribute
427427
overwrite = kwargs.pop("overwrite", None) or _infer_overwrite(mode)
428-
new = await AsyncArray.create(
428+
new = await AsyncArray._create(
429429
store_path,
430430
zarr_format=zarr_format,
431431
shape=shape,
@@ -1041,7 +1041,7 @@ async def create(
10411041

10421042
config_parsed = ArrayConfig.from_dict(config_dict)
10431043

1044-
return await AsyncArray.create(
1044+
return await AsyncArray._create(
10451045
store_path,
10461046
shape=shape,
10471047
chunks=chunks,

src/zarr/core/array.py

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from dataclasses import dataclass, field
88
from itertools import starmap
99
from logging import getLogger
10-
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeAlias, cast, overload
10+
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeAlias, TypedDict, cast, overload
1111
from warnings import warn
1212

1313
import numcodecs
@@ -109,8 +109,10 @@
109109
from typing import Self
110110

111111
from zarr.abc.codec import CodecPipeline
112+
from zarr.codecs.sharding import ShardingCodecIndexLocation
112113
from zarr.core.group import AsyncGroup
113114

115+
114116
# Array and AsyncArray are defined in the base ``zarr`` namespace
115117
__all__ = ["create_codec_pipeline", "parse_array_metadata"]
116118

@@ -271,7 +273,7 @@ def __init__(
271273
# this overload defines the function signature when zarr_format is 2
272274
@overload
273275
@classmethod
274-
async def create(
276+
async def _create(
275277
cls,
276278
store: StoreLike,
277279
*,
@@ -295,7 +297,7 @@ async def create(
295297
# this overload defines the function signature when zarr_format is 3
296298
@overload
297299
@classmethod
298-
async def create(
300+
async def _create(
299301
cls,
300302
store: StoreLike,
301303
*,
@@ -323,7 +325,7 @@ async def create(
323325

324326
@overload
325327
@classmethod
326-
async def create(
328+
async def _create(
327329
cls,
328330
store: StoreLike,
329331
*,
@@ -350,7 +352,7 @@ async def create(
350352
) -> AsyncArray[ArrayV3Metadata]: ...
351353
@overload
352354
@classmethod
353-
async def create(
355+
async def _create(
354356
cls,
355357
store: StoreLike,
356358
*,
@@ -383,7 +385,7 @@ async def create(
383385
) -> AsyncArray[ArrayV3Metadata] | AsyncArray[ArrayV2Metadata]: ...
384386

385387
@classmethod
386-
async def create(
388+
async def _create(
387389
cls,
388390
store: StoreLike,
389391
*,
@@ -494,19 +496,6 @@ async def create(
494496
-------
495497
AsyncArray
496498
The created asynchronous array instance.
497-
498-
Examples
499-
--------
500-
>>> import zarr
501-
>>> store = zarr.storage.MemoryStore(mode='w')
502-
>>> async_arr = await zarr.core.array.AsyncArray.create(
503-
>>> store=store,
504-
>>> shape=(100,100),
505-
>>> chunks=(10,10),
506-
>>> dtype='i4',
507-
>>> fill_value=0)
508-
<AsyncArray memory://140349042942400 shape=(100, 100) dtype=int32>
509-
510499
"""
511500
store_path = await make_store_path(store)
512501

@@ -1148,7 +1137,7 @@ async def getitem(
11481137
--------
11491138
>>> import zarr
11501139
>>> store = zarr.storage.MemoryStore(mode='w')
1151-
>>> async_arr = await zarr.core.array.AsyncArray.create(
1140+
>>> async_arr = await zarr.api.asynchronous.create_array(
11521141
... store=store,
11531142
... shape=(100,100),
11541143
... chunks=(10,10),
@@ -1542,7 +1531,7 @@ class Array:
15421531

15431532
@classmethod
15441533
@_deprecate_positional_args
1545-
def create(
1534+
def _create(
15461535
cls,
15471536
store: StoreLike,
15481537
*,
@@ -1643,7 +1632,7 @@ def create(
16431632
Array created from the store.
16441633
"""
16451634
async_array = sync(
1646-
AsyncArray.create(
1635+
AsyncArray._create(
16471636
store=store,
16481637
shape=shape,
16491638
dtype=dtype,
@@ -2025,10 +2014,10 @@ def __getitem__(self, selection: Selection) -> NDArrayLike:
20252014
>>> import zarr
20262015
>>> import numpy as np
20272016
>>> data = np.arange(100, dtype="uint16")
2028-
>>> z = Array.create(
2017+
>>> z = zarr.create_array(
20292018
>>> StorePath(MemoryStore(mode="w")),
20302019
>>> shape=data.shape,
2031-
>>> chunk_shape=(10,),
2020+
>>> chunks=(10,),
20322021
>>> dtype=data.dtype,
20332022
>>> )
20342023
>>> z[:] = data
@@ -2059,10 +2048,10 @@ def __getitem__(self, selection: Selection) -> NDArrayLike:
20592048
Setup a 2-dimensional array::
20602049
20612050
>>> data = np.arange(100, dtype="uint16").reshape(10, 10)
2062-
>>> z = Array.create(
2051+
>>> z = zarr.create_array(
20632052
>>> StorePath(MemoryStore(mode="w")),
20642053
>>> shape=data.shape,
2065-
>>> chunk_shape=(10, 10),
2054+
>>> chunks=(10, 10),
20662055
>>> dtype=data.dtype,
20672056
>>> )
20682057
>>> z[:] = data
@@ -2290,10 +2279,10 @@ def get_basic_selection(
22902279
>>> import zarr
22912280
>>> import numpy as np
22922281
>>> data = np.arange(100, dtype="uint16")
2293-
>>> z = Array.create(
2282+
>>> z = zarr.create_array(
22942283
>>> StorePath(MemoryStore(mode="w")),
22952284
>>> shape=data.shape,
2296-
>>> chunk_shape=(3,),
2285+
>>> chunks=(3,),
22972286
>>> dtype=data.dtype,
22982287
>>> )
22992288
>>> z[:] = data
@@ -2319,10 +2308,10 @@ def get_basic_selection(
23192308
Setup a 3-dimensional array::
23202309
23212310
>>> data = np.arange(1000).reshape(10, 10, 10)
2322-
>>> z = Array.create(
2311+
>>> z = zarr.create_array(
23232312
>>> StorePath(MemoryStore(mode="w")),
23242313
>>> shape=data.shape,
2325-
>>> chunk_shape=(5, 5, 5),
2314+
>>> chunks=(5, 5, 5),
23262315
>>> dtype=data.dtype,
23272316
>>> )
23282317
>>> z[:] = data
@@ -2514,10 +2503,10 @@ def get_orthogonal_selection(
25142503
>>> import zarr
25152504
>>> import numpy as np
25162505
>>> data = np.arange(100).reshape(10, 10)
2517-
>>> z = Array.create(
2506+
>>> z = zarr.create_array(
25182507
>>> StorePath(MemoryStore(mode="w")),
25192508
>>> shape=data.shape,
2520-
>>> chunk_shape=data.shape,
2509+
>>> chunks=data.shape,
25212510
>>> dtype=data.dtype,
25222511
>>> )
25232512
>>> z[:] = data
@@ -2748,10 +2737,10 @@ def get_mask_selection(
27482737
>>> import zarr
27492738
>>> import numpy as np
27502739
>>> data = np.arange(100).reshape(10, 10)
2751-
>>> z = Array.create(
2740+
>>> z = zarr.create_array(
27522741
>>> StorePath(MemoryStore(mode="w")),
27532742
>>> shape=data.shape,
2754-
>>> chunk_shape=data.shape,
2743+
>>> chunks=data.shape,
27552744
>>> dtype=data.dtype,
27562745
>>> )
27572746
>>> z[:] = data
@@ -2908,10 +2897,10 @@ def get_coordinate_selection(
29082897
>>> import zarr
29092898
>>> import numpy as np
29102899
>>> data = np.arange(0, 100, dtype="uint16").reshape((10, 10))
2911-
>>> z = Array.create(
2900+
>>> z = zarr.create_array(
29122901
>>> StorePath(MemoryStore(mode="w")),
29132902
>>> shape=data.shape,
2914-
>>> chunk_shape=(3, 3),
2903+
>>> chunks=(3, 3),
29152904
>>> dtype=data.dtype,
29162905
>>> )
29172906
>>> z[:] = data
@@ -3096,10 +3085,10 @@ def get_block_selection(
30963085
>>> import zarr
30973086
>>> import numpy as np
30983087
>>> data = np.arange(0, 100, dtype="uint16").reshape((10, 10))
3099-
>>> z = Array.create(
3088+
>>> z = zarr.create_array(
31003089
>>> StorePath(MemoryStore(mode="w")),
31013090
>>> shape=data.shape,
3102-
>>> chunk_shape=(3, 3),
3091+
>>> chunks=(3, 3),
31033092
>>> dtype=data.dtype,
31043093
>>> )
31053094
>>> z[:] = data
@@ -3517,14 +3506,22 @@ def _get_default_codecs(
35173506
)
35183507

35193508

3509+
class ShardsConfigParam(TypedDict):
3510+
shape: ChunkCoords
3511+
index_location: ShardingCodecIndexLocation | None
3512+
3513+
3514+
ShardsParam: TypeAlias = ChunkCoords | ShardsConfigParam | Literal["auto"]
3515+
3516+
35203517
async def create_array(
35213518
store: str | StoreLike,
35223519
*,
35233520
name: str | None = None,
35243521
shape: ShapeLike,
35253522
dtype: npt.DTypeLike,
35263523
chunks: ChunkCoords | Literal["auto"] = "auto",
3527-
shards: ChunkCoords | Literal["auto"] | None = None,
3524+
shards: ShardsParam | None = None,
35283525
filters: FiltersParam = "auto",
35293526
compressors: CompressorsParam = "auto",
35303527
fill_value: Any | None = 0,
@@ -3616,13 +3613,24 @@ async def create_array(
36163613
-------
36173614
z : array
36183615
The array.
3616+
3617+
Examples
3618+
--------
3619+
>>> import zarr
3620+
>>> store = zarr.storage.MemoryStore(mode='w')
3621+
>>> async_arr = await zarr.api.asynchronous.create_array(
3622+
>>> store=store,
3623+
>>> shape=(100,100),
3624+
>>> chunks=(10,10),
3625+
>>> dtype='i4',
3626+
>>> fill_value=0)
3627+
<AsyncArray memory://140349042942400 shape=(100, 100) dtype=int32>
36193628
"""
36203629

36213630
if zarr_format is None:
36223631
zarr_format = _default_zarr_version()
36233632

3624-
# TODO: figure out why putting these imports at top-level causes circular imports
3625-
from zarr.codecs.sharding import ShardingCodec
3633+
from zarr.codecs.sharding import ShardingCodec, ShardingCodecIndexLocation
36263634

36273635
mode: Literal["a"] = "a"
36283636
dtype_parsed = parse_dtype(dtype, zarr_format=zarr_format)
@@ -3677,7 +3685,14 @@ async def create_array(
36773685
sub_codecs = cast(tuple[Codec, ...], (*array_array, array_bytes, *bytes_bytes))
36783686
codecs_out: tuple[Codec, ...]
36793687
if shard_shape_parsed is not None:
3680-
sharding_codec = ShardingCodec(chunk_shape=chunk_shape_parsed, codecs=sub_codecs)
3688+
index_location = None
3689+
if isinstance(shards, dict):
3690+
index_location = ShardingCodecIndexLocation(shards.get("index_location", None))
3691+
if index_location is None:
3692+
index_location = ShardingCodecIndexLocation.end
3693+
sharding_codec = ShardingCodec(
3694+
chunk_shape=chunk_shape_parsed, codecs=sub_codecs, index_location=index_location
3695+
)
36813696
sharding_codec.validate(
36823697
shape=chunk_shape_parsed,
36833698
dtype=dtype_parsed,

src/zarr/core/chunk_grids.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from collections.abc import Iterator
2828
from typing import Self
2929

30+
from zarr.core.array import ShardsParam
31+
3032

3133
def _guess_chunks(
3234
shape: ShapeLike,
@@ -201,7 +203,7 @@ def _auto_partition(
201203
*,
202204
array_shape: tuple[int, ...],
203205
chunk_shape: tuple[int, ...] | Literal["auto"],
204-
shard_shape: tuple[int, ...] | Literal["auto"] | None,
206+
shard_shape: ShardsParam | None,
205207
dtype: np.dtype[Any],
206208
) -> tuple[tuple[int, ...] | None, tuple[int, ...]]:
207209
"""
@@ -241,6 +243,8 @@ def _auto_partition(
241243
_shards_out += (c_shape * 2,)
242244
else:
243245
_shards_out += (c_shape,)
246+
elif isinstance(shard_shape, dict):
247+
_shards_out = tuple(shard_shape["shape"])
244248
else:
245249
_shards_out = shard_shape
246250

0 commit comments

Comments
 (0)