Skip to content

Commit dee9d86

Browse files
authored
Combine plugins in one file (#419)
* feat: combine plugins * docs: fix typo * docs: update requirement * docs: standardise docs to start without linebreak * docs: fix doctest * docs: add docs dynamically - mkdocs does not pick this up though
1 parent f145186 commit dee9d86

File tree

11 files changed

+195
-160
lines changed

11 files changed

+195
-160
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ 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+
### Changed:
9+
- Refactor: Combine plugins in one file, add plugins to the class docs dynamically.
810

911
## [1.0.3] - 2025-10-30
1012
### Added:

bigtree/_plugins.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
def register_binarytree_plugins() -> None:
2+
"""Register plugin for BinaryTree"""
3+
from bigtree.binarytree import construct
4+
from bigtree.binarytree.binarytree import BinaryTree
5+
from bigtree.utils import iterators
6+
7+
BinaryTree.register_plugins(
8+
{
9+
# Append methods
10+
"from_heapq_list": construct.list_to_binarytree,
11+
},
12+
method="class",
13+
)
14+
BinaryTree.register_plugins(
15+
{
16+
# Iterator methods
17+
"inorder_iter": iterators.inorder_iter,
18+
},
19+
)
20+
21+
plugin_docs = "\n".join(
22+
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
23+
for name, func in BinaryTree._plugins.items()
24+
)
25+
BinaryTree.__doc__ = (
26+
BinaryTree.__doc__ or ""
27+
) + f"\n\n## Registered Plugins\n\n{plugin_docs}"
28+
29+
30+
def register_dag_plugins() -> None:
31+
"""Register plugin for DAG"""
32+
from bigtree.dag import construct, export
33+
from bigtree.dag.dag import DAG
34+
from bigtree.utils import iterators
35+
36+
DAG.register_plugins(
37+
{
38+
# Construct methods
39+
"from_dataframe": construct.dataframe_to_dag,
40+
"from_dict": construct.dict_to_dag,
41+
"from_list": construct.list_to_dag,
42+
},
43+
method="class",
44+
)
45+
DAG.register_plugins(
46+
{
47+
# Export methods
48+
"to_dataframe": export.dag_to_dataframe,
49+
"to_dict": export.dag_to_dict,
50+
"to_list": export.dag_to_list,
51+
"to_dot": export.dag_to_dot,
52+
# Iterator methods
53+
"iterate": iterators.dag_iterator,
54+
},
55+
)
56+
57+
plugin_docs = "\n".join(
58+
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
59+
for name, func in DAG._plugins.items()
60+
)
61+
DAG.__doc__ = (DAG.__doc__ or "") + f"\n\n## Registered Plugins\n\n{plugin_docs}"
62+
63+
64+
def register_tree_plugins() -> None:
65+
"""Register plugin for Tree"""
66+
from bigtree.tree import construct, export, helper, query, search
67+
from bigtree.tree.tree import Tree
68+
from bigtree.utils import iterators
69+
70+
Tree.register_plugins(
71+
{
72+
# Construct methods
73+
"from_dataframe": construct.dataframe_to_tree,
74+
"from_dataframe_relation": construct.dataframe_to_tree_by_relation,
75+
"from_polars": construct.polars_to_tree,
76+
"from_polars_relation": construct.polars_to_tree_by_relation,
77+
"from_dict": construct.dict_to_tree,
78+
"from_nested_dict": construct.nested_dict_to_tree,
79+
"from_nested_dict_key": construct.nested_dict_key_to_tree,
80+
"from_list": construct.list_to_tree,
81+
"from_list_relation": construct.list_to_tree_by_relation,
82+
"from_str": construct.str_to_tree,
83+
"from_newick": construct.newick_to_tree,
84+
},
85+
method="class",
86+
)
87+
88+
Tree.register_plugins(
89+
{
90+
# Append methods
91+
"add_dataframe_by_path": construct.add_dataframe_to_tree_by_path,
92+
"add_dataframe_by_name": construct.add_dataframe_to_tree_by_name,
93+
"add_polars_by_path": construct.add_polars_to_tree_by_path,
94+
"add_polars_by_name": construct.add_polars_to_tree_by_name,
95+
"add_dict_by_path": construct.add_dict_to_tree_by_path,
96+
"add_dict_by_name": construct.add_dict_to_tree_by_name,
97+
# Export methods
98+
"show": export.print_tree,
99+
"hshow": export.hprint_tree,
100+
"vshow": export.vprint_tree,
101+
"yield": export.yield_tree,
102+
"hyield": export.hyield_tree,
103+
"vyield": export.vyield_tree,
104+
"to_dataframe": export.tree_to_dataframe,
105+
"to_polars": export.tree_to_polars,
106+
"to_dict": export.tree_to_dict,
107+
"to_nested_dict": export.tree_to_nested_dict,
108+
"to_nested_dict_key": export.tree_to_nested_dict_key,
109+
"to_newick": export.tree_to_newick,
110+
"to_dot": export.tree_to_dot,
111+
"to_pillow_graph": export.tree_to_pillow_graph,
112+
"to_pillow": export.tree_to_pillow,
113+
"to_mermaid": export.tree_to_mermaid,
114+
"to_vis": export.tree_to_vis,
115+
# Query methods
116+
"query": query.query_tree,
117+
# Search methods
118+
"findall": search.findall,
119+
"find": search.find,
120+
"find_name": search.find_name,
121+
"find_names": search.find_names,
122+
"find_relative_path": search.find_relative_path,
123+
"find_relative_paths": search.find_relative_paths,
124+
"find_full_path": search.find_full_path,
125+
"find_path": search.find_path,
126+
"find_paths": search.find_paths,
127+
"find_attr": search.find_attr,
128+
"find_attrs": search.find_attrs,
129+
"find_children": search.find_children,
130+
"find_child": search.find_child,
131+
"find_child_by_name": search.find_child_by_name,
132+
# Iterator methods
133+
"preorder_iter": iterators.preorder_iter,
134+
"postorder_iter": iterators.postorder_iter,
135+
"levelorder_iter": iterators.levelorder_iter,
136+
"levelordergroup_iter": iterators.levelordergroup_iter,
137+
"zigzag_iter": iterators.zigzag_iter,
138+
"zigzaggroup_iter": iterators.zigzaggroup_iter,
139+
}
140+
)
141+
Tree.register_plugins(
142+
{
143+
# Helper methods
144+
"clone": helper.clone_tree,
145+
"prune": helper.prune_tree,
146+
},
147+
method="helper",
148+
)
149+
Tree.register_plugins(
150+
{
151+
# Helper methods
152+
"diff_dataframe": helper.get_tree_diff_dataframe,
153+
"diff": helper.get_tree_diff,
154+
},
155+
method="diff",
156+
)
157+
158+
plugin_docs = "\n".join(
159+
f"- `{name}()` — {getattr(func, '__doc__', '').splitlines()[0] if func.__doc__ else ''}"
160+
for name, func in Tree._plugins.items()
161+
)
162+
Tree.__doc__ = (Tree.__doc__ or "") + f"\n\n## Registered Plugins\n\n{plugin_docs}"

bigtree/binarytree/binarytree.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from typing import Any
22

3-
from bigtree.binarytree import construct
3+
from bigtree._plugins import register_binarytree_plugins
44
from bigtree.node import binarynode
55
from bigtree.tree.tree import Tree
6-
from bigtree.utils import iterators
76

87

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

2625

27-
BinaryTree.register_plugins(
28-
{
29-
# Append methods
30-
"from_heapq_list": construct.list_to_binarytree,
31-
},
32-
method="class",
33-
)
34-
BinaryTree.register_plugins(
35-
{
36-
# Iterator methods
37-
"inorder_iter": iterators.inorder_iter,
38-
},
39-
)
26+
register_binarytree_plugins()

bigtree/dag/dag.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
import functools
55
from typing import Any, Callable, Literal, TypeVar
66

7-
from bigtree.dag import construct, export
7+
from bigtree._plugins import register_dag_plugins
88
from bigtree.node import dagnode
9-
from bigtree.utils import iterators
109

1110

1211
class DAG:
@@ -121,23 +120,4 @@ def __repr__(self) -> str:
121120

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

124-
DAG.register_plugins(
125-
{
126-
# Construct methods
127-
"from_dataframe": construct.dataframe_to_dag,
128-
"from_dict": construct.dict_to_dag,
129-
"from_list": construct.list_to_dag,
130-
},
131-
method="class",
132-
)
133-
DAG.register_plugins(
134-
{
135-
# Export methods
136-
"to_dataframe": export.dag_to_dataframe,
137-
"to_dict": export.dag_to_dict,
138-
"to_list": export.dag_to_list,
139-
"to_dot": export.dag_to_dot,
140-
# Iterator methods
141-
"iterate": iterators.dag_iterator,
142-
},
143-
)
123+
register_dag_plugins()

bigtree/tree/construct/dataframes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def add_dataframe_to_tree_by_path(
8080
... columns=["PATH", "age"]
8181
... )
8282
>>> tree.add_dataframe_by_path(path_data)
83+
Node(/a, age=90)
8384
>>> tree.show(attr_list=["age"])
8485
a [age=90]
8586
├── b [age=65]
@@ -159,6 +160,7 @@ def add_dataframe_to_tree_by_name(
159160
... columns=["NAME", "age"]
160161
... )
161162
>>> tree.add_dataframe_by_name(name_data)
163+
Node(/a, age=90)
162164
>>> tree.show(attr_list=["age"])
163165
a [age=90]
164166
└── b [age=65]
@@ -244,6 +246,7 @@ def add_polars_to_tree_by_path(
244246
... schema=["PATH", "age"]
245247
... )
246248
>>> tree.add_polars_by_path(path_data)
249+
Node(/a, age=90)
247250
>>> tree.show(attr_list=["age"])
248251
a [age=90]
249252
├── b [age=65]
@@ -323,6 +326,7 @@ def add_polars_to_tree_by_name(
323326
... "age": [90, 65],
324327
... })
325328
>>> tree.add_polars_by_name(name_data)
329+
Node(/a, age=90)
326330
>>> tree.show(attr_list=["age"])
327331
a [age=90]
328332
└── b [age=65]

