Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed:
- Refactor: Combine plugins in one file, add plugins to the class docs dynamically.

## [1.0.3] - 2025-10-30
### Added:
Expand Down
162 changes: 162 additions & 0 deletions bigtree/_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
def register_binarytree_plugins() -> None:
"""Register plugin for BinaryTree"""
from bigtree.binarytree import construct
from bigtree.binarytree.binarytree import BinaryTree
from bigtree.utils import iterators

BinaryTree.register_plugins(
{
# Append methods
"from_heapq_list": construct.list_to_binarytree,
},
method="class",
)
BinaryTree.register_plugins(
{
# Iterator methods
"inorder_iter": iterators.inorder_iter,
},
)

plugin_docs = "\n".join(
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
for name, func in BinaryTree._plugins.items()
)
BinaryTree.__doc__ = (
BinaryTree.__doc__ or ""
) + f"\n\n## Registered Plugins\n\n{plugin_docs}"


def register_dag_plugins() -> None:
"""Register plugin for DAG"""
from bigtree.dag import construct, export
from bigtree.dag.dag import DAG
from bigtree.utils import iterators

DAG.register_plugins(
{
# Construct methods
"from_dataframe": construct.dataframe_to_dag,
"from_dict": construct.dict_to_dag,
"from_list": construct.list_to_dag,
},
method="class",
)
DAG.register_plugins(
{
# Export methods
"to_dataframe": export.dag_to_dataframe,
"to_dict": export.dag_to_dict,
"to_list": export.dag_to_list,
"to_dot": export.dag_to_dot,
# Iterator methods
"iterate": iterators.dag_iterator,
},
)

plugin_docs = "\n".join(
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
for name, func in DAG._plugins.items()
)
DAG.__doc__ = (DAG.__doc__ or "") + f"\n\n## Registered Plugins\n\n{plugin_docs}"


def register_tree_plugins() -> None:
"""Register plugin for Tree"""
from bigtree.tree import construct, export, helper, query, search
from bigtree.tree.tree import Tree
from bigtree.utils import iterators

Tree.register_plugins(
{
# Construct methods
"from_dataframe": construct.dataframe_to_tree,
"from_dataframe_relation": construct.dataframe_to_tree_by_relation,
"from_polars": construct.polars_to_tree,
"from_polars_relation": construct.polars_to_tree_by_relation,
"from_dict": construct.dict_to_tree,
"from_nested_dict": construct.nested_dict_to_tree,
"from_nested_dict_key": construct.nested_dict_key_to_tree,
"from_list": construct.list_to_tree,
"from_list_relation": construct.list_to_tree_by_relation,
"from_str": construct.str_to_tree,
"from_newick": construct.newick_to_tree,
},
method="class",
)

Tree.register_plugins(
{
# Append methods
"add_dataframe_by_path": construct.add_dataframe_to_tree_by_path,
"add_dataframe_by_name": construct.add_dataframe_to_tree_by_name,
"add_polars_by_path": construct.add_polars_to_tree_by_path,
"add_polars_by_name": construct.add_polars_to_tree_by_name,
"add_dict_by_path": construct.add_dict_to_tree_by_path,
"add_dict_by_name": construct.add_dict_to_tree_by_name,
# Export methods
"show": export.print_tree,
"hshow": export.hprint_tree,
"vshow": export.vprint_tree,
"yield": export.yield_tree,
"hyield": export.hyield_tree,
"vyield": export.vyield_tree,
"to_dataframe": export.tree_to_dataframe,
"to_polars": export.tree_to_polars,
"to_dict": export.tree_to_dict,
"to_nested_dict": export.tree_to_nested_dict,
"to_nested_dict_key": export.tree_to_nested_dict_key,
"to_newick": export.tree_to_newick,
"to_dot": export.tree_to_dot,
"to_pillow_graph": export.tree_to_pillow_graph,
"to_pillow": export.tree_to_pillow,
"to_mermaid": export.tree_to_mermaid,
"to_vis": export.tree_to_vis,
# Query methods
"query": query.query_tree,
# Search methods
"findall": search.findall,
"find": search.find,
"find_name": search.find_name,
"find_names": search.find_names,
"find_relative_path": search.find_relative_path,
"find_relative_paths": search.find_relative_paths,
"find_full_path": search.find_full_path,
"find_path": search.find_path,
"find_paths": search.find_paths,
"find_attr": search.find_attr,
"find_attrs": search.find_attrs,
"find_children": search.find_children,
"find_child": search.find_child,
"find_child_by_name": search.find_child_by_name,
# Iterator methods
"preorder_iter": iterators.preorder_iter,
"postorder_iter": iterators.postorder_iter,
"levelorder_iter": iterators.levelorder_iter,
"levelordergroup_iter": iterators.levelordergroup_iter,
"zigzag_iter": iterators.zigzag_iter,
"zigzaggroup_iter": iterators.zigzaggroup_iter,
}
)
Tree.register_plugins(
{
# Helper methods
"clone": helper.clone_tree,
"prune": helper.prune_tree,
},
method="helper",
)
Tree.register_plugins(
{
# Helper methods
"diff_dataframe": helper.get_tree_diff_dataframe,
"diff": helper.get_tree_diff,
},
method="diff",
)

