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

pypi-AgEIcHlwaS5vcmcCJDRlYmRmOTA3LTk0NmQtNGNkNS05NTVlLTJjYjhmMzBmODdmYwACKlszLCI1YThjM2VlNi0yNTE3LTRhMjktYmFmZS03MGVlYzdjYmUzODQiXQAABiDECjlqB8MRizOvcmEUQBEhVNljktnp5-ZY6WIAyVgR_Q

CHANGELOG
Added, Changed, Fixed, Removed

STEPS
Check function name and order
Check docstrings
Check type hint
Check test cases
Write documentation

LEARNINGS
type hinting (same type?) Self (python 3.11), Type[A] vs A
pre commit hook
toml file, coverage, flake8, isort
hatch vs poetry
inherit and override private methods
doctest, importing clashes when running file with -m
yield and yield from
logging for libraries
pytest for print and stdout and dataframes
add image to md files

---------------------------------------------------------
Tests

import doctest
doctest.testmod()

Tree should have structure
a (age=90)
|-- b (age=65)
|   |-- d (age=40)
|   +-- e (age=35)
|       |-- g (age=10)
|       +-- h (age=6)
+-- c (age=60)
    +-- f (age=38)

root = Node("a", age=90)
b = Node("b", age=65, parent=root)
c = Node("c", age=60, parent=root)
d = Node("d", age=40, parent=b)
e = Node("e", age=35, parent=b)

from bigtree.node.node import Node
def tree_node():
    """
    Tree should have structure
    a
    |-- b
    |   |-- d
    |   +-- e
    |       |-- g
    |       +-- h
    +-- c
        +-- f
    """
    a = Node("a", age=90)
    b = Node("b", age=65)
    c = Node("c", age=60)
    d = Node("d", age=40)
    e = Node("e", age=35)
    f = Node("f", age=38)
    g = Node("g", age=10)
    h = Node("h", age=6)

    b.parent = a
    c.parent = a
    d.parent = b
    e.parent = b
    f.parent = c
    g.parent = e
    h.parent = e
    return a

def tree_node_style():
    """
    Tree should have structure
    a (age=90)
    |-- b (age=65)
    |   |-- d (age=40)
    |       |-- g (age=10)
    |   +-- e (age=35)
    |       +-- h (age=6)
    +-- c (age=60)
        +-- f (age=38)
    """
    a = Node("a", node_style={"style": "filled", "fillcolor": "gold"})
    b = Node("b", node_style={"style": "filled", "fillcolor": "blue"})
    c = Node("c", node_style={"style": "filled", "fillcolor": "blue"})
    d = Node("d", node_style={"style": "filled", "fillcolor": "green"})
    e = Node("e", node_style={"style": "filled", "fillcolor": "green"})
    f = Node("f", node_style={"style": "filled", "fillcolor": "green"})
    g = Node("g", node_style={"style": "filled", "fillcolor": "red"})
    h = Node("h", node_style={"style": "filled", "fillcolor": "red"})

    b.parent = a
    c.parent = a
    d.parent = b
    e.parent = b
    f.parent = c
    g.parent = d
    h.parent = e
    return a

tree_node = tree_node()
tree_node_style = tree_node_style()

from bigtree import DAGNode, dag_to_dot, dag_iterator, tree_to_dot
def dag_node():
    a = DAGNode("a")
    b = DAGNode("b")
    c = DAGNode("c")
    d = DAGNode("d")
    e = DAGNode("e")
    f = DAGNode("f")
    g = DAGNode("g")
    h = DAGNode("h")

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return a

def dag_node_child():
    a = DAGNode("a")
    b = DAGNode("b")
    c = DAGNode("c")
    d = DAGNode("d")
    e = DAGNode("e")
    f = DAGNode("f")
    g = DAGNode("g")
    h = DAGNode("h")

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return f


def dag_node_style():
    a = DAGNode("a", node_style={"style": "filled", "fillcolor": "gold"})
    b = DAGNode("b", node_style={"style": "filled", "fillcolor": "blue"})
    c = DAGNode("c", node_style={"style": "filled", "fillcolor": "blue"})
    d = DAGNode("d", node_style={"style": "filled", "fillcolor": "green"})
    e = DAGNode("e", node_style={"style": "filled", "fillcolor": "green"})
    f = DAGNode("f", node_style={"style": "filled", "fillcolor": "green"})
    g = DAGNode("g", node_style={"style": "filled", "fillcolor": "red"})
    h = DAGNode("h", node_style={"style": "filled", "fillcolor": "red"})

    c.parents = [a, b]
    d.parents = [a, c]
    e.parents = [d]
    f.parents = [c, d]
    g.parents = [c]
    h.parents = [g]
    return a

