17
17
from collections .abc import Generator , Iterator , Mapping
18
18
from contextlib import ExitStack
19
19
from io import BytesIO
20
- from os import listdir
21
20
from pathlib import Path
22
21
from typing import TYPE_CHECKING , Any , Final , Literal , cast
23
22
from unittest .mock import patch
@@ -3698,34 +3697,54 @@ def roundtrip_dir(
3698
3697
3699
3698
@pytest .mark .parametrize ("consolidated" , [True , False , None ])
3700
3699
@pytest .mark .parametrize ("write_empty" , [True , False , None ])
3701
- @pytest .mark .skipif (
3702
- has_zarr_v3 , reason = "zarr-python 3.x removed write_empty_chunks"
3703
- )
3704
3700
def test_write_empty (
3705
- self , consolidated : bool | None , write_empty : bool | None
3701
+ self ,
3702
+ consolidated : bool | None ,
3703
+ write_empty : bool | None ,
3706
3704
) -> None :
3707
- if write_empty is False :
3708
- expected = ["0.1.0" , "1.1.0" ]
3705
+ def assert_expected_files (expected : list [str ], store : str ) -> None :
3706
+ """Convenience for comparing with actual files written"""
3707
+ ls = []
3708
+ test_root = os .path .join (store , "test" )
3709
+ for root , _ , files in os .walk (test_root ):
3710
+ ls .extend (
3711
+ [
3712
+ os .path .join (root , f ).removeprefix (test_root ).lstrip ("/" )
3713
+ for f in files
3714
+ ]
3715
+ )
3716
+
3717
+ assert set (expected ) == set (
3718
+ [
3719
+ file .lstrip ("c/" )
3720
+ for file in ls
3721
+ if (file not in (".zattrs" , ".zarray" , "zarr.json" ))
3722
+ ]
3723
+ )
3724
+
3725
+ # The zarr format is set by the `default_zarr_format`
3726
+ # pytest fixture that acts on a superclass
3727
+ zarr_format_3 = has_zarr_v3 and zarr .config .config ["default_zarr_format" ] == 3
3728
+ if (write_empty is False ) or (write_empty is None and has_zarr_v3 ):
3729
+ expected = ["0.1.0" ]
3709
3730
else :
3710
3731
expected = [
3711
3732
"0.0.0" ,
3712
3733
"0.0.1" ,
3713
3734
"0.1.0" ,
3714
3735
"0.1.1" ,
3715
- "1.0.0" ,
3716
- "1.0.1" ,
3717
- "1.1.0" ,
3718
- "1.1.1" ,
3719
3736
]
3720
3737
3721
- ds = xr .Dataset (
3722
- data_vars = {
3723
- "test" : (
3724
- ("Z" , "Y" , "X" ),
3725
- np .array ([np .nan , np .nan , 1.0 , np .nan ]).reshape ((1 , 2 , 2 )),
3726
- )
3727
- }
3728
- )
3738
+ if zarr_format_3 :
3739
+ data = np .array ([0.0 , 0 , 1.0 , 0 ]).reshape ((1 , 2 , 2 ))
3740
+ # transform to the path style of zarr 3
3741
+ # e.g. 0/0/1
3742
+ expected = [e .replace ("." , "/" ) for e in expected ]
3743
+ else :
3744
+ # use nan for default fill_value behaviour
3745
+ data = np .array ([np .nan , np .nan , 1.0 , np .nan ]).reshape ((1 , 2 , 2 ))
3746
+
3747
+ ds = xr .Dataset (data_vars = {"test" : (("Z" , "Y" , "X" ), data )})
3729
3748
3730
3749
if has_dask :
3731
3750
ds ["test" ] = ds ["test" ].chunk (1 )
@@ -3741,17 +3760,42 @@ def test_write_empty(
3741
3760
write_empty_chunks = write_empty ,
3742
3761
)
3743
3762
3763
+ # check expected files after a write
3764
+ assert_expected_files (expected , store )
3765
+
3744
3766
with self .roundtrip_dir (
3745
3767
ds ,
3746
3768
store ,
3747
- {"mode" : "a" , "append_dim" : "Z" , "write_empty_chunks" : write_empty },
3769
+ save_kwargs = {
3770
+ "mode" : "a" ,
3771
+ "append_dim" : "Z" ,
3772
+ "write_empty_chunks" : write_empty ,
3773
+ },
3748
3774
) as a_ds :
3749
3775
expected_ds = xr .concat ([ds , ds ], dim = "Z" )
3750
3776
3751
- assert_identical (a_ds , expected_ds )
3752
-
3753
- ls = listdir (os .path .join (store , "test" ))
3754
- assert set (expected ) == set ([file for file in ls if file [0 ] != "." ])
3777
+ assert_identical (a_ds , expected_ds .compute ())
3778
+ # add the new files we expect to be created by the append
3779
+ # that was performed by the roundtrip_dir
3780
+ if (write_empty is False ) or (write_empty is None and has_zarr_v3 ):
3781
+ expected .append ("1.1.0" )
3782
+ else :
3783
+ if not has_zarr_v3 :
3784
+ # TODO: remove zarr3 if once zarr issue is fixed
3785
+ # https://github.com/zarr-developers/zarr-python/issues/2931
3786
+ expected .extend (
3787
+ [
3788
+ "1.1.0" ,
3789
+ "1.0.0" ,
3790
+ "1.0.1" ,
3791
+ "1.1.1" ,
3792
+ ]
3793
+ )
3794
+ else :
3795
+ expected .append ("1.1.0" )
3796
+ if zarr_format_3 :
3797
+ expected = [e .replace ("." , "/" ) for e in expected ]
3798
+ assert_expected_files (expected , store )
3755
3799
3756
3800
def test_avoid_excess_metadata_calls (self ) -> None :
3757
3801
"""Test that chunk requests do not trigger redundant metadata requests.
0 commit comments