bigtree/tree/construct/dictionaries.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def add_dict_to_tree_by_path(
5555
... "a/b/e/h": {"age": 6},
5656
... }
5757
>>> tree.add_dict_by_path(path_dict)
58+
Node(/a, age=90)
5859
>>> tree.show()
5960
a
6061
├── b
@@ -109,6 +110,7 @@ def add_dict_to_tree_by_name(tree: T, name_attrs: Mapping[str, Mapping[str, Any]
109110
... "b": {"age": 65},
110111
... }
111112
>>> tree.add_dict_by_name(name_dict)
113+
Node(/a, age=90)
112114
>>> tree.show(attr_list=["age"])
113115
a [age=90]
114116
└── b [age=65]

bigtree/tree/export/stdout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def print_tree(
188188
attr_list: node attributes to print
189189
attr_format: if attributes are displayed, the format in which to display, uses k,v to correspond to
190190
attribute name and attribute value
191-
attr_list_sep: if attributes are displayed, the separator of attributes, defaults to comma
191+
attr_sep: if attributes are displayed, the separator of attributes, defaults to comma
192192
attr_omit_null: indicator whether to omit showing of null attributes
193193
attr_bracket: open and close bracket for `all_attrs` or `attr_list`
194194
style: style of print

0 commit comments

Comments
 (0)