Powerful and Lightweight Python Tree Data Structure with various plugins
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core node classes for building tree structures. This module provides the fundamental building blocks for creating hierarchical data structures with parent-child relationships and tree properties.
Extends any Python class with tree node functionality. The core mixin that provides parent-child relationships and all tree navigation properties.
class NodeMixin:
"""
Extends any Python class to a tree node.
The only tree relevant information is the parent attribute.
If None, the NodeMixin is root node.
If set to another node, the NodeMixin becomes the child of it.
"""
def __init__(self): ...
# Core tree relationships
parent: Optional['NodeMixin']
children: Tuple['NodeMixin', ...]
# Tree navigation properties
ancestors: Tuple['NodeMixin', ...]
descendants: Tuple['NodeMixin', ...]
leaves: Tuple['NodeMixin', ...]
root: 'NodeMixin'
siblings: Tuple['NodeMixin', ...]
# Tree state properties
is_leaf: bool
is_root: bool
depth: int
height: int
path: Tuple['NodeMixin', ...]
# Methods
def iter_path_reverse(self) -> Iterator['NodeMixin']: ...Usage Example:
from anytree import NodeMixin, RenderTree
class MyBaseClass:
foo = 4
class MyClass(MyBaseClass, NodeMixin):
def __init__(self, name, length, width, parent=None, children=None):
super().__init__()
self.name = name
self.length = length
self.width = width
self.parent = parent
if children:
self.children = children
# Create tree structure
my0 = MyClass('my0', 0, 0)
my1 = MyClass('my1', 1, 0, parent=my0)
my2 = MyClass('my2', 0, 2, parent=my0)
print(RenderTree(my0))A simple tree node with a required name attribute and optional keyword arguments. Most commonly used node class for straightforward tree structures.
class Node(NodeMixin):
"""
A simple tree node with a name and any kwargs.
Args:
name: A name or any other object this node can reference to as identifier.
parent: Reference to parent node.
children: Iterable with child nodes.
**kwargs: Any other given attribute is just stored as object attribute.
"""
def __init__(self, name, parent=None, children=None, **kwargs): ...
name: AnyUsage Example:
from anytree import Node, RenderTree
# Create nodes with parent relationships
root = Node("root")
s0 = Node("sub0", parent=root)
s0b = Node("sub0B", parent=s0, foo=4, bar=109)
s0a = Node("sub0A", parent=s0)
s1 = Node("sub1", parent=root)
print(RenderTree(root))
# Node('/root')
# ├── Node('/root/sub0')
# │ ├── Node('/root/sub0/sub0B', bar=109, foo=4)
# │ └── Node('/root/sub0/sub0A')
# └── Node('/root/sub1')
# Alternative construction using children
root = Node("root", children=[
Node("sub0", children=[
Node("sub0B", bar=109, foo=4),
Node("sub0A"),
]),
Node("sub1")
])A generic tree node with no required attributes, only optional keyword arguments. Useful when you need complete flexibility in node attributes.
class AnyNode(NodeMixin):
"""
A generic tree node with any kwargs.
Keyword Args:
parent: Reference to parent node.
children: Iterable with child nodes.
**kwargs: Any other given attribute is just stored as object attribute.
"""
def __init__(self, parent=None, children=None, **kwargs): ...Usage Example:
from anytree import AnyNode, RenderTree
# Create nodes with arbitrary attributes
root = AnyNode(id="root", type="company")
s0 = AnyNode(id="sub0", parent=root, department="engineering")
s1 = AnyNode(id="sub1", parent=root, department="marketing", budget=50000)
print(RenderTree(root))
# AnyNode(id='root', type='company')
# ├── AnyNode(department='engineering', id='sub0')
# └── AnyNode(budget=50000, department='marketing', id='sub1')A lightweight version of NodeMixin using __slots__ for reduced memory usage. Provides the same functionality as NodeMixin but with better memory efficiency for large trees.
class LightNodeMixin:
"""
A NodeMixin using slots for memory efficiency.
"""
def __init__(self): ...
# Same properties and methods as NodeMixin
parent: Optional['LightNodeMixin']
children: Tuple['LightNodeMixin', ...]
# ... (all other NodeMixin properties)Mixin for creating symbolic link nodes that reference other tree nodes. Useful for creating references without duplicating tree structures.
class SymlinkNodeMixin(NodeMixin):
"""
Extends any Python class to a symbolic link to a tree node.
Args:
target: Target node this symlink points to.
"""
def __init__(self, target=None): ...
target: Optional['NodeMixin']A complete symbolic link node implementation that combines SymlinkNodeMixin functionality with the Node class structure.
class SymlinkNode(SymlinkNodeMixin):
"""
Tree node which references to another tree node.
"""
def __init__(self, target=None, parent=None, children=None): ...Usage Example:
from anytree import Node, SymlinkNode, RenderTree
# Create main tree
root = Node("root")
sub1 = Node("sub1", parent=root)
sub2 = Node("sub2", parent=root)
# Create symbolic link to sub1
link = SymlinkNode(target=sub1, parent=sub2)
print(RenderTree(root))All node classes inherit these properties from NodeMixin:
parent: Direct parent node (None for root nodes)children: Tuple of direct child nodesancestors: Tuple of all ancestor nodes from parent to rootdescendants: Tuple of all descendant nodes in subtreesiblings: Tuple of sibling nodes (same parent)leaves: Tuple of all leaf nodes in subtreeroot: Root node of the treepath: Tuple representing path from root to this nodedepth: Integer depth/level in tree (0 for root)height: Integer height of subtree rooted at this nodeis_root: Boolean indicating if node is the rootis_leaf: Boolean indicating if node has no childrenfrom anytree import NodeMixin
class Employee(NodeMixin):
def __init__(self, name, title, salary, parent=None):
super().__init__()
self.name = name
self.title = title
self.salary = salary
self.parent = parent
def __repr__(self):
return f"Employee('{self.name}', '{self.title}')"
# Build organizational chart
ceo = Employee("Alice", "CEO", 200000)
cto = Employee("Bob", "CTO", 150000, parent=ceo)
engineer = Employee("Charlie", "Engineer", 80000, parent=cto)from anytree import Node
def build_file_tree(path_data):
"""Build tree from path strings"""
root = Node("root")
for path_str in path_data:
parts = path_str.split('/')
current = root
for part in parts:
# Find or create child
child = next((c for c in current.children if c.name == part), None)
if not child:
child = Node(part, parent=current)
current = child
return root
paths = ["src/main.py", "src/utils.py", "tests/test_main.py"]
tree = build_file_tree(paths)Install with Tessl CLI
npx tessl i tessl/pypi-anytree