1+ from __future__ import annotations
2+
13from abc import ABC , abstractmethod
24from asyncio import gather
35from collections .abc import AsyncGenerator , Iterable
46from 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
1322class 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
262284class 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
269291class 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
0 commit comments