This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
AlgoTree is a powerful Python library for working with tree structures, featuring an immutable-by-default API, composable transformations, and comprehensive tree operations. Version 2.0+ provides a clean, modern architecture following functional programming principles.
Primary Interface: The fluent Python API (Node, Tree, transformers, selectors) is the recommended approach for all scripting, automation, and programmatic use.
Secondary Interface: The interactive shell (AlgoTree.shell) is designed for interactive exploration, quick queries, and terminal-based workflows - not for scripting or automation.
# Install dependencies
make install
# or
pip install -r requirements.txt# Run all tests
make test
# or
python -m pytest test/
# Run a specific test file
python -m pytest test/test_node.py
# Run with coverage
make coveragemake lint
# or
python -m flake8 AlgoTree test# Generate documentation
make docs# Build package
python setup.py sdist bdist_wheel
# Upload to PyPI
make pypi# Start interactive shell for exploration
python -m AlgoTree.shell.shell
# Start shell with a tree file
algotree-shell tree.json
# Use CLI for one-off terminal operations
algotree ls tree.json
algotree tree tree.json
algotree select 'n.depth > 2' tree.jsonNote: For scripting and automation, always use the Python API below, not the shell.
-
Immutable Node API
Node(AlgoTree/node.py): Immutable tree nodes with functional operations- Constructor:
Node(name, *children, attrs={}) - Immutable transformations:
with_name(),with_attrs(),with_child(), etc. - Tree operations:
map(),filter(),find(),find_all() - Iteration:
walk(),descendants(),ancestors(),leaves()
- Constructor:
node()convenience function for creating nodes with mixed string/Node children
-
Selectors (AlgoTree/selectors.py)
- Composable pattern matching for tree nodes
- Basic selectors:
name(),attrs(),type_(),predicate() - Structural selectors:
depth(),leaf(),root() - Logical combinators:
&(and),|(or),~(not),^(xor) - Structural combinators:
ChildOfSelector,ParentOfSelector, etc.
-
Transformers (AlgoTree/transformers.py)
- Tree → Tree transformers:
map_(),filter_(),prune(),graft(), etc. - Tree → Any shapers:
reduce_(),fold(),extract(),to_dict(),to_paths() - Composite transformers:
Pipeline,ParallelTransformer,RepeatTransformer
- Tree → Tree transformers:
-
Builders (AlgoTree/builders.py)
- Fluent API for tree construction
TreeBuilder,FluentTree,TreeContext,QuickBuilder- Factory functions:
tree(),branch(),leaf()
-
Tree Wrapper (AlgoTree/tree.py)
Tree: Wrapper providing functional operations and consistent API- Factory methods:
from_dict(),from_paths() - Fluent API with method chaining
-
DSL Support (AlgoTree/dsl.py)
TreeDSL: Parse trees from text formats- Formats: visual (Unicode tree), indent-based, S-expression
parse_tree()convenience function
-
Export & Visualization
exporters.py: Export to GraphViz, Mermaid, JSON, XML, YAML, HTMLpretty_tree.py: ASCII/Unicode tree visualizationserialization.py: Save/load trees to/from files
-
Interactive Shell (AlgoTree/shell/) - For exploration, not scripting
Forest: Collection of named treesShellContext: Immutable navigation stateTreeShell: Interactive REPL with prompt_toolkit- Built-in commands:
cd,ls,pwd,cat,tree,find,select, etc. - CLI tool:
algotreefor stateless terminal operations - Use case: Interactive exploration, learning, quick queries
- Not for: Scripting, automation, production code
- See
AlgoTree/shell/README.mdfor full documentation
Important: These examples use the Python API, which is the recommended approach for all scripting and programmatic use. The shell is only for interactive exploration.
from AlgoTree import Node, node
# Direct construction (immutable)
tree = Node("root",
Node("child1", attrs={"value": 1}),
Node("child2", attrs={"value": 2})
)
# Convenience function with mixed children
tree = node('root',
node('child1', value=1),
'child2', # String auto-converted to Node
node('child3',
'grandchild1',
'grandchild2'
)
)# All operations return new trees
tree2 = tree.with_name("new_root")
tree3 = tree.with_attrs(status="active")
tree4 = tree.with_child(Node("new_child"))
# Map over all nodes
doubled = tree.map(lambda n: n.with_attrs(
value=n.get("value", 0) * 2
))
# Filter nodes
filtered = tree.filter(lambda n: n.get("value", 0) > 5)# Find first match
node = tree.find("child1")
node = tree.find(lambda n: n.get("value") > 5)
# Find all matches
nodes = tree.find_all("leaf*") # Wildcard matching
nodes = tree.find_all(lambda n: n.is_leaf)# Various traversals
for node in tree.walk("preorder"):
print(node.name)
for node in tree.walk("postorder"):
process(node)
# Specific node types
for leaf in tree.leaves():
print(leaf)
for ancestor in node.ancestors():
print(ancestor)from AlgoTree import export_tree, save_tree, pretty_tree
# Export to various formats
json_str = export_tree(tree, "json")
dot_str = export_tree(tree, "graphviz")
mermaid_str = export_tree(tree, "mermaid")
# Save to file
save_tree(tree, "tree.json")
save_tree(tree, "tree.dot")
# Pretty print
print(pretty_tree(tree))- Unit tests in
test/directory cover all major components - Test files follow
test_*.pynaming convention - Tests use pytest framework
- Run specific test methods:
python -m pytest test/test_node.py::TestNodeCreation::test_simple_node
- Immutability: All operations return new objects, never mutate existing ones
- Composability: Small, focused functions that combine well
- Functional Style: Prefer pure functions and method chaining
- Type Safety: Full type hints for IDE support
- Clean Separation: Node (data) vs Tree (operations) vs Transformers (algorithms)
- Python First: The Python API is the primary interface for all programmatic use
For:
- Scripts and automation
- Production code
- Complex transformations
- Integration with other Python code
- Testing and CI/CD
- Any programmatic usage
Example:
from AlgoTree import Tree, Node, map_, filter_
tree = Tree(Node('root', Node('a'), Node('b')))
result = tree.filter(lambda n: n.depth > 0).map(lambda n: n.with_attrs(tagged=True))For:
- Interactive exploration of tree structures
- Quick ad-hoc queries
- Learning tree operations
- Terminal workflows
- Visualizing tree structure
Example:
$ algotree shell tree.json
> tree
> cd root
> find ".*"
> exitRule of thumb: If you're thinking about scripting shell commands, use the Python API instead.
The v2.0 API is a clean break from v1.x:
node = TreeNode(name="x", foo="bar") # Arbitrary kwargs
node.add_child(child) # Mutable operationsnode = Node("x", attrs={"foo": "bar"}) # Explicit attrs
node = node.with_child(child) # Immutable operations- Do what has been asked; nothing more, nothing less
- NEVER create files unless absolutely necessary
- ALWAYS prefer editing an existing file to creating a new one
- NEVER proactively create documentation files (*.md) or README files unless explicitly requested