-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add inherit=False option to DataTree.copy() #9628
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
TypeVar, | ||
) | ||
|
||
from xarray.core.types import Self | ||
from xarray.core.utils import Frozen, is_dict_like | ||
|
||
if TYPE_CHECKING: | ||
|
@@ -238,10 +239,7 @@ def _post_attach_children(self: Tree, children: Mapping[str, Tree]) -> None: | |
"""Method call after attaching `children`.""" | ||
pass | ||
|
||
def copy( | ||
self: Tree, | ||
deep: bool = False, | ||
) -> Tree: | ||
def copy(self, *, inherit: bool = True, deep: bool = False) -> Self: | ||
""" | ||
Returns a copy of this subtree. | ||
|
||
|
@@ -254,7 +252,12 @@ def copy( | |
|
||
Parameters | ||
---------- | ||
deep : bool, default: False | ||
inherit : bool | ||
Whether inherited coordinates defined on parents of this node should | ||
also be copied onto the new tree. Only relevant if the `parent` of | ||
this node is not yet, and "Inherited coordinates" appear in its | ||
repr. | ||
deep : bool | ||
Whether each component variable is loaded into memory and copied onto | ||
the new object. Default is False. | ||
|
||
|
@@ -269,35 +272,27 @@ def copy( | |
xarray.Dataset.copy | ||
pandas.DataFrame.copy | ||
""" | ||
return self._copy_subtree(deep=deep) | ||
return self._copy_subtree(inherit=inherit, deep=deep) | ||
|
||
def _copy_subtree( | ||
self: Tree, | ||
deep: bool = False, | ||
memo: dict[int, Any] | None = None, | ||
) -> Tree: | ||
def _copy_subtree(self, inherit: bool, deep: bool = False) -> Self: | ||
"""Copy entire subtree recursively.""" | ||
|
||
new_tree = self._copy_node(deep=deep) | ||
new_tree = self._copy_node(inherit=inherit, deep=deep) | ||
for name, child in self.children.items(): | ||
# TODO use `.children[name] = ...` once #9477 is implemented | ||
new_tree._set(name, child._copy_subtree(deep=deep)) | ||
|
||
new_tree._set(name, child._copy_subtree(inherit=False, deep=deep)) | ||
return new_tree | ||
|
||
def _copy_node( | ||
self: Tree, | ||
deep: bool = False, | ||
) -> Tree: | ||
def _copy_node(self, inherit: bool, deep: bool = False) -> Self: | ||
"""Copy just one node of a tree""" | ||
new_empty_node = type(self)() | ||
return new_empty_node | ||
|
||
def __copy__(self: Tree) -> Tree: | ||
return self._copy_subtree(deep=False) | ||
def __copy__(self) -> Self: | ||
return self._copy_subtree(inherit=True, deep=False) | ||
|
||
def __deepcopy__(self: Tree, memo: dict[int, Any] | None = None) -> Tree: | ||
return self._copy_subtree(deep=True, memo=memo) | ||
def __deepcopy__(self, memo: dict[int, Any] | None = None) -> Self: | ||
del memo # nodes cannot be reused in a DataTree | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what this has to do with the memo. The memo is a kind of cache of deeply-copied objects that prevents recursion issues. Not sure if our DataTree model allows recursive subtrees... (I guess your comment is trying to say, that the answer is no?) |
||
return self._copy_subtree(inherit=True, deep=True) | ||
|
||
def _iter_parents(self: Tree) -> Iterator[Tree]: | ||
"""Iterate up the tree, starting from the current node's parent.""" | ||
|
@@ -693,17 +688,14 @@ def __str__(self) -> str: | |
name_repr = repr(self.name) if self.name is not None else "" | ||
return f"NamedNode({name_repr})" | ||
|
||
def _post_attach(self: AnyNamedNode, parent: AnyNamedNode, name: str) -> None: | ||
def _post_attach(self, parent: Self, name: str) -> None: | ||
"""Ensures child has name attribute corresponding to key under which it has been stored.""" | ||
_validate_name(name) # is this check redundant? | ||
self._name = name | ||
|
||
def _copy_node( | ||
self: AnyNamedNode, | ||
deep: bool = False, | ||
) -> AnyNamedNode: | ||
def _copy_node(self, inherit: bool, deep: bool = False) -> Self: | ||
"""Copy just one node of a tree""" | ||
new_node = super()._copy_node() | ||
new_node = super()._copy_node(inherit=inherit, deep=deep) | ||
new_node._name = self.name | ||
return new_node | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.