77from collections .abc import Iterable
88from typing import TYPE_CHECKING , Any , TypedDict
99
10- import obstore as obs
11- from obstore .store import (
12- AzureStore ,
13- GCSStore ,
14- HTTPStore ,
15- LocalStore ,
16- MemoryStore ,
17- S3Store ,
18- )
19-
2010from zarr .abc .store import (
2111 ByteRequest ,
2212 OffsetByteRequest ,
3222 from typing import Any
3323
3424 from obstore import ListResult , ListStream , ObjectMeta , OffsetRange , SuffixRange
35- from obstore .store import ObjectStore as _ObjectStore
25+ from obstore .store import ObjectStore as _UpstreamObjectStore
3626
3727 from zarr .core .buffer import BufferPrototype
3828 from zarr .core .common import BytesLike
@@ -62,10 +52,19 @@ class ObjectStore(Store):
6252 raise an issue with any comments/concerns about the store.
6353 """
6454
65- store : _ObjectStore
55+ store : _UpstreamObjectStore
6656 """The underlying obstore instance."""
6757
6858 def __eq__ (self , value : object ) -> bool :
59+ from obstore .store import (
60+ AzureStore ,
61+ GCSStore ,
62+ HTTPStore ,
63+ LocalStore ,
64+ MemoryStore ,
65+ S3Store ,
66+ )
67+
6968 if not isinstance (value , ObjectStore ):
7069 return False
7170
@@ -119,7 +118,11 @@ def __eq__(self, value: object) -> bool:
119118 return False # Two memory stores can't be equal because we can't pickle memory stores
120119 return True
121120
122- def __init__ (self , store : _ObjectStore , * , read_only : bool = False ) -> None :
121+ def __init__ (self , store : _UpstreamObjectStore , * , read_only : bool = False ) -> None :
122+ import obstore as obs
123+
124+ self .obs = obs
125+
123126 if not isinstance (
124127 store ,
125128 (
@@ -154,6 +157,8 @@ async def get(
154157 self , key : str , prototype : BufferPrototype , byte_range : ByteRequest | None = None
155158 ) -> Buffer | None :
156159 # docstring inherited
160+ import obstore as obs
161+
157162 try :
158163 if byte_range is None :
159164 resp = await obs .get_async (self .store , key )
@@ -188,6 +193,8 @@ async def get_partial_values(
188193
189194 async def exists (self , key : str ) -> bool :
190195 # docstring inherited
196+ import obstore as obs
197+
191198 try :
192199 await obs .head_async (self .store , key )
193200 except FileNotFoundError :
@@ -202,6 +209,8 @@ def supports_writes(self) -> bool:
202209
203210 async def set (self , key : str , value : Buffer ) -> None :
204211 # docstring inherited
212+ import obstore as obs
213+
205214 self ._check_writable ()
206215 if not isinstance (value , Buffer ):
207216 raise TypeError (
@@ -212,6 +221,8 @@ async def set(self, key: str, value: Buffer) -> None:
212221
213222 async def set_if_not_exists (self , key : str , value : Buffer ) -> None :
214223 # docstring inherited
224+ import obstore as obs
225+
215226 self ._check_writable ()
216227 buf = value .to_bytes ()
217228 with contextlib .suppress (obs .exceptions .AlreadyExistsError ):
@@ -224,6 +235,8 @@ def supports_deletes(self) -> bool:
224235
225236 async def delete (self , key : str ) -> None :
226237 # docstring inherited
238+ import obstore as obs
239+
227240 self ._check_writable ()
228241 await obs .delete_async (self .store , key )
229242
@@ -245,16 +258,22 @@ def supports_listing(self) -> bool:
245258
246259 def list (self ) -> AsyncGenerator [str , None ]:
247260 # docstring inherited
261+ import obstore as obs
262+
248263 objects : ListStream [list [ObjectMeta ]] = obs .list (self .store )
249264 return _transform_list (objects )
250265
251266 def list_prefix (self , prefix : str ) -> AsyncGenerator [str , None ]:
252267 # docstring inherited
268+ import obstore as obs
269+
253270 objects : ListStream [list [ObjectMeta ]] = obs .list (self .store , prefix = prefix )
254271 return _transform_list (objects )
255272
256273 def list_dir (self , prefix : str ) -> AsyncGenerator [str , None ]:
257274 # docstring inherited
275+ import obstore as obs
276+
258277 coroutine = obs .list_with_delimiter_async (self .store , prefix = prefix )
259278 return _transform_list_dir (coroutine , prefix )
260279
@@ -332,7 +351,7 @@ class _Response(TypedDict):
332351
333352
334353async def _make_bounded_requests (
335- store : obs . store . ObjectStore ,
354+ store : _UpstreamObjectStore ,
336355 path : str ,
337356 requests : list [_BoundedRequest ],
338357 prototype : BufferPrototype ,
@@ -343,6 +362,7 @@ async def _make_bounded_requests(
343362 within a single file, and will e.g. merge concurrent requests. This only uses one
344363 single Python coroutine.
345364 """
365+ import obstore as obs
346366
347367 starts = [r ["start" ] for r in requests ]
348368 ends = [r ["end" ] for r in requests ]
@@ -361,7 +381,7 @@ async def _make_bounded_requests(
361381
362382
363383async def _make_other_request (
364- store : obs . store . ObjectStore ,
384+ store : _UpstreamObjectStore ,
365385 request : _OtherRequest ,
366386 prototype : BufferPrototype ,
367387) -> list [_Response ]:
@@ -370,6 +390,8 @@ async def _make_other_request(
370390 We return a `list[_Response]` for symmetry with `_make_bounded_requests` so that all
371391 futures can be gathered together.
372392 """
393+ import obstore as obs
394+
373395 if request ["range" ] is None :
374396 resp = await obs .get_async (store , request ["path" ])
375397 else :
@@ -384,7 +406,7 @@ async def _make_other_request(
384406
385407
386408async def _get_partial_values (
387- store : obs . store . ObjectStore ,
409+ store : _UpstreamObjectStore ,
388410 prototype : BufferPrototype ,
389411 key_ranges : Iterable [tuple [str , ByteRequest | None ]],
390412) -> list [Buffer | None ]:
0 commit comments