@@ -91,17 +91,13 @@ def _collect_data_and_coord_variables(
91
91
return data_variables , coord_variables
92
92
93
93
94
- def _coerce_to_dataset (data : Dataset | DataArray | None ) -> Dataset :
95
- if isinstance (data , DataArray ):
96
- ds = data .to_dataset ()
97
- elif isinstance (data , Dataset ):
94
+ def _to_new_dataset (data : Dataset | None ) -> Dataset :
95
+ if isinstance (data , Dataset ):
98
96
ds = data .copy (deep = False )
99
97
elif data is None :
100
98
ds = Dataset ()
101
99
else :
102
- raise TypeError (
103
- f"data object is not an xarray Dataset, DataArray, or None, it is of type { type (data )} "
104
- )
100
+ raise TypeError (f"data object is not an xarray.Dataset, dict, or None: { data } " )
105
101
return ds
106
102
107
103
@@ -422,7 +418,8 @@ class DataTree(
422
418
423
419
def __init__ (
424
420
self ,
425
- data : Dataset | DataArray | None = None ,
421
+ data : Dataset | None = None ,
422
+ parent : DataTree | None = None ,
426
423
children : Mapping [str , DataTree ] | None = None ,
427
424
name : str | None = None ,
428
425
):
@@ -435,9 +432,8 @@ def __init__(
435
432
436
433
Parameters
437
434
----------
438
- data : Dataset, DataArray, or None, optional
439
- Data to store under the .ds attribute of this node. DataArrays will
440
- be promoted to Datasets. Default is None.
435
+ data : Dataset, optional
436
+ Data to store under the .ds attribute of this node.
441
437
children : Mapping[str, DataTree], optional
442
438
Any child nodes of this node. Default is None.
443
439
name : str, optional
@@ -455,7 +451,7 @@ def __init__(
455
451
children = {}
456
452
457
453
super ().__init__ (name = name )
458
- self ._set_node_data (_coerce_to_dataset (data ))
454
+ self ._set_node_data (_to_new_dataset (data ))
459
455
460
456
# shallow copy to avoid modifying arguments in-place (see GH issue #9196)
461
457
self .children = {name : child .copy () for name , child in children .items ()}
@@ -540,8 +536,8 @@ def ds(self) -> DatasetView:
540
536
return self ._to_dataset_view (rebuild_dims = True )
541
537
542
538
@ds .setter
543
- def ds (self , data : Dataset | DataArray | None = None ) -> None :
544
- ds = _coerce_to_dataset (data )
539
+ def ds (self , data : Dataset | None = None ) -> None :
540
+ ds = _to_new_dataset (data )
545
541
self ._replace_node (ds )
546
542
547
543
def to_dataset (self , inherited : bool = True ) -> Dataset :
@@ -1050,7 +1046,7 @@ def drop_nodes(
1050
1046
@classmethod
1051
1047
def from_dict (
1052
1048
cls ,
1053
- d : Mapping [str , Dataset | DataArray | DataTree | None ],
1049
+ d : Mapping [str , Dataset | DataTree | None ],
1054
1050
name : str | None = None ,
1055
1051
) -> DataTree :
1056
1052
"""
@@ -1059,10 +1055,10 @@ def from_dict(
1059
1055
Parameters
1060
1056
----------
1061
1057
d : dict-like
1062
- A mapping from path names to xarray.Dataset, xarray.DataArray, or DataTree objects.
1058
+ A mapping from path names to xarray.Dataset or DataTree objects.
1063
1059
1064
- Path names are to be given as unix-like path. If path names containing more than one part are given, new
1065
- tree nodes will be constructed as necessary.
1060
+ Path names are to be given as unix-like path. If path names containing more than one
1061
+ part are given, new tree nodes will be constructed as necessary.
1066
1062
1067
1063
To assign data to the root node of the tree use "/" as the path.
1068
1064
name : Hashable | None, optional
@@ -1083,8 +1079,12 @@ def from_dict(
1083
1079
if isinstance (root_data , DataTree ):
1084
1080
obj = root_data .copy ()
1085
1081
obj .orphan ()
1086
- else :
1082
+ elif root_data is None or isinstance ( root_data , Dataset ) :
1087
1083
obj = cls (name = name , data = root_data , children = None )
1084
+ else :
1085
+ raise TypeError (
1086
+ f'root node data (at "/") must be a Dataset or DataTree, got { type (root_data )} '
1087
+ )
1088
1088
1089
1089
def depth (item ) -> int :
1090
1090
pathstr , _ = item
0 commit comments