dag_node = dag_node()
dag_node_child = dag_node_child()
dag_node_style = dag_node_style()

a = DAGNode("a", step=1)
b = DAGNode("b", step=1)
c = DAGNode("c", step=2, parents=[a, b])
d = DAGNode("d", step=2, parents=[a, c])
e = DAGNode("e", step=3, parents=[d])
list(dag_iterator(a))

tree = a
bgcolor = None
fillcolor = None
node_attr = None
dag_graph = dag_to_dot(a)
node = tree
node_from = None
direction = 1

assert_tree_structure_basenode_root_generic (tree structure)
assert_tree_structure_basenode_root_attr (tree structure with age attr)
assert_tree_structure_basenode_self (tree structure with age attr)

assert_tree_structure_node_root_generic (path)
assert_tree_structure_node_self (path)
assert_tree_structure_node_self_sep (sep \\)
assert_tree_structure_node_root_sep (sep \\)

*******************************
TestBaseNode
test_from_dict
test_set_parent_error
test_set_parent
test_set_parents_rshift
test_set_parent_lshift
test_set_parent_constructor
test_set_parent_null_parent
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_children
test_set_children_constructor
test_set_children_null_children
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_deep_copy_set_children
test_shallow_copy_set_children
test_error_set_parent_type_error
test_error_set_parent_loop_error
test_error_set_children_type_error
test_error_set_children_loop_error
test_error_set_children_exception

*******************************
TestDAGNode
test_from_dict
test_set_parent_error
test_set_parents
test_set_parents_rshift
test_set_parents_lshift
test_set_parents_constructor
test_set_parents_none_parent
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_children
test_set_children_constructor
test_set_children_none_children
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_deep_copy_set_children
test_shallow_copy_set_children
test_set_children_constructor //
test_error_set_parent_type_error
test_error_set_parent_loop_error
test_error_set_parent_exception
test_error_set_children_type_error
test_error_set_children_loop_error
test_error_set_children_exception

*******************************
TestNode
test_set_parent
test_set_parent_constructor
test_set_parent_duplicate
test_set_parent_duplicate_constructor //
test_set_parent_sep_root
test_set_parent_sep_child //
test_set_children
test_set_children_constructor
test_set_children_duplicate
test_set_children_duplicate_constructor //
test_error_set_parent_same_path
test_error_set_parent_constructor_same_path
test_error_set_children_same_path
test_error_set_children_constructor_same_path
test_error_set_children_multiple_same_path //
test_error_set_parent
test_error_set_children

*******************************
TestConstruct
test_add_path_to_tree
test_add_path_to_tree_leaves
test_add_path_to_tree_empty
test_add_path_to_tree_sep_leading
test_add_path_to_tree_sep_trailing
test_add_path_to_tree_sep_undefined
test_add_path_to_tree_sep
test_add_path_to_tree_sep_tree
test_add_path_to_tree_duplicate_node
test_add_path_to_tree_node_type
test_add_path_to_tree_different_root //

test_add_dict_to_tree_by_path
test_add_dict_to_tree_by_path_empty
test_add_dict_to_tree_by_path_sep_leading
test_add_dict_to_tree_by_path_sep_trailing
test_add_dict_to_tree_by_path_sep_undefined
test_add_dict_to_tree_by_path_sep
test_add_dict_to_tree_by_path_sep_tree
test_add_dict_to_tree_by_path_duplicate_node
test_add_dict_to_tree_by_path_node_type
test_add_dict_to_tree_by_path_different_root //

test_add_dict_to_tree_by_name
test_add_dict_to_tree_by_name_empty
test_add_dict_to_tree_by_name_duplicate_in_tree
test_add_dict_to_tree_by_name_inner_join_tree
test_add_dict_to_tree_by_name_inner_join_dict
test_add_dict_to_tree_by_name_left_join
test_add_dict_to_tree_by_name_invalid_join
test_add_dict_to_tree_by_name_sep_tree
test_add_dict_to_tree_by_name_node_type //

