Skip to content

Commit 35cb5d6

Browse files
authored
Merge pull request #335 from kayjan/v0.23.0
v0.23.0
2 parents cfc1f6f + 6f9bda2 commit 35cb5d6

File tree

6 files changed

+36
-30
lines changed

6 files changed

+36
-30
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
9+
## [0.23.0] - 2024-12-26
810
### Changed:
911
- Tree Modify: Update documentation and docstring with some rephrasing.
1012
- Tree Modify: Clean up test cases.
1113
### Added:
1214
- Tree Modify: Add parameter `merge_attribute` to allow from-node and to-node attributes to be merged if there are clashes.
1315
### Fixed:
14-
- Tree Modify: Fixed bug when `merge_children` is used with `overriding` as the `merge_children` value is changed in for-loop (bad move, literally).
16+
- Tree Modify: Fixed bug when `merge_children` is used with `overriding` as the `merge_children` value is changed in
17+
for-loop (bad move, literally). Modified the logic such that if there are clashes for `merge_children=True, overriding=True`,
18+
the origin node parent and destination node children are preserved. The origin node's children are overridden.
19+
**This might not be backwards-compatible!**
1520

1621
## [0.22.3] - 2024-11-14
1722
### Added:

bigtree/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.22.3"
1+
__version__ = "0.23.0"
22

33
from bigtree.binarytree.construct import list_to_binarytree
44
from bigtree.dag.construct import dataframe_to_dag, dict_to_dag, list_to_dag

