33import pytest
44
55from zarr .attrs import Attributes
6- from zarr .tests .util import CountingDict
7- from zarr .storage import KVStore
6+ from zarr .storage import KVStore , KVStoreV3
7+ from zarr .tests .util import CountingDict , CountingDictV3
8+
9+
10+ @pytest .fixture (params = [2 , 3 ])
11+ def zarr_version (request ):
12+ return request .param
13+
14+
15+ def _init_store (version ):
16+ """Use a plain dict() for v2, but KVStoreV3 otherwise."""
17+ if version == 2 :
18+ return dict ()
19+ return KVStoreV3 (dict ())
820
921
1022class TestAttributes ():
1123
1224 def init_attributes (self , store , read_only = False , cache = True ):
1325 return Attributes (store , key = 'attrs' , read_only = read_only , cache = cache )
1426
15- @pytest .mark .parametrize ('store_from_dict' , [False , True ])
16- def test_storage (self , store_from_dict ):
27+ def test_storage (self , zarr_version ):
1728
18- if store_from_dict :
19- store = dict ()
20- else :
21- store = KVStore (dict ())
29+ store = _init_store (zarr_version )
2230 a = Attributes (store = store , key = 'attrs' )
2331 assert isinstance (a .store , KVStore )
2432 assert 'foo' not in a
@@ -30,11 +38,14 @@ def test_storage(self, store_from_dict):
3038 assert 'attrs' in store
3139 assert isinstance (store ['attrs' ], bytes )
3240 d = json .loads (str (store ['attrs' ], 'ascii' ))
41+ if zarr_version == 3 :
42+ d = d ['attributes' ]
3343 assert dict (foo = 'bar' , baz = 42 ) == d
3444
35- def test_get_set_del_contains (self ):
45+ def test_get_set_del_contains (self , zarr_version ):
3646
37- a = self .init_attributes (dict ())
47+ store = _init_store (zarr_version )
48+ a = self .init_attributes (store )
3849 assert 'foo' not in a
3950 a ['foo' ] = 'bar'
4051 a ['baz' ] = 42
@@ -48,9 +59,10 @@ def test_get_set_del_contains(self):
4859 # noinspection PyStatementEffect
4960 a ['foo' ]
5061
51- def test_update_put (self ):
62+ def test_update_put (self , zarr_version ):
5263
53- a = self .init_attributes (dict ())
64+ store = _init_store (zarr_version )
65+ a = self .init_attributes (store )
5466 assert 'foo' not in a
5567 assert 'bar' not in a
5668 assert 'baz' not in a
@@ -65,9 +77,10 @@ def test_update_put(self):
6577 assert a ['bar' ] == 84
6678 assert 'baz' not in a
6779
68- def test_iterators (self ):
80+ def test_iterators (self , zarr_version ):
6981
70- a = self .init_attributes (dict ())
82+ store = _init_store (zarr_version )
83+ a = self .init_attributes (store )
7184 assert 0 == len (a )
7285 assert set () == set (a )
7386 assert set () == set (a .keys ())
@@ -83,10 +96,13 @@ def test_iterators(self):
8396 assert {'bar' , 42 } == set (a .values ())
8497 assert {('foo' , 'bar' ), ('baz' , 42 )} == set (a .items ())
8598
86- def test_read_only (self ):
87- store = dict ( )
99+ def test_read_only (self , zarr_version ):
100+ store = _init_store ( zarr_version )
88101 a = self .init_attributes (store , read_only = True )
89- store ['attrs' ] = json .dumps (dict (foo = 'bar' , baz = 42 )).encode ('ascii' )
102+ if zarr_version == 2 :
103+ store ['attrs' ] = json .dumps (dict (foo = 'bar' , baz = 42 )).encode ('ascii' )
104+ else :
105+ store ['attrs' ] = json .dumps (dict (attributes = dict (foo = 'bar' , baz = 42 ))).encode ('ascii' )
90106 assert a ['foo' ] == 'bar'
91107 assert a ['baz' ] == 42
92108 with pytest .raises (PermissionError ):
@@ -96,8 +112,9 @@ def test_read_only(self):
96112 with pytest .raises (PermissionError ):
97113 a .update (foo = 'quux' )
98114
99- def test_key_completions (self ):
100- a = self .init_attributes (dict ())
115+ def test_key_completions (self , zarr_version ):
116+ store = _init_store (zarr_version )
117+ a = self .init_attributes (store )
101118 d = a ._ipython_key_completions_ ()
102119 assert 'foo' not in d
103120 assert '123' not in d
@@ -112,14 +129,17 @@ def test_key_completions(self):
112129 assert 'asdf;' in d
113130 assert 'baz' not in d
114131
115- def test_caching_on (self ):
132+ def test_caching_on (self , zarr_version ):
116133 # caching is turned on by default
117134
118135 # setup store
119- store = CountingDict ()
136+ store = CountingDict () if zarr_version == 2 else CountingDictV3 ()
120137 assert 0 == store .counter ['__getitem__' , 'attrs' ]
121138 assert 0 == store .counter ['__setitem__' , 'attrs' ]
122- store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
139+ if zarr_version == 2 :
140+ store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
141+ else :
142+ store ['attrs' ] = json .dumps (dict (attributes = dict (foo = 'xxx' , bar = 42 ))).encode ('ascii' )
123143 assert 0 == store .counter ['__getitem__' , 'attrs' ]
124144 assert 1 == store .counter ['__setitem__' , 'attrs' ]
125145
@@ -136,54 +156,65 @@ def test_caching_on(self):
136156
137157 # test __setitem__ updates the cache
138158 a ['foo' ] = 'yyy'
139- assert 2 == store .counter ['__getitem__' , 'attrs' ]
159+ get_cnt = 2 if zarr_version == 2 else 3
160+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
140161 assert 2 == store .counter ['__setitem__' , 'attrs' ]
141162 assert a ['foo' ] == 'yyy'
142- assert 2 == store .counter ['__getitem__' , 'attrs' ]
163+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
143164 assert 2 == store .counter ['__setitem__' , 'attrs' ]
144165
145166 # test update() updates the cache
146167 a .update (foo = 'zzz' , bar = 84 )
147- assert 3 == store .counter ['__getitem__' , 'attrs' ]
168+ get_cnt = 3 if zarr_version == 2 else 5
169+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
148170 assert 3 == store .counter ['__setitem__' , 'attrs' ]
149171 assert a ['foo' ] == 'zzz'
150172 assert a ['bar' ] == 84
151- assert 3 == store .counter ['__getitem__' , 'attrs' ]
173+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
152174 assert 3 == store .counter ['__setitem__' , 'attrs' ]
153175
154176 # test __contains__ uses the cache
155177 assert 'foo' in a
156- assert 3 == store .counter ['__getitem__' , 'attrs' ]
178+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
157179 assert 3 == store .counter ['__setitem__' , 'attrs' ]
158180 assert 'spam' not in a
159- assert 3 == store .counter ['__getitem__' , 'attrs' ]
181+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
160182 assert 3 == store .counter ['__setitem__' , 'attrs' ]
161183
162184 # test __delitem__ updates the cache
163185 del a ['bar' ]
164- assert 4 == store .counter ['__getitem__' , 'attrs' ]
186+ get_cnt = 4 if zarr_version == 2 else 7
187+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
165188 assert 4 == store .counter ['__setitem__' , 'attrs' ]
166189 assert 'bar' not in a
167- assert 4 == store .counter ['__getitem__' , 'attrs' ]
190+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
168191 assert 4 == store .counter ['__setitem__' , 'attrs' ]
169192
170193 # test refresh()
171- store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
172- assert 4 == store .counter ['__getitem__' , 'attrs' ]
194+ if zarr_version == 2 :
195+ store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
196+ else :
197+ store ['attrs' ] = json .dumps (dict (attributes = dict (foo = 'xxx' , bar = 42 ))).encode ('ascii' )
198+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
173199 a .refresh ()
174- assert 5 == store .counter ['__getitem__' , 'attrs' ]
200+ get_cnt = 5 if zarr_version == 2 else 8
201+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
175202 assert a ['foo' ] == 'xxx'
176- assert 5 == store .counter ['__getitem__' , 'attrs' ]
203+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
177204 assert a ['bar' ] == 42
178- assert 5 == store .counter ['__getitem__' , 'attrs' ]
205+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
179206
180- def test_caching_off (self ):
207+ def test_caching_off (self , zarr_version ):
181208
182209 # setup store
183- store = CountingDict ()
210+ store = CountingDict () if zarr_version == 2 else CountingDictV3 ()
184211 assert 0 == store .counter ['__getitem__' , 'attrs' ]
185212 assert 0 == store .counter ['__setitem__' , 'attrs' ]
186- store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
213+
214+ if zarr_version == 2 :
215+ store ['attrs' ] = json .dumps (dict (foo = 'xxx' , bar = 42 )).encode ('ascii' )
216+ else :
217+ store ['attrs' ] = json .dumps (dict (attributes = dict (foo = 'xxx' , bar = 42 ))).encode ('ascii' )
187218 assert 0 == store .counter ['__getitem__' , 'attrs' ]
188219 assert 1 == store .counter ['__setitem__' , 'attrs' ]
189220
@@ -200,25 +231,31 @@ def test_caching_off(self):
200231
201232 # test __setitem__
202233 a ['foo' ] = 'yyy'
203- assert 4 == store .counter ['__getitem__' , 'attrs' ]
234+ get_cnt = 4 if zarr_version == 2 else 5
235+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
204236 assert 2 == store .counter ['__setitem__' , 'attrs' ]
205237 assert a ['foo' ] == 'yyy'
206- assert 5 == store .counter ['__getitem__' , 'attrs' ]
238+ get_cnt = 5 if zarr_version == 2 else 6
239+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
207240 assert 2 == store .counter ['__setitem__' , 'attrs' ]
208241
209242 # test update()
210243 a .update (foo = 'zzz' , bar = 84 )
211- assert 6 == store .counter ['__getitem__' , 'attrs' ]
244+ get_cnt = 6 if zarr_version == 2 else 8
245+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
212246 assert 3 == store .counter ['__setitem__' , 'attrs' ]
213247 assert a ['foo' ] == 'zzz'
214248 assert a ['bar' ] == 84
215- assert 8 == store .counter ['__getitem__' , 'attrs' ]
249+ get_cnt = 8 if zarr_version == 2 else 10
250+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
216251 assert 3 == store .counter ['__setitem__' , 'attrs' ]
217252
218253 # test __contains__
219254 assert 'foo' in a
220- assert 9 == store .counter ['__getitem__' , 'attrs' ]
255+ get_cnt = 9 if zarr_version == 2 else 11
256+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
221257 assert 3 == store .counter ['__setitem__' , 'attrs' ]
222258 assert 'spam' not in a
223- assert 10 == store .counter ['__getitem__' , 'attrs' ]
259+ get_cnt = 10 if zarr_version == 2 else 12
260+ assert get_cnt == store .counter ['__getitem__' , 'attrs' ]
224261 assert 3 == store .counter ['__setitem__' , 'attrs' ]
0 commit comments