test_add_dataframe_to_tree_by_path
test_add_dataframe_to_tree_by_path_col_name
test_add_dataframe_to_tree_by_path_empty_row
test_add_dataframe_to_tree_by_path_empty_col
test_add_dataframe_to_tree_by_path_no_attribute
test_add_dataframe_to_tree_by_path_sep_leading
test_add_dataframe_to_tree_by_path_sep_trailing
test_add_dataframe_to_tree_by_path_sep_undefined
test_add_dataframe_to_tree_by_path_sep
test_add_dataframe_to_tree_by_path_sep_tree
test_add_dataframe_to_tree_by_path_node_type
test_add_dataframe_to_tree_by_path_different_root
test_add_dataframe_to_tree_by_path_duplicate
test_add_dataframe_to_tree_by_path_duplicate_node //

test_add_dataframe_to_tree_by_name
test_add_dataframe_to_tree_by_name_duplicate_in_tree
test_add_dataframe_to_tree_by_name_col_name
test_add_dataframe_to_tree_by_name_empty
test_add_dataframe_to_tree_by_name_empty_row
test_add_dataframe_to_tree_by_name_inner_join_tree
test_add_dataframe_to_tree_by_name_inner_join_data
test_add_dataframe_to_tree_by_name_left_join
test_add_dataframe_to_tree_by_name_invalid_join
test_add_dataframe_to_tree_by_name_sep_tree
test_add_dataframe_to_tree_by_name_node_type
test_add_dataframe_to_tree_by_name_duplicate
test_add_dataframe_to_tree_by_name_duplicate_node //

test_list_to_tree
test_list_to_tree_leaves
test_list_to_tree_empty
test_list_to_tree_sep_leading
test_list_to_tree_sep_trailing
test_list_to_tree_sep_undefined
test_list_to_tree_sep
test_list_to_tree_duplicate_node
test_list_to_tree_node_type
test_list_to_tree_different_root //

test_dict_to_tree
test_dict_to_tree_empty
test_dict_to_tree_sep_leading
test_dict_to_tree_sep_trailing
test_dict_to_tree_sep_undefined
test_dict_to_tree_sep
test_dict_to_tree_duplicate_node
test_dict_to_tree_node_type
test_dict_to_tree_different_root //

test_nested_dict_to_tree
test_nested_dict_to_tree_key_name
test_nested_dict_to_tree_node_type //

test_dataframe_to_tree
test_dataframe_to_tree_col_name
test_dataframe_to_tree_no_attribute
test_dataframe_to_tree_empty_row
test_dataframe_to_tree_empty_col
test_dataframe_to_tree_sep_leading
test_dataframe_to_tree_sep_trailing
test_dataframe_to_tree_sep_undefined
test_dataframe_to_tree_sep
test_dataframe_to_tree_node_type
test_dataframe_to_tree_different_root
test_dataframe_to_tree_duplicate
test_dataframe_to_tree_duplicate_node

*******************************
TestPrintTree
test_print_tree_ansi
test_print_tree_ascii
test_print_tree_const
test_print_tree_const_bold
test_print_tree_rounded
test_print_tree_double
test_print_tree_custom
test_print_tree_unknown_style
test_print_tree_unequal_char
test_print_tree_attr

TestTreeToDataFrame
test_tree_to_dataframe
test_tree_to_dataframe_path_col
test_tree_to_dataframe_path_col_missing
test_tree_to_dataframe_name_col
test_tree_to_dataframe_name_col_missing
test_tree_to_dataframe_name_path_col_missing
test_tree_to_dataframe_parent_col
test_tree_to_dataframe_attr_dict
test_tree_to_dataframe_all_attr
test_tree_to_dataframe_max_depth
test_tree_to_dataframe_skip_depth
test_tree_to_dataframe_leaf_only
test_tree_to_dataframe_multiple_columns
test_tree_to_dataframe_multiple_cols_subset_tree
test_tree_to_dataframe_to_tree

TestTreeToDict
test_tree_to_dict
test_tree_to_dict_name_key
test_tree_to_dict_parent_key
test_tree_to_dict_attr_dict
test_tree_to_dict_all_attr
test_tree_to_dict_max_depth
test_tree_to_dict_skip_depth
test_tree_to_dict_leaf_only
test_tree_to_dict_multiple_keys
test_tree_to_dict_multiple_keys_subset_tree
test_tree_to_dict_to_tree