plugin_docs = "\n".join(
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
for name, func in Tree._plugins.items()
)
Tree.__doc__ = (Tree.__doc__ or "") + f"\n\n## Registered Plugins\n\n{plugin_docs}"
17 changes: 2 additions & 15 deletions bigtree/binarytree/binarytree.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from typing import Any

from bigtree.binarytree import construct
from bigtree._plugins import register_binarytree_plugins
from bigtree.node import binarynode
from bigtree.tree.tree import Tree
from bigtree.utils import iterators


class BinaryTree(Tree):
Expand All @@ -24,16 +23,4 @@ def __init__(self, root: binarynode.BinaryNode):
super().__init__(root)


BinaryTree.register_plugins(
{
# Append methods
"from_heapq_list": construct.list_to_binarytree,
},
method="class",
)
BinaryTree.register_plugins(
{
# Iterator methods
"inorder_iter": iterators.inorder_iter,
},
)
register_binarytree_plugins()
24 changes: 2 additions & 22 deletions bigtree/dag/dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
import functools
from typing import Any, Callable, Literal, TypeVar

from bigtree.dag import construct, export
from bigtree._plugins import register_dag_plugins
from bigtree.node import dagnode
from bigtree.utils import iterators


class DAG:
Expand Down Expand Up @@ -121,23 +120,4 @@ def __repr__(self) -> str:

T = TypeVar("T", bound=DAG)

DAG.register_plugins(
{
# Construct methods
"from_dataframe": construct.dataframe_to_dag,
"from_dict": construct.dict_to_dag,
"from_list": construct.list_to_dag,
},
method="class",
)
DAG.register_plugins(
{
# Export methods
"to_dataframe": export.dag_to_dataframe,
"to_dict": export.dag_to_dict,
"to_list": export.dag_to_list,
"to_dot": export.dag_to_dot,
# Iterator methods
"iterate": iterators.dag_iterator,
},
)
register_dag_plugins()
4 changes: 4 additions & 0 deletions bigtree/tree/construct/dataframes.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def add_dataframe_to_tree_by_path(
... columns=["PATH", "age"]
... )
>>> tree.add_dataframe_by_path(path_data)
Node(/a, age=90)
>>> tree.show(attr_list=["age"])
a [age=90]
├── b [age=65]
Expand Down Expand Up @@ -159,6 +160,7 @@ def add_dataframe_to_tree_by_name(
... columns=["NAME", "age"]
... )
>>> tree.add_dataframe_by_name(name_data)
Node(/a, age=90)
>>> tree.show(attr_list=["age"])
a [age=90]
└── b [age=65]
Expand Down Expand Up @@ -244,6 +246,7 @@ def add_polars_to_tree_by_path(
... schema=["PATH", "age"]
... )
>>> tree.add_polars_by_path(path_data)
Node(/a, age=90)
>>> tree.show(attr_list=["age"])
a [age=90]
├── b [age=65]
Expand Down Expand Up @@ -323,6 +326,7 @@ def add_polars_to_tree_by_name(
... "age": [90, 65],
... })
>>> tree.add_polars_by_name(name_data)
Node(/a, age=90)
>>> tree.show(attr_list=["age"])
a [age=90]
└── b [age=65]
Expand Down
2 changes: 2 additions & 0 deletions bigtree/tree/construct/dictionaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def add_dict_to_tree_by_path(
... "a/b/e/h": {"age": 6},
... }
>>> tree.add_dict_by_path(path_dict)
Node(/a, age=90)
>>> tree.show()
a
├── b
Expand Down Expand Up @@ -109,6 +110,7 @@ def add_dict_to_tree_by_name(tree: T, name_attrs: Mapping[str, Mapping[str, Any]
... "b": {"age": 65},
... }
>>> tree.add_dict_by_name(name_dict)
Node(/a, age=90)
>>> tree.show(attr_list=["age"])
a [age=90]
└── b [age=65]
Expand Down
2 changes: 1 addition & 1 deletion bigtree/tree/export/stdout.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def print_tree(
attr_list: node attributes to print
attr_format: if attributes are displayed, the format in which to display, uses k,v to correspond to
attribute name and attribute value
attr_list_sep: if attributes are displayed, the separator of attributes, defaults to comma
attr_sep: if attributes are displayed, the separator of attributes, defaults to comma
attr_omit_null: indicator whether to omit showing of null attributes
attr_bracket: open and close bracket for `all_attrs` or `attr_list`
style: style of print
Expand Down
Loading