@@ -666,10 +666,21 @@ def open_store(
666
666
use_zarr_fill_value_as_mask = use_zarr_fill_value_as_mask ,
667
667
zarr_format = zarr_format ,
668
668
)
669
+
670
+ from zarr import Group
671
+
672
+ group_members : dict [str , Group ] = {}
669
673
group_paths = list (_iter_zarr_groups (zarr_group , parent = group ))
670
- return {
674
+ for path in group_paths :
675
+ if path == group :
676
+ group_members [path ] = zarr_group
677
+ else :
678
+ rel_path = path .removeprefix (f"{ group } /" )
679
+ group_members [path ] = zarr_group [rel_path .removeprefix ("/" )]
680
+
681
+ out = {
671
682
group : cls (
672
- zarr_group . get ( group ) ,
683
+ group_store ,
673
684
mode ,
674
685
consolidate_on_close ,
675
686
append_dim ,
@@ -680,8 +691,9 @@ def open_store(
680
691
use_zarr_fill_value_as_mask ,
681
692
cache_members = cache_members ,
682
693
)
683
- for group in group_paths
694
+ for group , group_store in group_members . items ()
684
695
}
696
+ return out
685
697
686
698
@classmethod
687
699
def open_group (
@@ -1034,8 +1046,6 @@ def store(
1034
1046
if self ._consolidate_on_close :
1035
1047
kwargs = {}
1036
1048
if _zarr_v3 ():
1037
- # https://github.com/zarr-developers/zarr-python/pull/2113#issuecomment-2386718323
1038
- kwargs ["path" ] = self .zarr_group .name .lstrip ("/" )
1039
1049
kwargs ["zarr_format" ] = self .zarr_group .metadata .zarr_format
1040
1050
zarr .consolidate_metadata (self .zarr_group .store , ** kwargs )
1041
1051
@@ -1662,8 +1672,6 @@ def open_groups_as_dict(
1662
1672
zarr_version = None ,
1663
1673
zarr_format = None ,
1664
1674
) -> dict [str , Dataset ]:
1665
- from xarray .core .treenode import NodePath
1666
-
1667
1675
filename_or_obj = _normalize_path (filename_or_obj )
1668
1676
1669
1677
# Check for a group and make it a parent if it exists
@@ -1686,7 +1694,6 @@ def open_groups_as_dict(
1686
1694
)
1687
1695
1688
1696
groups_dict = {}
1689
-
1690
1697
for path_group , store in stores .items ():
1691
1698
store_entrypoint = StoreBackendEntrypoint ()
1692
1699
@@ -1762,44 +1769,57 @@ def _get_open_params(
1762
1769
consolidated = False
1763
1770
1764
1771
if _zarr_v3 ():
1765
- missing_exc = ValueError
1772
+ # TODO: replace AssertionError after https://github.com/zarr-developers/zarr-python/issues/2821 is resolved
1773
+ missing_exc = AssertionError
1766
1774
else :
1767
1775
missing_exc = zarr .errors .GroupNotFoundError
1768
1776
1769
- if consolidated is None :
1770
- try :
1771
- zarr_group = zarr .open_consolidated (store , ** open_kwargs )
1772
- except (ValueError , KeyError ):
1773
- # ValueError in zarr-python 3.x, KeyError in 2.x.
1777
+ if consolidated in [None , True ]:
1778
+ # open the root of the store, in case there is metadata consolidated there
1779
+ group = open_kwargs .pop ("path" )
1780
+
1781
+ if consolidated :
1782
+ # TODO: an option to pass the metadata_key keyword
1783
+ zarr_root_group = zarr .open_consolidated (store , ** open_kwargs )
1784
+ elif consolidated is None :
1785
+ # same but with more error handling in case no consolidated metadata found
1774
1786
try :
1775
- zarr_group = zarr .open_group (store , ** open_kwargs )
1776
- emit_user_level_warning (
1777
- "Failed to open Zarr store with consolidated metadata, "
1778
- "but successfully read with non-consolidated metadata. "
1779
- "This is typically much slower for opening a dataset. "
1780
- "To silence this warning, consider:\n "
1781
- "1. Consolidating metadata in this existing store with "
1782
- "zarr.consolidate_metadata().\n "
1783
- "2. Explicitly setting consolidated=False, to avoid trying "
1784
- "to read consolidate metadata, or\n "
1785
- "3. Explicitly setting consolidated=True, to raise an "
1786
- "error in this case instead of falling back to try "
1787
- "reading non-consolidated metadata." ,
1788
- RuntimeWarning ,
1789
- )
1790
- except missing_exc as err :
1791
- raise FileNotFoundError (
1792
- f"No such file or directory: '{ store } '"
1793
- ) from err
1794
- elif consolidated :
1795
- # TODO: an option to pass the metadata_key keyword
1796
- zarr_group = zarr .open_consolidated (store , ** open_kwargs )
1787
+ zarr_root_group = zarr .open_consolidated (store , ** open_kwargs )
1788
+ except (ValueError , KeyError ):
1789
+ # ValueError in zarr-python 3.x, KeyError in 2.x.
1790
+ try :
1791
+ zarr_root_group = zarr .open_group (store , ** open_kwargs )
1792
+ emit_user_level_warning (
1793
+ "Failed to open Zarr store with consolidated metadata, "
1794
+ "but successfully read with non-consolidated metadata. "
1795
+ "This is typically much slower for opening a dataset. "
1796
+ "To silence this warning, consider:\n "
1797
+ "1. Consolidating metadata in this existing store with "
1798
+ "zarr.consolidate_metadata().\n "
1799
+ "2. Explicitly setting consolidated=False, to avoid trying "
1800
+ "to read consolidate metadata, or\n "
1801
+ "3. Explicitly setting consolidated=True, to raise an "
1802
+ "error in this case instead of falling back to try "
1803
+ "reading non-consolidated metadata." ,
1804
+ RuntimeWarning ,
1805
+ )
1806
+ except missing_exc as err :
1807
+ raise FileNotFoundError (
1808
+ f"No such file or directory: '{ store } '"
1809
+ ) from err
1810
+
1811
+ # but the user should still receive a DataTree whose root is the group they asked for
1812
+ if group and group != "/" :
1813
+ zarr_group = zarr_root_group [group .removeprefix ("/" )]
1814
+ else :
1815
+ zarr_group = zarr_root_group
1797
1816
else :
1798
1817
if _zarr_v3 ():
1799
1818
# we have determined that we don't want to use consolidated metadata
1800
1819
# so we set that to False to avoid trying to read it
1801
1820
open_kwargs ["use_consolidated" ] = False
1802
1821
zarr_group = zarr .open_group (store , ** open_kwargs )
1822
+
1803
1823
close_store_on_close = zarr_group .store is not store
1804
1824
1805
1825
# we use this to determine how to handle fill_value
0 commit comments