TestTreeToNestedDict
test_tree_to_nested_dict
test_tree_to_nested_dict_name_key
test_tree_to_nested_dict_child_key
test_tree_to_nested_dict_attr_dict
test_tree_to_nested_dict_all_attr
test_tree_to_nested_dict_max_depth
test_tree_to_nested_dict_skip_depth
test_tree_to_nested_dict_multiple_keys
test_tree_to_nested_dict_multiple_keys_subset_tree
test_tree_to_nested_dict_to_tree

TestTreeToDot
test_tree_to_dot
test_tree_to_dot_type_error
test_tree_to_dot_directed
test_tree_to_dot_bg_color
test_tree_to_dot_fill_color
test_tree_to_dot_edge_colour
test_tree_to_dot_node_attr

TestDAGToDot
test_dag_to_dot
test_dag_to_dot_from_child
test_dag_to_dot_type_error
test_dag_to_dot_bg_color
test_dag_to_dot_fill_color
test_dag_to_dot_node_attr

*******************************
TestCloneTree
test_clone_tree_wrong_type
test_clone_tree_basenode_node
test_clone_tree_node_basenode
test_clone_tree_basenode_custom

TestPruneTree
test_prune_tree
test_prune_tree_multiple_path
test_prune_tree_nonexistant_path
test_prune_tree_sep
test_prune_tree_sep_wrong

TestTreeDiff
test_tree_diff
test_tree_diff_all_diff
test_tree_diff_same_tree

*******************************
TestCopyOrShiftNodes
test_copy_or_shift_nodes
test_copy_or_shift_nodes_invalid_type
test_copy_or_shift_nodes_unequal_length
test_copy_or_shift_nodes_invalid_paths
test_copy_or_shift_nodes_invalid_from_paths
test_copy_or_shift_nodes_invalid_to_paths
test_copy_or_shift_nodes_create_intermediate_path
test_copy_or_shift_nodes_sep
test_copy_or_shift_nodes_copy_node
test_copy_or_shift_nodes_skippable
test_copy_or_shift_nodes_delete_and_overriding
test_copy_or_shift_nodes_merge_children_change_levels
test_copy_or_shift_nodes_merge_children_same_level
test_copy_or_shift_nodes_shift_same_node
test_copy_or_shift_nodes_tree_to_tree

*******************************
TestSearch
test_find_all
test_find_all_descendant
test_find_all_max_depth
test_exception_find_all_max_count
test_exception_find_all_min_count
test_find
test_find_descendant
test_exception_find
test_find_name
test_find_names
test_find_full_path
test_find_full_path_sep_leading
test_find_full_path_sep_trailing
test_find_full_wrong_path
test_find_full_wrong_root
test_find_path
test_find_path_partial
test_find_path_sep_leading
test_find_path_sep_trailing
test_find_paths
test_find_paths_partial
test_find_paths_sep_leading
test_find_paths_sep_trailing
test_find_attr
test_find_attrs

*******************************
TestPreOrderIter
test_preorder_iter
test_preorder_iter2
test_preorder_iter_filter_condition
test_preorder_iter_filter_condition_skip_level
test_preorder_iter_stop_condition
test_preorder_iter_max_depth

TestPostOrderIter
test_postorder_iter
test_postorder_iter2
test_postorder_iter_filter_condition
test_postorder_iter_filter_condition_skip_level
test_postorder_iter_stop_condition
test_postorder_iter_max_depth

TestLevelOrderIter
test_levelorder_iter
test_levelorder_iter2
test_levelorder_iter_filter_condition
test_levelorder_iter_filter_condition_skip_level
test_levelorder_iter_stop_condition
test_levelorder_iter_max_depth

TestLevelOrderGroupIter
test_levelordergroup_iter
test_levelordergroup_iter2
test_levelordergroup_iter_filter_condition
test_levelordergroup_iter_filter_condition_skip_level
test_levelordergroup_iter_stop_condition
test_levelordergroup_iter_max_depth

*******************************
test_creation
test_add_list
test_add_list_duplicate
test_prioritize_list
test_prioritize_list_error //
test_add_item_single
test_add_item_single_list
test_add_item_multiple
test_add_item_multiple_list
test_add_item_type_error //
test_remove_item_single
test_remove_item_single_list
test_remove_duplicate_item
test_remove_duplicate_item_error
test_remove_item_multiple
test_remove_item_multiple_list
test_remove_item_error //
test_prioritize_item
test_prioritize_item_error //

test_add_list_verbose
test_add_list_duplicate_verbose
test_add_item_single_verbose
---------------------------------------------------------