bigtree/tree/modify.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,10 +1216,6 @@ def copy_or_shift_logic(
12161216

12171217
# Perform shifting/copying
12181218
for from_path, to_path in zip(from_paths, to_paths):
1219-
# Reset parameters
1220-
merge_children2 = merge_children
1221-
merge_leaves2 = merge_leaves
1222-
12231219
if with_full_path:
12241220
from_node = search.find_full_path(tree, from_path)
12251221
else:
@@ -1264,10 +1260,7 @@ def copy_or_shift_logic(
12641260
logging.info(
12651261
f"Path {to_path} already exists and its children be overridden by the merge"
12661262
)
1267-
parent = to_node.parent
1268-
to_node.parent = None
1269-
to_node = parent
1270-
merge_children2 = False
1263+
del to_node.children
12711264
elif merge_attribute:
12721265
logging.info(
12731266
f"Path {to_path} already exists and their attributes will be merged"
@@ -1279,10 +1272,10 @@ def copy_or_shift_logic(
12791272
merge_children=merge_children,
12801273
merge_leaves=merge_leaves,
12811274
)
1282-
parent = to_node.parent
1283-
to_node.parent = None
1284-
to_node = parent
1285-
merge_children2 = False
1275+
to_node.set_attrs(
1276+
dict(from_node.describe(exclude_prefix="_"))
1277+
)
1278+
del to_node.children
12861279
else:
12871280
logging.info(
12881281
f"Path {to_path} already exists and children are merged"
@@ -1304,10 +1297,10 @@ def copy_or_shift_logic(
13041297
merge_children=merge_children,
13051298
merge_leaves=merge_leaves,
13061299
)
1307-
parent = to_node.parent
1308-
to_node.parent = None
1309-
to_node = parent
1310-
merge_leaves2 = False
1300+
to_node.set_attrs(
1301+
dict(from_node.describe(exclude_prefix="_"))
1302+
)
1303+
del to_node.children
13111304
else:
13121305
logging.info(
13131306
f"Path {to_path} already exists and leaves are merged"
@@ -1353,7 +1346,7 @@ def copy_or_shift_logic(
13531346
if copy:
13541347
logging.debug(f"Copying {from_node.node_name}")
13551348
from_node = from_node.copy()
1356-
if merge_children2:
1349+
if merge_children:
13571350
# overriding / merge_attribute handled merge_children, set merge_children=False
13581351
logging.debug(
13591352
f"Reassigning children from {from_node.node_name} to {to_node.node_name}"
@@ -1363,7 +1356,7 @@ def copy_or_shift_logic(
13631356
del children.children
13641357
children.parent = to_node
13651358
from_node.parent = None
1366-
elif merge_leaves2:
1359+
elif merge_leaves:
13671360
logging.debug(
13681361
f"Reassigning leaf nodes from {from_node.node_name} to {to_node.node_name}"
13691362
)

docs/bigtree/tree/modify.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,33 +94,37 @@ If you're still feeling lost over the parameters, here are some guiding question
9494
- Do I want to retain the original node where they are?
9595
- Yes: Set `copy=True`
9696
- Default performs a shift instead of copy
97-
- Am I unsure of what nodes I am going to shift, they may or may not exist and this is perfectly fine?
97+
- Am I unsure of what nodes I am going to copy/shift, they may or may not exist and this is perfectly fine?
9898
- Yes: Set `skippable=True`
9999
- Default throws error if origin node is not found
100100
- The origin node (and its descendants) may clash with the destination node(s), how do I want to handle it?
101101
- Set `overriding=True` to overwrite origin node
102102
- Set `merge_attribute=True` to combine both nodes' attributes
103103
- Default throws error about the clash in node name
104-
- I want to shift everything under the node, but not the node itself
104+
- I want to copy/shift everything under the node, but not the node itself
105105
- Set `merge_children=True` or `merge_leaves=True` to shift the children and leaf nodes respectively
106106
- Default shifts the node itself, and everything under it
107-
- I want to shift the node and only the node, and not everything under it
107+
- I want to copy/shift the node and only the node, and not everything under it
108108
- Yes: Set `delete_children=True`
109109
- Default shifts the node itself, and everything under it
110-
- I want to shift things from one tree to another tree
110+
- I want to copy/shift things from one tree to another tree
111111
- Specify `to_tree`
112112
- Default shifts nodes within the same tree
113113

114114
What about the permutations between the parameters?
115115

116-
- These parameters are standalone and does not produce any interaction effect
116+
- These parameters are standalone and do not produce any interaction effect
117117
- `copy`, `skippable`, `delete_children`
118118
- These parameters have some interaction:
119119
- `overriding` and `merge_attribute` with `merge_children` and `merge_leaves`
120-
- `overriding` + `merge_children`: Behaves like `merge_children` when there is no clash in node name, otherwise behaves like `overriding`. Note that clashes will preserve destination nodes' children only.
121-
- `overriding` + `merge_leaves`: Behaves like `merge_leaves` when there is no clash in node name, otherwise behaves like `overriding`. Note that clashes will preserve destination nodes' leaves only.
122-
- `merge_attribute` + `merge_children`: Behaves like `merge_children` when there is no clash in node name, otherwise behaves like `merge_attribute`. Note that attributes will be merged for node and all descendants, and will preserve origin and destination nodes' children.
123-
- `merge_attribute` + `merge_leaves`: Behaves like `merge_leaves` when there is no clash in node name, otherwise behaves like `merge_attribute`. Note that attributes will be merged for node and all descendants, and will preserve origin nodes' children and destination nodes' leaves.
120+
- `overriding` + `merge_children`: Behaves like `merge_children` when there is no clash in node name, otherwise behaves like `overriding`.
121+
Note that clashes will preserve origin node parent and destination nodes' children.
122+
- `overriding` + `merge_leaves`: Behaves like `merge_leaves` when there is no clash in node name, otherwise behaves like `overriding`.
123+
Note that clashes will preserve origin node parent and destination nodes' leaves.
124+
- `merge_attribute` + `merge_children`: Behaves like `merge_children` when there is no clash in node name, otherwise behaves like `merge_attribute`.
125+
Note that attributes will be merged for node and all descendants, and will preserve origin and destination nodes' children.
126+
- `merge_attribute` + `merge_leaves`: Behaves like `merge_leaves` when there is no clash in node name, otherwise behaves like `merge_attribute`.
127+
Note that attributes will be merged for node and all descendants, and will preserve origin nodes' children and destination nodes' leaves.
124128

125129
-----
126130

docs/gettingstarted/demo/tree.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,9 @@ Nodes can be <mark>shifted</mark> (with or without replacement) or <mark>copied<
617617
from one path to another, this changes the tree in-place.
618618
Nodes can also be copied (with or without replacement) <mark>between two different trees</mark>.
619619

620+
There are various other configurations for performing copying/shifting, refer to [code documentation](../../bigtree/tree/modify.md)
621+
for more examples.
622+
620623
=== "Shift nodes"
621624
```python hl_lines="12-16 24-28"
622625
from bigtree import list_to_tree, shift_nodes, shift_and_replace_nodes

tests/tree/test_modify.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2377,7 +2377,7 @@ def test_copy_nodes_from_tree_to_tree_merge_children_overriding(self):
23772377
overriding=True,
23782378
)
23792379
assert_tree_structure_basenode_root(self.root_other_full_wrong)
2380-
assert_tree_structure_basenode_root_attr(self.root_other_full_wrong)
2380+
assert_tree_structure_basenode_root_attr(self.root_other_full_wrong, c=("c", 1))
23812381
assert_tree_structure_node_root(self.root_other_full_wrong)
23822382

23832383
# merge_children, merge_attribute
@@ -2454,6 +2454,7 @@ def test_copy_nodes_from_tree_to_tree_merge_leaves_merge_attribute(self):
24542454
merge_leaves=True,
24552455
merge_attribute=True,
24562456
)
2457+
self.root_other_full_wrong["b"].sort(key=lambda node: node.node_name)
24572458
assert_tree_structure_basenode_root(self.root_other_full_wrong)
24582459
assert_tree_structure_basenode_root_attr(self.root_other_full_wrong)
24592460
assert_tree_structure_node_root(self.root_other_full_wrong)

0 commit comments

Comments
 (0)