@@ -1104,10 +1104,12 @@ def from_dict(
1104
1104
d : dict-like
1105
1105
A mapping from path names to xarray.Dataset or DataTree objects.
1106
1106
1107
- Path names are to be given as unix-like path. If path names containing more than one
1108
- part are given, new tree nodes will be constructed as necessary.
1107
+ Path names are to be given as unix-like path. If path names
1108
+ containing more than one part are given, new tree nodes will be
1109
+ constructed as necessary.
1109
1110
1110
- To assign data to the root node of the tree use "/" as the path.
1111
+ To assign data to the root node of the tree use "", ".", "/" or "./"
1112
+ as the path.
1111
1113
name : Hashable | None, optional
1112
1114
Name for the root node of the tree. Default is None.
1113
1115
@@ -1119,17 +1121,27 @@ def from_dict(
1119
1121
-----
1120
1122
If your dictionary is nested you will need to flatten it before using this method.
1121
1123
"""
1122
-
1123
- # First create the root node
1124
+ # Find any values corresponding to the root
1124
1125
d_cast = dict (d )
1125
- root_data = d_cast .pop ("/" , None )
1126
+ root_data = None
1127
+ for key in ("" , "." , "/" , "./" ):
1128
+ if key in d_cast :
1129
+ if root_data is not None :
1130
+ raise ValueError (
1131
+ "multiple entries found corresponding to the root node"
1132
+ )
1133
+ root_data = d_cast .pop (key )
1134
+
1135
+ # Create the root node
1126
1136
if isinstance (root_data , DataTree ):
1127
1137
obj = root_data .copy ()
1138
+ obj .name = name
1128
1139
elif root_data is None or isinstance (root_data , Dataset ):
1129
1140
obj = cls (name = name , dataset = root_data , children = None )
1130
1141
else :
1131
1142
raise TypeError (
1132
- f'root node data (at "/") must be a Dataset or DataTree, got { type (root_data )} '
1143
+ f'root node data (at "", ".", "/" or "./") must be a Dataset '
1144
+ f"or DataTree, got { type (root_data )} "
1133
1145
)
1134
1146
1135
1147
def depth (item ) -> int :
@@ -1141,11 +1153,10 @@ def depth(item) -> int:
1141
1153
# Sort keys by depth so as to insert nodes from root first (see GH issue #9276)
1142
1154
for path , data in sorted (d_cast .items (), key = depth ):
1143
1155
# Create and set new node
1144
- node_name = NodePath (path ).name
1145
1156
if isinstance (data , DataTree ):
1146
1157
new_node = data .copy ()
1147
1158
elif isinstance (data , Dataset ) or data is None :
1148
- new_node = cls (name = node_name , dataset = data )
1159
+ new_node = cls (dataset = data )
1149
1160
else :
1150
1161
raise TypeError (f"invalid values: { data } " )
1151
1162
obj ._set_item (
@@ -1683,7 +1694,7 @@ def reduce(
1683
1694
numeric_only = numeric_only ,
1684
1695
** kwargs ,
1685
1696
)
1686
- path = "/" if node is self else node .relative_to (self )
1697
+ path = node .relative_to (self )
1687
1698
result [path ] = node_result
1688
1699
return type (self ).from_dict (result , name = self .name )
1689
1700
@@ -1718,7 +1729,7 @@ def _selective_indexing(
1718
1729
# with a scalar) can also create scalar coordinates, which
1719
1730
# need to be explicitly removed.
1720
1731
del node_result .coords [k ]
1721
- path = "/" if node is self else node .relative_to (self )
1732
+ path = node .relative_to (self )
1722
1733
result [path ] = node_result
1723
1734
return type (self ).from_dict (result , name = self .name )
1724
1735
0 commit comments