11from __future__ import annotations
22
3- from typing import TYPE_CHECKING
3+ from typing import TYPE_CHECKING , Any , TypedDict
44
55import pytest
66
7- from zarr .core .buffer .cpu import Buffer , buffer_prototype
7+ from zarr .abc .store import ByteRequest , Store
8+ from zarr .core .buffer import Buffer
9+ from zarr .core .buffer .cpu import buffer_prototype
810from zarr .storage import LocalStore , WrapperStore
911from zarr .testing .store import StoreTests
1012
1113if TYPE_CHECKING :
12- from _pytest . compat import LEGACY_PATH
14+ from pathlib import Path
1315
14- from zarr .abc .store import Store
1516 from zarr .core .buffer .core import BufferPrototype
1617
1718
19+ class StoreKwargs (TypedDict ):
20+ store : LocalStore
21+
22+
23+ class OpenKwargs (TypedDict ):
24+ store_cls : type [LocalStore ]
25+ root : str
26+
27+
1828# TODO: fix this warning
1929@pytest .mark .filterwarnings (
2030 "ignore:coroutine 'ClientCreatorContext.__aexit__' was never awaited:RuntimeWarning"
2131)
22- class TestWrapperStore (StoreTests [WrapperStore , Buffer ]):
23- store_cls = WrapperStore
32+ class TestWrapperStore (StoreTests [WrapperStore [ LocalStore ] , Buffer ]):
33+ store_cls = WrapperStore [ LocalStore ]
2434 buffer_cls = Buffer
2535
26- async def get (self , store : WrapperStore , key : str ) -> Buffer :
36+ async def get (self , store : WrapperStore [ LocalStore ] , key : str ) -> Buffer :
2737 return self .buffer_cls .from_bytes ((store ._store .root / key ).read_bytes ())
2838
29- async def set (self , store : WrapperStore , key : str , value : Buffer ) -> None :
39+ async def set (self , store : WrapperStore [ LocalStore ] , key : str , value : Buffer ) -> None :
3040 parent = (store ._store .root / key ).parent
3141 if not parent .exists ():
3242 parent .mkdir (parents = True )
3343 (store ._store .root / key ).write_bytes (value .to_bytes ())
3444
3545 @pytest .fixture
36- def store_kwargs (self , tmpdir : LEGACY_PATH ) -> dict [ str , str ] :
37- return {"store" : LocalStore (str (tmpdir ))}
46+ def store_kwargs (self , tmp_path : Path ) -> StoreKwargs :
47+ return {"store" : LocalStore (str (tmp_path ))}
3848
3949 @pytest .fixture
40- def open_kwargs (self , tmpdir ) -> dict [ str , str ] :
41- return {"store_cls" : LocalStore , "root" : str (tmpdir )}
50+ def open_kwargs (self , tmp_path : Path ) -> OpenKwargs :
51+ return {"store_cls" : LocalStore , "root" : str (tmp_path )}
4252
43- def test_store_supports_writes (self , store : WrapperStore ) -> None :
53+ def test_store_supports_writes (self , store : WrapperStore [ LocalStore ] ) -> None :
4454 assert store .supports_writes
4555
46- def test_store_supports_partial_writes (self , store : WrapperStore ) -> None :
56+ def test_store_supports_partial_writes (self , store : WrapperStore [ LocalStore ] ) -> None :
4757 assert store .supports_partial_writes
4858
49- def test_store_supports_listing (self , store : WrapperStore ) -> None :
59+ def test_store_supports_listing (self , store : WrapperStore [ LocalStore ] ) -> None :
5060 assert store .supports_listing
5161
52- def test_store_repr (self , store : WrapperStore ) -> None :
62+ def test_store_repr (self , store : WrapperStore [ LocalStore ] ) -> None :
5363 assert f"{ store !r} " == f"WrapperStore(LocalStore, 'file://{ store ._store .root .as_posix ()} ')"
5464
55- def test_store_str (self , store : WrapperStore ) -> None :
65+ def test_store_str (self , store : WrapperStore [ LocalStore ] ) -> None :
5666 assert str (store ) == f"wrapping-file://{ store ._store .root .as_posix ()} "
5767
58- def test_check_writeable (self , store : WrapperStore ) -> None :
68+ def test_check_writeable (self , store : WrapperStore [ LocalStore ] ) -> None :
5969 """
6070 Test _check_writeable() runs without errors.
6171 """
6272 store ._check_writable ()
6373
64- def test_close (self , store : WrapperStore ) -> None :
74+ def test_close (self , store : WrapperStore [ LocalStore ] ) -> None :
6575 "Test store can be closed"
6676 store .close ()
6777 assert not store ._is_open
6878
69- def test_is_open_setter_raises (self , store : WrapperStore ) -> None :
79+ def test_is_open_setter_raises (self , store : WrapperStore [ LocalStore ] ) -> None :
7080 """
7181 Test that a user cannot change `_is_open` without opening the underlying store.
7282 """
@@ -83,7 +93,7 @@ def test_is_open_setter_raises(self, store: WrapperStore) -> None:
8393@pytest .mark .parametrize ("store" , ["local" , "memory" , "zip" ], indirect = True )
8494async def test_wrapped_set (store : Store , capsys : pytest .CaptureFixture [str ]) -> None :
8595 # define a class that prints when it sets
86- class NoisySetter (WrapperStore ):
96+ class NoisySetter (WrapperStore [ Store ] ):
8797 async def set (self , key : str , value : Buffer ) -> None :
8898 print (f"setting { key } " )
8999 await super ().set (key , value )
@@ -101,15 +111,17 @@ async def set(self, key: str, value: Buffer) -> None:
101111@pytest .mark .parametrize ("store" , ["local" , "memory" , "zip" ], indirect = True )
102112async def test_wrapped_get (store : Store , capsys : pytest .CaptureFixture [str ]) -> None :
103113 # define a class that prints when it sets
104- class NoisyGetter (WrapperStore ):
105- def get (self , key : str , prototype : BufferPrototype ) -> None :
114+ class NoisyGetter (WrapperStore [Any ]):
115+ async def get (
116+ self , key : str , prototype : BufferPrototype , byte_range : ByteRequest | None = None
117+ ) -> None :
106118 print (f"getting { key } " )
107- return super ().get (key , prototype = prototype )
119+ await super ().get (key , prototype = prototype , byte_range = byte_range )
108120
109121 key = "foo"
110122 value = Buffer .from_bytes (b"bar" )
111123 store_wrapped = NoisyGetter (store )
112124 await store_wrapped .set (key , value )
113- assert await store_wrapped .get (key , buffer_prototype ) == value
125+ await store_wrapped .get (key , buffer_prototype )
114126 captured = capsys .readouterr ()
115127 assert f"getting { key } " in captured .out
0 commit comments