@@ -143,6 +143,7 @@ class MockEnvCodecPipeline(CodecPipeline):
143143        assert  get_pipeline_class (reload_config = True ) ==  MockEnvCodecPipeline 
144144
145145
146+ @pytest .mark .filterwarnings ("error" ) 
146147@pytest .mark .parametrize ("store" , ["local" , "memory" ], indirect = ["store" ]) 
147148def  test_config_codec_implementation (store : Store ) ->  None :
148149    # has default value 
@@ -156,24 +157,29 @@ async def _encode_single(
156157        ) ->  CodecOutput  |  None :
157158            _mock .call ()
158159
159-     config .set ({"codecs.blosc" : fully_qualified_name (MockBloscCodec )})
160160    register_codec ("blosc" , MockBloscCodec )
161-     assert  get_codec_class ("blosc" ) ==  MockBloscCodec 
162- 
163-     # test if codec is used 
164-     arr  =  Array .create (
165-         store = store ,
166-         shape = (100 ,),
167-         chunks = (10 ,),
168-         zarr_format = 3 ,
169-         dtype = "i4" ,
170-         codecs = [BytesCodec (), {"name" : "blosc" , "configuration" : {}}],
171-     )
172-     arr [:] =  range (100 )
173-     _mock .call .assert_called ()
161+     with  config .set ({"codecs.blosc" : fully_qualified_name (MockBloscCodec )}):
162+         assert  get_codec_class ("blosc" ) ==  MockBloscCodec 
163+ 
164+         # test if codec is used 
165+         arr  =  Array .create (
166+             store = store ,
167+             shape = (100 ,),
168+             chunks = (10 ,),
169+             zarr_format = 3 ,
170+             dtype = "i4" ,
171+             codecs = [BytesCodec (), {"name" : "blosc" , "configuration" : {}}],
172+         )
173+         arr [:] =  range (100 )
174+         _mock .call .assert_called ()
175+ 
176+     # test set codec with environment variable 
177+     class  NewBloscCodec (BloscCodec ):
178+         pass 
174179
175-     with  mock .patch .dict (os .environ , {"ZARR_CODECS__BLOSC" : fully_qualified_name (BloscCodec )}):
176-         assert  get_codec_class ("blosc" , reload_config = True ) ==  BloscCodec 
180+     register_codec ("blosc" , NewBloscCodec )
181+     with  mock .patch .dict (os .environ , {"ZARR_CODECS__BLOSC" : fully_qualified_name (NewBloscCodec )}):
182+         assert  get_codec_class ("blosc" , reload_config = True ) ==  NewBloscCodec 
177183
178184
179185@pytest .mark .parametrize ("store" , ["local" , "memory" ], indirect = ["store" ]) 
@@ -183,18 +189,17 @@ def test_config_ndbuffer_implementation(store: Store) -> None:
183189
184190    # set custom ndbuffer with TestNDArrayLike implementation 
185191    register_ndbuffer (NDBufferUsingTestNDArrayLike )
186-     config .set ({"ndbuffer" : fully_qualified_name (NDBufferUsingTestNDArrayLike )})
187-     assert  get_ndbuffer_class () ==  NDBufferUsingTestNDArrayLike 
188-     arr  =  Array .create (
189-         store = store ,
190-         shape = (100 ,),
191-         chunks = (10 ,),
192-         zarr_format = 3 ,
193-         dtype = "i4" ,
194-     )
195-     got  =  arr [:]
196-     print (type (got ))
197-     assert  isinstance (got , TestNDArrayLike )
192+     with  config .set ({"ndbuffer" : fully_qualified_name (NDBufferUsingTestNDArrayLike )}):
193+         assert  get_ndbuffer_class () ==  NDBufferUsingTestNDArrayLike 
194+         arr  =  Array .create (
195+             store = store ,
196+             shape = (100 ,),
197+             chunks = (10 ,),
198+             zarr_format = 3 ,
199+             dtype = "i4" ,
200+         )
201+         got  =  arr [:]
202+         assert  isinstance (got , TestNDArrayLike )
198203
199204
200205def  test_config_buffer_implementation () ->  None :
@@ -208,27 +213,53 @@ def test_config_buffer_implementation() -> None:
208213        arr [:] =  np .arange (100 )
209214
210215    register_buffer (TestBuffer )
211-     config .set ({"buffer" : fully_qualified_name (TestBuffer )})
212-     assert  get_buffer_class () ==  TestBuffer 
213- 
214-     # no error using TestBuffer 
215-     data  =  np .arange (100 )
216-     arr [:] =  np .arange (100 )
217-     assert  np .array_equal (arr [:], data )
218- 
219-     data2d  =  np .arange (1000 ).reshape (100 , 10 )
220-     arr_sharding  =  zeros (
221-         shape = (100 , 10 ),
222-         store = StoreExpectingTestBuffer (),
223-         codecs = [ShardingCodec (chunk_shape = (10 , 10 ))],
224-     )
225-     arr_sharding [:] =  data2d 
226-     assert  np .array_equal (arr_sharding [:], data2d )
216+     with  config .set ({"buffer" : fully_qualified_name (TestBuffer )}):
217+         assert  get_buffer_class () ==  TestBuffer 
227218
228-     arr_Crc32c  =  zeros (
229-         shape = (100 , 10 ),
230-         store = StoreExpectingTestBuffer (),
231-         codecs = [BytesCodec (), Crc32cCodec ()],
232-     )
233-     arr_Crc32c [:] =  data2d 
234-     assert  np .array_equal (arr_Crc32c [:], data2d )
219+         # no error using TestBuffer 
220+         data  =  np .arange (100 )
221+         arr [:] =  np .arange (100 )
222+         assert  np .array_equal (arr [:], data )
223+ 
224+         data2d  =  np .arange (1000 ).reshape (100 , 10 )
225+         arr_sharding  =  zeros (
226+             shape = (100 , 10 ),
227+             store = StoreExpectingTestBuffer (),
228+             codecs = [ShardingCodec (chunk_shape = (10 , 10 ))],
229+         )
230+         arr_sharding [:] =  data2d 
231+         assert  np .array_equal (arr_sharding [:], data2d )
232+ 
233+         arr_Crc32c  =  zeros (
234+             shape = (100 , 10 ),
235+             store = StoreExpectingTestBuffer (),
236+             codecs = [BytesCodec (), Crc32cCodec ()],
237+         )
238+         arr_Crc32c [:] =  data2d 
239+         assert  np .array_equal (arr_Crc32c [:], data2d )
240+ 
241+ 
242+ @pytest .mark .filterwarnings ("error" ) 
243+ def  test_warning_on_missing_codec_config () ->  None :
244+     class  NewCodec (BytesCodec ):
245+         pass 
246+ 
247+     class  NewCodec2 (BytesCodec ):
248+         pass 
249+ 
250+     # error if codec is not registered 
251+     with  pytest .raises (KeyError ):
252+         get_codec_class ("missing_codec" )
253+ 
254+     # no warning if only one implementation is available 
255+     register_codec ("new_codec" , NewCodec )
256+     get_codec_class ("new_codec" )
257+ 
258+     # warning because multiple implementations are available but none is selected in the config 
259+     register_codec ("new_codec" , NewCodec2 )
260+     with  pytest .warns (UserWarning ):
261+         get_codec_class ("new_codec" )
262+ 
263+     # no warning if multiple implementations are available and one is selected in the config 
264+     with  config .set ({"codecs.new_codec" : fully_qualified_name (NewCodec )}):
265+         get_codec_class ("new_codec" )
0 commit comments