From 9ce89fc842d2280e63ab4048b3cac424a115033d Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 9 Nov 2022 16:43:51 +0100 Subject: [PATCH 1/4] allow passing `DataTree` objects as `dict` values --- datatree/datatree.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/datatree/datatree.py b/datatree/datatree.py index ff7a417b..8882bcc3 100644 --- a/datatree/datatree.py +++ b/datatree/datatree.py @@ -754,7 +754,7 @@ def update(self, other: Dataset | Mapping[str, DataTree | DataArray]) -> None: @classmethod def from_dict( cls, - d: MutableMapping[str, Dataset | DataArray | None], + d: MutableMapping[str, Dataset | DataArray | DataTree | None], name: str = None, ) -> DataTree: """ @@ -790,7 +790,11 @@ def from_dict( for path, data in d.items(): # Create and set new node node_name = NodePath(path).name - new_node = cls(name=node_name, data=data) + if isinstance(data, cls): + new_node = data.copy() + new_node.orphan() + else: + new_node = cls(name=node_name, data=data) obj._set_item( path, new_node, From 748f379a1f257dc78b44017de2bbbd0cfc8a1b30 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 9 Nov 2022 16:52:16 +0100 Subject: [PATCH 2/4] add a test verifying that DataTree objects are actually allowed --- datatree/tests/test_datatree.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/datatree/tests/test_datatree.py b/datatree/tests/test_datatree.py index dd08618d..f5d7b928 100644 --- a/datatree/tests/test_datatree.py +++ b/datatree/tests/test_datatree.py @@ -391,6 +391,15 @@ def test_full(self, simple_datatree): "/set3", ] + def test_datatree_values(self): + dat1 = DataTree(data=xr.Dataset({"a": 1})) + expected = DataTree() + expected["a"] = dat1 + + actual = DataTree.from_dict({"a": dat1}) + + dtt.assert_identical(actual, expected) + def test_roundtrip(self, simple_datatree): dt = simple_datatree roundtrip = DataTree.from_dict(dt.to_dict()) From 2d501b93c91185a62efcc55d08bd4a404d666467 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 7 Dec 2022 14:20:33 -0500 Subject: [PATCH 3/4] ignore mypy error with copied copy method --- datatree/datatree.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datatree/datatree.py b/datatree/datatree.py index b042d41b..5d588da1 100644 --- a/datatree/datatree.py +++ b/datatree/datatree.py @@ -791,7 +791,8 @@ def from_dict( # Create and set new node node_name = NodePath(path).name if isinstance(data, cls): - new_node = data.copy() + # TODO ignoring type error only needed whilst .copy() method is copied from Dataset.copy(). + new_node = data.copy() # type: ignore[attr-defined] new_node.orphan() else: new_node = cls(name=node_name, data=data) From b90d1086534b7b8c298840ad69006c16075da35a Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 7 Dec 2022 14:24:09 -0500 Subject: [PATCH 4/4] whatsnew --- docs/source/whats-new.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/whats-new.rst b/docs/source/whats-new.rst index 8d9d6573..cfe73a50 100644 --- a/docs/source/whats-new.rst +++ b/docs/source/whats-new.rst @@ -37,6 +37,9 @@ Deprecations Bug fixes ~~~~~~~~~ +- Allow ``Datatree`` objects as values in :py:meth:`DataTree.from_dict` (:pull:`159`). + By `Justus Magin `_. + Documentation ~~~~~~~~~~~~~