Skip to content

Commit 14e5573

Browse files
authored
Merge branch 'main' into chore/add-missing-tests
2 parents a9b4ad2 + 4b26501 commit 14e5573

28 files changed

+300
-260
lines changed

changes/3368.misc.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improved performance of reading arrays by not unnecessarily using
2+
the fill value.

changes/3374.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Replaces usage of the ``zarr.core.common.ChunkCoords`` typealias with ``tuple[int, ...]``.

changes/3378.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Ensure passing `config` is handled properly when `open`ing an existing
2+
array.
3+

docs/developers/roadmap.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Goals
5656
- Provide a complete implementation of Zarr V3 through the Zarr-Python
5757
API
5858
- Clear the way for exciting extensions / ZEPs
59-
(i.e. `sharding <https://zarr-specs.readthedocs.io/en/latest/v3/codecs/sharding-indexed/v1.0.html>`__,
59+
(i.e. `sharding <https://zarr-specs.readthedocs.io/en/latest/v3/codecs/sharding-indexed/>`__,
6060
`variable chunking <https://zarr.dev/zeps/draft/ZEP0003.html>`__,
6161
etc.)
6262
- Provide a developer API that can be used to implement and register V3

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["hatchling>=1.27.0", "hatch-vcs", "setuptools-scm!=9.0.0"]
2+
requires = ["hatchling>=1.27.0", "hatch-vcs"]
33
build-backend = "hatchling.build"
44

55
[tool.hatch.build.targets.sdist]

src/zarr/abc/codec.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from zarr.abc.metadata import Metadata
1010
from zarr.core.buffer import Buffer, NDBuffer
11-
from zarr.core.common import ChunkCoords, NamedConfig, concurrent_map
11+
from zarr.core.common import NamedConfig, concurrent_map
1212
from zarr.core.config import config
1313

1414
if TYPE_CHECKING:
@@ -120,7 +120,7 @@ def evolve_from_array_spec(self, array_spec: ArraySpec) -> Self:
120120
def validate(
121121
self,
122122
*,
123-
shape: ChunkCoords,
123+
shape: tuple[int, ...],
124124
dtype: ZDType[TBaseDType, TBaseScalar],
125125
chunk_grid: ChunkGrid,
126126
) -> None:
@@ -129,7 +129,7 @@ def validate(
129129
130130
Parameters
131131
----------
132-
shape : ChunkCoords
132+
shape : tuple[int, ...]
133133
The array shape
134134
dtype : np.dtype[Any]
135135
The array data type
@@ -335,14 +335,18 @@ def supports_partial_encode(self) -> bool: ...
335335

336336
@abstractmethod
337337
def validate(
338-
self, *, shape: ChunkCoords, dtype: ZDType[TBaseDType, TBaseScalar], chunk_grid: ChunkGrid
338+
self,
339+
*,
340+
shape: tuple[int, ...],
341+
dtype: ZDType[TBaseDType, TBaseScalar],
342+
chunk_grid: ChunkGrid,
339343
) -> None:
340344
"""Validates that all codec configurations are compatible with the array metadata.
341345
Raises errors when a codec configuration is not compatible.
342346
343347
Parameters
344348
----------
345-
shape : ChunkCoords
349+
shape : tuple[int, ...]
346350
The array shape
347351
dtype : np.dtype[Any]
348352
The array data type
@@ -423,6 +427,11 @@ async def read(
423427
The second slice selection determines where in the output array the chunk data will be written.
424428
The ByteGetter is used to fetch the necessary bytes.
425429
The chunk spec contains information about the construction of an array from the bytes.
430+
431+
If the Store returns ``None`` for a chunk, then the chunk was not
432+
written and the implementation must set the values of that chunk (or
433+
``out``) to the fill value for the array.
434+
426435
out : NDBuffer
427436
"""
428437
...

src/zarr/api/asynchronous.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from zarr.core.common import (
2525
JSON,
2626
AccessModeLiteral,
27-
ChunkCoords,
2827
DimensionNames,
2928
MemoryOrder,
3029
ZarrFormat,
@@ -106,7 +105,7 @@ def _infer_overwrite(mode: AccessModeLiteral) -> bool:
106105
return mode in _OVERWRITE_MODES
107106

108107

109-
def _get_shape_chunks(a: ArrayLike | Any) -> tuple[ChunkCoords | None, ChunkCoords | None]:
108+
def _get_shape_chunks(a: ArrayLike | Any) -> tuple[tuple[int, ...] | None, tuple[int, ...] | None]:
110109
"""Helper function to get the shape and chunks from an array-like object"""
111110
shape = None
112111
chunks = None
@@ -358,7 +357,9 @@ async def open(
358357
zarr_format = _metadata_dict["zarr_format"]
359358
is_v3_array = zarr_format == 3 and _metadata_dict.get("node_type") == "array"
360359
if is_v3_array or zarr_format == 2:
361-
return AsyncArray(store_path=store_path, metadata=_metadata_dict)
360+
return AsyncArray(
361+
store_path=store_path, metadata=_metadata_dict, config=kwargs.get("config")
362+
)
362363
except (AssertionError, FileNotFoundError, NodeTypeValidationError):
363364
pass
364365
return await open_group(store=store_path, zarr_format=zarr_format, mode=mode, **kwargs)
@@ -864,9 +865,9 @@ async def open_group(
864865

865866

866867
async def create(
867-
shape: ChunkCoords | int,
868+
shape: tuple[int, ...] | int,
868869
*, # Note: this is a change from v2
869-
chunks: ChunkCoords | int | bool | None = None,
870+
chunks: tuple[int, ...] | int | bool | None = None,
870871
dtype: ZDTypeLike | None = None,
871872
compressor: CompressorLike = "auto",
872873
fill_value: Any | None = DEFAULT_FILL_VALUE,
@@ -888,7 +889,7 @@ async def create(
888889
meta_array: Any | None = None, # TODO: need type
889890
attributes: dict[str, JSON] | None = None,
890891
# v3 only
891-
chunk_shape: ChunkCoords | int | None = None,
892+
chunk_shape: tuple[int, ...] | int | None = None,
892893
chunk_key_encoding: (
893894
ChunkKeyEncoding
894895
| tuple[Literal["default"], Literal[".", "/"]]
@@ -1073,7 +1074,7 @@ async def create(
10731074

10741075

10751076
async def empty(
1076-
shape: ChunkCoords, **kwargs: Any
1077+
shape: tuple[int, ...], **kwargs: Any
10771078
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
10781079
"""Create an empty array with the specified shape. The contents will be filled with the
10791080
array's fill value or zeros if no fill value is provided.
@@ -1125,7 +1126,7 @@ async def empty_like(
11251126

11261127
# TODO: add type annotations for fill_value and kwargs
11271128
async def full(
1128-
shape: ChunkCoords, fill_value: Any, **kwargs: Any
1129+
shape: tuple[int, ...], fill_value: Any, **kwargs: Any
11291130
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
11301131
"""Create an array, with `fill_value` being used as the default value for
11311132
uninitialized portions of the array.
@@ -1172,7 +1173,7 @@ async def full_like(
11721173

11731174

11741175
async def ones(
1175-
shape: ChunkCoords, **kwargs: Any
1176+
shape: tuple[int, ...], **kwargs: Any
11761177
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
11771178
"""Create an array, with one being used as the default value for
11781179
uninitialized portions of the array.
@@ -1295,7 +1296,7 @@ async def open_like(
12951296

12961297

12971298
async def zeros(
1298-
shape: ChunkCoords, **kwargs: Any
1299+
shape: tuple[int, ...], **kwargs: Any
12991300
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]:
13001301
"""Create an array, with zero being used as the default value for
13011302
uninitialized portions of the array.

src/zarr/api/synchronous.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from zarr.core.common import (
3434
JSON,
3535
AccessModeLiteral,
36-
ChunkCoords,
3736
DimensionNames,
3837
MemoryOrder,
3938
ShapeLike,
@@ -598,9 +597,9 @@ def create_group(
598597

599598
# TODO: add type annotations for kwargs
600599
def create(
601-
shape: ChunkCoords | int,
600+
shape: tuple[int, ...] | int,
602601
*, # Note: this is a change from v2
603-
chunks: ChunkCoords | int | bool | None = None,
602+
chunks: tuple[int, ...] | int | bool | None = None,
604603
dtype: ZDTypeLike | None = None,
605604
compressor: CompressorLike = "auto",
606605
fill_value: Any | None = DEFAULT_FILL_VALUE, # TODO: need type
@@ -622,7 +621,7 @@ def create(
622621
meta_array: Any | None = None, # TODO: need type
623622
attributes: dict[str, JSON] | None = None,
624623
# v3 only
625-
chunk_shape: ChunkCoords | int | None = None,
624+
chunk_shape: tuple[int, ...] | int | None = None,
626625
chunk_key_encoding: (
627626
ChunkKeyEncoding
628627
| tuple[Literal["default"], Literal[".", "/"]]
@@ -755,7 +754,7 @@ def create_array(
755754
shape: ShapeLike | None = None,
756755
dtype: ZDTypeLike | None = None,
757756
data: np.ndarray[Any, np.dtype[Any]] | None = None,
758-
chunks: ChunkCoords | Literal["auto"] = "auto",
757+
chunks: tuple[int, ...] | Literal["auto"] = "auto",
759758
shards: ShardsLike | None = None,
760759
filters: FiltersLike = "auto",
761760
compressors: CompressorsLike = "auto",
@@ -782,17 +781,17 @@ def create_array(
782781
name : str or None, optional
783782
The name of the array within the store. If ``name`` is ``None``, the array will be located
784783
at the root of the store.
785-
shape : ChunkCoords, optional
784+
shape : ShapeLike, optional
786785
Shape of the array. Must be ``None`` if ``data`` is provided.
787786
dtype : ZDTypeLike, optional
788787
Data type of the array. Must be ``None`` if ``data`` is provided.
789788
data : np.ndarray, optional
790789
Array-like data to use for initializing the array. If this parameter is provided, the
791790
``shape`` and ``dtype`` parameters must be ``None``.
792-
chunks : ChunkCoords, optional
791+
chunks : tuple[int, ...], optional
793792
Chunk shape of the array.
794793
If not specified, default are guessed based on the shape and dtype.
795-
shards : ChunkCoords, optional
794+
shards : tuple[int, ...], optional
796795
Shard shape of the array. The default value of ``None`` results in no sharding at all.
797796
filters : Iterable[Codec], optional
798797
Iterable of filters to apply to each chunk of the array, in order, before serializing that
@@ -920,7 +919,7 @@ def from_array(
920919
data: Array | npt.ArrayLike,
921920
write_data: bool = True,
922921
name: str | None = None,
923-
chunks: Literal["auto", "keep"] | ChunkCoords = "keep",
922+
chunks: Literal["auto", "keep"] | tuple[int, ...] = "keep",
924923
shards: ShardsLike | None | Literal["keep"] = "keep",
925924
filters: FiltersLike | Literal["keep"] = "keep",
926925
compressors: CompressorsLike | Literal["keep"] = "keep",
@@ -950,22 +949,22 @@ def from_array(
950949
name : str or None, optional
951950
The name of the array within the store. If ``name`` is ``None``, the array will be located
952951
at the root of the store.
953-
chunks : ChunkCoords or "auto" or "keep", optional
952+
chunks : tuple[int, ...] or "auto" or "keep", optional
954953
Chunk shape of the array.
955954
Following values are supported:
956955
957956
- "auto": Automatically determine the chunk shape based on the array's shape and dtype.
958957
- "keep": Retain the chunk shape of the data array if it is a zarr Array.
959-
- ChunkCoords: A tuple of integers representing the chunk shape.
958+
- tuple[int, ...]: A tuple of integers representing the chunk shape.
960959
961960
If not specified, defaults to "keep" if data is a zarr Array, otherwise "auto".
962-
shards : ChunkCoords, optional
961+
shards : tuple[int, ...], optional
963962
Shard shape of the array.
964963
Following values are supported:
965964
966965
- "auto": Automatically determine the shard shape based on the array's shape and chunk shape.
967966
- "keep": Retain the shard shape of the data array if it is a zarr Array.
968-
- ChunkCoords: A tuple of integers representing the shard shape.
967+
- tuple[int, ...]: A tuple of integers representing the shard shape.
969968
- None: No sharding.
970969
971970
If not specified, defaults to "keep" if data is a zarr Array, otherwise None.
@@ -1128,7 +1127,7 @@ def from_array(
11281127

11291128

11301129
# TODO: add type annotations for kwargs
1131-
def empty(shape: ChunkCoords, **kwargs: Any) -> Array:
1130+
def empty(shape: tuple[int, ...], **kwargs: Any) -> Array:
11321131
"""Create an empty array with the specified shape. The contents will be filled with the
11331132
array's fill value or zeros if no fill value is provided.
11341133
@@ -1181,7 +1180,7 @@ def empty_like(a: ArrayLike, **kwargs: Any) -> Array:
11811180

11821181

11831182
# TODO: add type annotations for kwargs and fill_value
1184-
def full(shape: ChunkCoords, fill_value: Any, **kwargs: Any) -> Array:
1183+
def full(shape: tuple[int, ...], fill_value: Any, **kwargs: Any) -> Array:
11851184
"""Create an array with a default fill value.
11861185
11871186
Parameters
@@ -1222,7 +1221,7 @@ def full_like(a: ArrayLike, **kwargs: Any) -> Array:
12221221

12231222

12241223
# TODO: add type annotations for kwargs
1225-
def ones(shape: ChunkCoords, **kwargs: Any) -> Array:
1224+
def ones(shape: tuple[int, ...], **kwargs: Any) -> Array:
12261225
"""Create an array with a fill value of one.
12271226
12281227
Parameters
@@ -1324,7 +1323,7 @@ def open_like(a: ArrayLike, path: str, **kwargs: Any) -> Array:
13241323

13251324

13261325
# TODO: add type annotations for kwargs
1327-
def zeros(shape: ChunkCoords, **kwargs: Any) -> Array:
1326+
def zeros(shape: tuple[int, ...], **kwargs: Any) -> Array:
13281327
"""Create an array with a fill value of zero.
13291328
13301329
Parameters

0 commit comments

Comments
 (0)