Skip to content

Commit 7c530f5

Browse files
committed
Removes parent keyword from DataTree constructor
But it doesn't fix all the tests There's three tests that I don't fully know what should be tested or if they still make sense.
1 parent 847f238 commit 7c530f5

File tree

2 files changed

+62
-43
lines changed

2 files changed

+62
-43
lines changed

xarray/core/datatree.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ class DataTree(
424424
def __init__(
425425
self,
426426
data: Dataset | DataArray | None = None,
427-
parent: DataTree | None = None,
428427
children: Mapping[str, DataTree] | None = None,
429428
name: str | None = None,
430429
):
@@ -440,8 +439,6 @@ def __init__(
440439
data : Dataset, DataArray, or None, optional
441440
Data to store under the .ds attribute of this node. DataArrays will
442441
be promoted to Datasets. Default is None.
443-
parent : DataTree, optional
444-
Parent node to this node. Default is None.
445442
children : Mapping[str, DataTree], optional
446443
Any child nodes of this node. Default is None.
447444
name : str, optional
@@ -462,7 +459,6 @@ def __init__(
462459
self._set_node_data(_coerce_to_dataset(data))
463460

464461
# shallow copy to avoid modifying arguments in-place (see GH issue #9196)
465-
self.parent = parent.copy() if parent is not None else None
466462
self.children = {name: child.copy() for name, child in children.items()}
467463

468464
def _set_node_data(self, ds: Dataset):
@@ -1100,7 +1096,7 @@ def from_dict(
11001096
obj = root_data.copy()
11011097
obj.orphan()
11021098
else:
1103-
obj = cls(name=name, data=root_data, parent=None, children=None)
1099+
obj = cls(name=name, data=root_data, children=None)
11041100

11051101
def depth(item) -> int:
11061102
pathstr, _ = item

xarray/tests/test_datatree.py

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ def test_setparent_unnamed_child_node_fails(self):
5555
def test_create_two_children(self):
5656
root_data = xr.Dataset({"a": ("y", [6, 7, 8]), "set0": ("x", [9, 10])})
5757
set1_data = xr.Dataset({"a": 0, "b": 1})
58-
58+
# root = DataTree.from_dict(
59+
# {"/": root_data, "/set1": set1_data, "/set1/set2": None}
60+
# )
5961
root: DataTree = DataTree(data=root_data)
6062
set1: DataTree = DataTree(name="set1", parent=root, data=set1_data)
6163
DataTree(name="set1", parent=root)
@@ -195,9 +197,13 @@ def test_to_dataset(self):
195197

196198
class TestVariablesChildrenNameCollisions:
197199
def test_parent_already_has_variable_with_childs_name(self):
198-
dt: DataTree = DataTree(data=xr.Dataset({"a": [0], "b": 1}))
199200
with pytest.raises(KeyError, match="already contains a variable named a"):
200-
DataTree(name="a", data=None, parent=dt)
201+
DataTree.from_dict({"/": xr.Dataset({"a": [0], "b": 1}), "/a": None})
202+
203+
def test_parent_already_has_variable_with_childs_name_update(self):
204+
dt: DataTree = DataTree(data=xr.Dataset({"a": [0], "b": 1}))
205+
with pytest.raises(ValueError, match="already contains a variable named a"):
206+
dt.update({"a": DataTree()})
201207

202208
def test_assign_when_already_child_with_variables_name(self):
203209
dt = DataTree.from_dict(
@@ -249,8 +255,7 @@ def test_getitem_single_data_variable_from_node(self):
249255
assert_identical(folder1["results/highres/temp"], data["temp"])
250256

251257
def test_getitem_nonexistent_node(self):
252-
folder1: DataTree = DataTree(name="folder1")
253-
DataTree(name="results", parent=folder1)
258+
folder1: DataTree = DataTree.from_dict({"/results": DataTree()}, name="folder1")
254259
with pytest.raises(KeyError):
255260
folder1["results/highres"]
256261

@@ -448,10 +453,10 @@ def test_setitem_new_empty_node(self):
448453
assert_identical(mary.to_dataset(), xr.Dataset())
449454

450455
def test_setitem_overwrite_data_in_node_with_none(self):
451-
john: DataTree = DataTree(name="john")
452-
mary: DataTree = DataTree(name="mary", parent=john, data=xr.Dataset())
456+
john: DataTree = DataTree.from_dict({"/mary": xr.Dataset()}, name="john")
457+
453458
john["mary"] = DataTree()
454-
assert_identical(mary.to_dataset(), xr.Dataset())
459+
assert_identical(john["mary"].to_dataset(), xr.Dataset())
455460

456461
john.ds = xr.Dataset() # type: ignore[assignment]
457462
with pytest.raises(ValueError, match="has no name"):
@@ -633,8 +638,13 @@ def test_view_contents(self):
633638

634639
def test_immutability(self):
635640
# See issue https://github.com/xarray-contrib/datatree/issues/38
636-
dt: DataTree = DataTree(name="root", data=None)
637-
DataTree(name="a", data=None, parent=dt)
641+
dt = DataTree.from_dict(
642+
{
643+
"/": None,
644+
"/a": None,
645+
},
646+
name="root",
647+
)
638648

639649
with pytest.raises(
640650
AttributeError, match="Mutation of the DatasetView is not allowed"
@@ -1087,44 +1097,51 @@ def test_filter(self):
10871097
class TestDSMethodInheritance:
10881098
def test_dataset_method(self):
10891099
ds = xr.Dataset({"a": ("x", [1, 2, 3])})
1090-
dt: DataTree = DataTree(data=ds)
1091-
DataTree(name="results", parent=dt, data=ds)
1100+
dt = DataTree.from_dict(
1101+
{
1102+
"/": ds,
1103+
"/results": ds,
1104+
}
1105+
)
10921106

1093-
expected: DataTree = DataTree(data=ds.isel(x=1))
1094-
DataTree(name="results", parent=expected, data=ds.isel(x=1))
1107+
expected = DataTree.from_dict(
1108+
{
1109+
"/": ds.isel(x=1),
1110+
"/results": ds.isel(x=1),
1111+
}
1112+
)
10951113

10961114
result = dt.isel(x=1)
10971115
assert_equal(result, expected)
10981116

10991117
def test_reduce_method(self):
11001118
ds = xr.Dataset({"a": ("x", [False, True, False])})
1101-
dt: DataTree = DataTree(data=ds)
1102-
DataTree(name="results", parent=dt, data=ds)
1119+
dt = DataTree.from_dict({"/": ds, "/results": ds})
11031120

1104-
expected: DataTree = DataTree(data=ds.any())
1105-
DataTree(name="results", parent=expected, data=ds.any())
1121+
expected = DataTree.from_dict({"/": ds.any(), "/results": ds.any()})
11061122

11071123
result = dt.any()
11081124
assert_equal(result, expected)
11091125

11101126
def test_nan_reduce_method(self):
11111127
ds = xr.Dataset({"a": ("x", [1, 2, 3])})
1112-
dt: DataTree = DataTree(data=ds)
1113-
DataTree(name="results", parent=dt, data=ds)
1128+
dt = DataTree.from_dict({"/": ds, "/results": ds})
11141129

1115-
expected: DataTree = DataTree(data=ds.mean())
1116-
DataTree(name="results", parent=expected, data=ds.mean())
1130+
expected = DataTree.from_dict({"/": ds.mean(), "/results": ds.mean()})
11171131

11181132
result = dt.mean()
11191133
assert_equal(result, expected)
11201134

11211135
def test_cum_method(self):
11221136
ds = xr.Dataset({"a": ("x", [1, 2, 3])})
1123-
dt: DataTree = DataTree(data=ds)
1124-
DataTree(name="results", parent=dt, data=ds)
1137+
dt = DataTree.from_dict({"/": ds, "/results": ds})
11251138

1126-
expected: DataTree = DataTree(data=ds.cumsum())
1127-
DataTree(name="results", parent=expected, data=ds.cumsum())
1139+
expected = DataTree.from_dict(
1140+
{
1141+
"/": ds.cumsum(),
1142+
"/results": ds.cumsum(),
1143+
}
1144+
)
11281145

11291146
result = dt.cumsum()
11301147
assert_equal(result, expected)
@@ -1134,11 +1151,9 @@ class TestOps:
11341151
def test_binary_op_on_int(self):
11351152
ds1 = xr.Dataset({"a": [5], "b": [3]})
11361153
ds2 = xr.Dataset({"x": [0.1, 0.2], "y": [10, 20]})
1137-
dt: DataTree = DataTree(data=ds1)
1138-
DataTree(name="subnode", data=ds2, parent=dt)
1154+
dt = DataTree.from_dict({"/": ds1, "/subnode": ds2})
11391155

1140-
expected: DataTree = DataTree(data=ds1 * 5)
1141-
DataTree(name="subnode", data=ds2 * 5, parent=expected)
1156+
expected = DataTree.from_dict({"/": ds1 * 5, "/subnode": ds2 * 5})
11421157

11431158
# TODO: Remove ignore when ops.py is migrated?
11441159
result: DataTree = dt * 5 # type: ignore[assignment,operator]
@@ -1147,24 +1162,32 @@ def test_binary_op_on_int(self):
11471162
def test_binary_op_on_dataset(self):
11481163
ds1 = xr.Dataset({"a": [5], "b": [3]})
11491164
ds2 = xr.Dataset({"x": [0.1, 0.2], "y": [10, 20]})
1150-
dt: DataTree = DataTree(data=ds1)
1151-
DataTree(name="subnode", data=ds2, parent=dt)
1165+
dt = DataTree.from_dict(
1166+
{
1167+
"/": ds1,
1168+
"/subnode": ds2,
1169+
}
1170+
)
1171+
11521172
other_ds = xr.Dataset({"z": ("z", [0.1, 0.2])})
11531173

1154-
expected: DataTree = DataTree(data=ds1 * other_ds)
1155-
DataTree(name="subnode", data=ds2 * other_ds, parent=expected)
1174+
expected = DataTree.from_dict(
1175+
{
1176+
"/": ds1 * other_ds,
1177+
"/subnode": ds2 * other_ds,
1178+
}
1179+
)
11561180

11571181
result = dt * other_ds
11581182
assert_equal(result, expected)
11591183

11601184
def test_binary_op_on_datatree(self):
11611185
ds1 = xr.Dataset({"a": [5], "b": [3]})
11621186
ds2 = xr.Dataset({"x": [0.1, 0.2], "y": [10, 20]})
1163-
dt: DataTree = DataTree(data=ds1)
1164-
DataTree(name="subnode", data=ds2, parent=dt)
11651187

1166-
expected: DataTree = DataTree(data=ds1 * ds1)
1167-
DataTree(name="subnode", data=ds2 * ds2, parent=expected)
1188+
dt = DataTree.from_dict({"/": ds1, "/subnode": ds2})
1189+
1190+
expected = DataTree.from_dict({"/": ds1 * ds1, "/subnode": ds2 * ds2})
11681191

11691192
# TODO: Remove ignore when ops.py is migrated?
11701193
result: DataTree = dt * dt # type: ignore[operator]

0 commit comments

Comments
 (0)