Skip to content

Commit f1d0253

Browse files
authored
Merge branch 'v3' into chore/drop-py310-np124
2 parents e934785 + 6984294 commit f1d0253

File tree

22 files changed

+797
-70
lines changed

22 files changed

+797
-70
lines changed

.deepsource.toml

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/zarr/abc/store.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1+
from __future__ import annotations
2+
13
from abc import ABC, abstractmethod
24
from asyncio import gather
35
from collections.abc import AsyncGenerator, Iterable
46
from types import TracebackType
5-
from typing import Any, NamedTuple, Protocol, Self, runtime_checkable
7+
from typing import TYPE_CHECKING, Any, NamedTuple, Protocol, runtime_checkable
8+
9+
if TYPE_CHECKING:
10+
from collections.abc import AsyncGenerator, Iterable
11+
from types import TracebackType
12+
from typing import Any, TypeAlias, Self
613

7-
from zarr.core.buffer import Buffer, BufferPrototype
8-
from zarr.core.common import AccessModeLiteral, BytesLike
14+
from zarr.core.buffer import Buffer, BufferPrototype
15+
from zarr.core.common import AccessModeLiteral, BytesLike
916

1017
__all__ = ["Store", "AccessMode", "ByteGetter", "ByteSetter", "set_or_delete"]
1118

19+
ByteRangeRequest: TypeAlias = tuple[int | None, int | None]
20+
1221

1322
class AccessMode(NamedTuple):
1423
str: AccessModeLiteral
@@ -98,14 +107,14 @@ async def get(
98107
self,
99108
key: str,
100109
prototype: BufferPrototype,
101-
byte_range: tuple[int | None, int | None] | None = None,
110+
byte_range: ByteRangeRequest | None = None,
102111
) -> Buffer | None:
103112
"""Retrieve the value associated with a given key.
104113
105114
Parameters
106115
----------
107116
key : str
108-
byte_range : tuple[int, Optional[int]], optional
117+
byte_range : tuple[int | None, int | None], optional
109118
110119
Returns
111120
-------
@@ -117,13 +126,13 @@ async def get(
117126
async def get_partial_values(
118127
self,
119128
prototype: BufferPrototype,
120-
key_ranges: list[tuple[str, tuple[int | None, int | None]]],
129+
key_ranges: Iterable[tuple[str, ByteRangeRequest]],
121130
) -> list[Buffer | None]:
122131
"""Retrieve possibly partial values from given key_ranges.
123132
124133
Parameters
125134
----------
126-
key_ranges : list[tuple[str, tuple[int, int]]]
135+
key_ranges : Iterable[tuple[str, tuple[int | None, int | None]]]
127136
Ordered set of key, range pairs, a key may occur multiple times with different ranges
128137
129138
Returns
@@ -193,7 +202,9 @@ def supports_partial_writes(self) -> bool:
193202
...
194203

195204
@abstractmethod
196-
async def set_partial_values(self, key_start_values: list[tuple[str, int, BytesLike]]) -> None:
205+
async def set_partial_values(
206+
self, key_start_values: Iterable[tuple[str, int, BytesLike]]
207+
) -> None:
197208
"""Store values at a given key, starting at byte range_start.
198209
199210
Parameters
@@ -257,21 +268,32 @@ def close(self) -> None:
257268
"""Close the store."""
258269
self._is_open = False
259270

271+
async def _get_many(
272+
self, requests: Iterable[tuple[str, BufferPrototype, ByteRangeRequest | None]]
273+
) -> AsyncGenerator[tuple[str, Buffer | None], None]:
274+
"""
275+
Retrieve a collection of objects from storage. In general this method does not guarantee
276+
that objects will be retrieved in the order in which they were requested, so this method
277+
yields tuple[str, Buffer | None] instead of just Buffer | None
278+
"""
279+
for req in requests:
280+
yield (req[0], await self.get(*req))
281+
260282

261283
@runtime_checkable
262284
class ByteGetter(Protocol):
263285
async def get(
264-
self, prototype: BufferPrototype, byte_range: tuple[int, int | None] | None = None
286+
self, prototype: BufferPrototype, byte_range: ByteRangeRequest | None = None
265287
) -> Buffer | None: ...
266288

267289

268290
@runtime_checkable
269291
class ByteSetter(Protocol):
270292
async def get(
271-
self, prototype: BufferPrototype, byte_range: tuple[int, int | None] | None = None
293+
self, prototype: BufferPrototype, byte_range: ByteRangeRequest | None = None
272294
) -> Buffer | None: ...
273295

274-
async def set(self, value: Buffer, byte_range: tuple[int, int] | None = None) -> None: ...
296+
async def set(self, value: Buffer, byte_range: ByteRangeRequest | None = None) -> None: ...
275297

276298
async def delete(self) -> None: ...
277299

src/zarr/codecs/sharding.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
Codec,
1818
CodecPipeline,
1919
)
20-
from zarr.abc.store import ByteGetter, ByteSetter
20+
from zarr.abc.store import ByteGetter, ByteRangeRequest, ByteSetter
2121
from zarr.codecs.bytes import BytesCodec
2222
from zarr.codecs.crc32c_ import Crc32cCodec
2323
from zarr.core.array_spec import ArraySpec
@@ -77,7 +77,7 @@ class _ShardingByteGetter(ByteGetter):
7777
chunk_coords: ChunkCoords
7878

7979
async def get(
80-
self, prototype: BufferPrototype, byte_range: tuple[int, int | None] | None = None
80+
self, prototype: BufferPrototype, byte_range: ByteRangeRequest | None = None
8181
) -> Buffer | None:
8282
assert byte_range is None, "byte_range is not supported within shards"
8383
assert (
@@ -90,7 +90,7 @@ async def get(
9090
class _ShardingByteSetter(_ShardingByteGetter, ByteSetter):
9191
shard_dict: ShardMutableMapping
9292

93-
async def set(self, value: Buffer, byte_range: tuple[int, int] | None = None) -> None:
93+
async def set(self, value: Buffer, byte_range: ByteRangeRequest | None = None) -> None:
9494
assert byte_range is None, "byte_range is not supported within shards"
9595
self.shard_dict[self.chunk_coords] = value
9696

0 commit comments

Comments
 (0)