66import numcodecs .abc
77import numpy as np
88import pytest
9- from numcodecs .zarr3 import LZMA , Delta
109
1110import zarr
1211from tests .test_cli .conftest import create_nested_zarr
3231
3332runner = typer_testing .CliRunner ()
3433
34+ NUMCODECS_USER_WARNING = "Numcodecs codecs are not in the Zarr version 3 specification and may not be supported by other zarr implementations."
35+
3536
3637def test_migrate_array (local_store : LocalStore ) -> None :
3738 shape = (10 , 10 )
@@ -283,28 +284,8 @@ def test_migrate_sub_group(
283284 ),
284285 (numcodecs .Zstd (level = 3 ), ZstdCodec (level = 3 )),
285286 (numcodecs .GZip (level = 3 ), GzipCodec (level = 3 )),
286- (
287- numcodecs .LZMA (
288- format = lzma .FORMAT_RAW ,
289- check = - 1 ,
290- preset = None ,
291- filters = [
292- {"id" : lzma .FILTER_DELTA , "dist" : 4 },
293- {"id" : lzma .FILTER_LZMA2 , "preset" : 1 },
294- ],
295- ),
296- LZMA (
297- format = lzma .FORMAT_RAW ,
298- check = - 1 ,
299- preset = None ,
300- filters = [
301- {"id" : lzma .FILTER_DELTA , "dist" : 4 },
302- {"id" : lzma .FILTER_LZMA2 , "preset" : 1 },
303- ],
304- ),
305- ),
306287 ],
307- ids = ["blosc" , "zstd" , "gzip" , "numcodecs-compressor" ],
288+ ids = ["blosc" , "zstd" , "gzip" ],
308289)
309290def test_migrate_compressor (
310291 local_store : LocalStore , compressor_v2 : numcodecs .abc .Codec , compressor_v3 : Codec
@@ -334,9 +315,54 @@ def test_migrate_compressor(
334315 assert np .all (zarr_array [:] == 1 )
335316
336317
318+ @pytest .mark .filterwarnings (f"ignore:{ NUMCODECS_USER_WARNING } :UserWarning" )
319+ def test_migrate_numcodecs_compressor (local_store : LocalStore ) -> None :
320+ """Test migration of a numcodecs compressor without a zarr.codecs equivalent."""
321+
322+ lzma_settings = {
323+ "format" : lzma .FORMAT_RAW ,
324+ "check" : - 1 ,
325+ "preset" : None ,
326+ "filters" : [
327+ {"id" : lzma .FILTER_DELTA , "dist" : 4 },
328+ {"id" : lzma .FILTER_LZMA2 , "preset" : 1 },
329+ ],
330+ }
331+
332+ zarr_array = zarr .create_array (
333+ store = local_store ,
334+ shape = (10 , 10 ),
335+ chunks = (10 , 10 ),
336+ dtype = "uint16" ,
337+ compressors = numcodecs .LZMA .from_config (lzma_settings ),
338+ zarr_format = 2 ,
339+ fill_value = 0 ,
340+ )
341+ zarr_array [:] = 1
342+
343+ result = runner .invoke (cli .app , ["migrate" , "v3" , str (local_store .root )])
344+ assert result .exit_code == 0
345+ assert (local_store .root / "zarr.json" ).exists ()
346+
347+ zarr_array = zarr .open_array (local_store .root , zarr_format = 3 )
348+ metadata = zarr_array .metadata
349+ assert metadata .zarr_format == 3
350+ assert metadata .codecs == (
351+ BytesCodec (endian = "little" ),
352+ numcodecs .zarr3 .LZMA (
353+ format = lzma_settings ["format" ],
354+ check = lzma_settings ["check" ],
355+ preset = lzma_settings ["preset" ],
356+ filters = lzma_settings ["filters" ],
357+ ),
358+ )
359+ assert np .all (zarr_array [:] == 1 )
360+
361+
362+ @pytest .mark .filterwarnings (f"ignore:{ NUMCODECS_USER_WARNING } :UserWarning" )
337363def test_migrate_filter (local_store : LocalStore ) -> None :
338364 filter_v2 = numcodecs .Delta (dtype = "<u2" , astype = "<u2" )
339- filter_v3 = Delta (dtype = "<u2" , astype = "<u2" )
365+ filter_v3 = numcodecs . zarr3 . Delta (dtype = "<u2" , astype = "<u2" )
340366
341367 zarr .create_array (
342368 store = local_store ,
@@ -496,7 +522,9 @@ def test_migrate_incorrect_filter(local_store: LocalStore) -> None:
496522 fill_value = 0 ,
497523 )
498524
499- result = runner .invoke (cli .app , ["migrate" , "v3" , str (local_store .root )])
525+ with pytest .warns (UserWarning , match = NUMCODECS_USER_WARNING ):
526+ result = runner .invoke (cli .app , ["migrate" , "v3" , str (local_store .root )])
527+
500528 assert result .exit_code == 1
501529 assert isinstance (result .exception , TypeError )
502530 assert (
@@ -517,7 +545,9 @@ def test_migrate_incorrect_compressor(local_store: LocalStore) -> None:
517545 fill_value = 0 ,
518546 )
519547
520- result = runner .invoke (cli .app , ["migrate" , "v3" , str (local_store .root )])
548+ with pytest .warns (UserWarning , match = NUMCODECS_USER_WARNING ):
549+ result = runner .invoke (cli .app , ["migrate" , "v3" , str (local_store .root )])
550+
521551 assert result .exit_code == 1
522552 assert isinstance (result .exception , TypeError )
523553 assert (
0 commit comments