Node Classes

Node Classes.

  • AnyNode: a generic tree node with any number of attributes.
  • Node: a simple tree node with at least a name attribute and any number of additional attributes.
  • NodeMixin: extends any python class to a tree node.
  • SymlinkNode: Tree node which references to another tree node.
  • SymlinkNodeMixin: extends any Python class to a symbolic link to a tree node.
class anytree.node.anynode.AnyNode(parent=None, children=None, **kwargs)[source]

Bases: anytree.node.nodemixin.NodeMixin, object

A generic tree node with any kwargs.

Keyword Arguments:
 
  • parent – Reference to parent node.
  • children – Iterable with child nodes.
  • * – Any other given attribute is just stored as object attribute.

Other than Node this class has no default idenifier. It is up to the user to use other attributes for identification.

The parent attribute refers the parent node:

>>> from anytree import AnyNode, RenderTree
>>> root = AnyNode(id="root")
>>> s0 = AnyNode(id="sub0", parent=root)
>>> s0b = AnyNode(id="sub0B", parent=s0, foo=4, bar=109)
>>> s0a = AnyNode(id="sub0A", parent=s0)
>>> s1 = AnyNode(id="sub1", parent=root)
>>> s1a = AnyNode(id="sub1A", parent=s1)
>>> s1b = AnyNode(id="sub1B", parent=s1, bar=8)
>>> s1c = AnyNode(id="sub1C", parent=s1)
>>> s1ca = AnyNode(id="sub1Ca", parent=s1c)
>>> root
AnyNode(id='root')
>>> s0
AnyNode(id='sub0')
>>> print(RenderTree(root))
AnyNode(id='root')
├── AnyNode(id='sub0')
│   ├── AnyNode(bar=109, foo=4, id='sub0B')
│   └── AnyNode(id='sub0A')
└── AnyNode(id='sub1')
    ├── AnyNode(id='sub1A')
    ├── AnyNode(bar=8, id='sub1B')
    └── AnyNode(id='sub1C')
        └── AnyNode(id='sub1Ca')

The same tree can be constructed by using the children attribute:

>>> root = AnyNode(id="root", children=[
...     AnyNode(id="sub0", children=[
...         AnyNode(id="sub0B", foo=4, bar=109),
...         AnyNode(id="sub0A"),
...     ]),
...     AnyNode(id="sub1", children=[
...         AnyNode(id="sub1A"),
...         AnyNode(id="sub1B", bar=8),
...         AnyNode(id="sub1C", children=[
...             AnyNode(id="sub1Ca"),
...         ]),
...     ]),
... ])
>>> print(RenderTree(root))
AnyNode(id='root')
├── AnyNode(id='sub0')
│   ├── AnyNode(bar=109, foo=4, id='sub0B')
│   └── AnyNode(id='sub0A')
└── AnyNode(id='sub1')
    ├── AnyNode(id='sub1A')
    ├── AnyNode(bar=8, id='sub1B')
    └── AnyNode(id='sub1C')
        └── AnyNode(id='sub1Ca')

Node attributes can be added, modified and deleted the pythonic way:

>>> root.new = 'a new attribute'
>>> s0b.bar = 110  # modified
>>> del s1b.bar
>>> print(RenderTree(root))
AnyNode(id='root', new='a new attribute')
├── AnyNode(id='sub0')
│   ├── AnyNode(bar=109, foo=4, id='sub0B')
│   └── AnyNode(id='sub0A')
└── AnyNode(id='sub1')
    ├── AnyNode(id='sub1A')
    ├── AnyNode(bar=8, id='sub1B')
    └── AnyNode(id='sub1C')
        └── AnyNode(id='sub1Ca')
class anytree.node.node.Node(name, parent=None, children=None, **kwargs)[source]

Bases: anytree.node.nodemixin.NodeMixin, object

A simple tree node with a name and any kwargs.

Parameters:

name – A name or any other object this node can reference to as idendifier.

Keyword Arguments:
 
  • parent – Reference to parent node.
  • children – Iterable with child nodes.
  • * – Any other given attribute is just stored as object attribute.

Other than AnyNode this class has at least the name attribute, to distinguish between different instances.

The parent attribute refers the parent node:

>>> from anytree import Node, RenderTree
>>> 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)
>>> s1a = Node("sub1A", parent=s1)
>>> s1b = Node("sub1B", parent=s1, bar=8)
>>> s1c = Node("sub1C", parent=s1)
>>> s1ca = Node("sub1Ca", parent=s1c)
>>> print(RenderTree(root))
Node('/root')
├── Node('/root/sub0')
│   ├── Node('/root/sub0/sub0B', bar=109, foo=4)
│   └── Node('/root/sub0/sub0A')
└── Node('/root/sub1')
    ├── Node('/root/sub1/sub1A')
    ├── Node('/root/sub1/sub1B', bar=8)
    └── Node('/root/sub1/sub1C')
        └── Node('/root/sub1/sub1C/sub1Ca')

The same tree can be constructed by using the children attribute:

>>> root = Node("root", children=[
...     Node("sub0", children=[
...         Node("sub0B", bar=109, foo=4),
...         Node("sub0A", children=None),
...     ]),
...     Node("sub1", children=[
...         Node("sub1A"),
...         Node("sub1B", bar=8, children=[]),
...         Node("sub1C", children=[
...             Node("sub1Ca"),
...         ]),
...     ]),
... ])
>>> print(RenderTree(root))
Node('/root')
├── Node('/root/sub0')
│   ├── Node('/root/sub0/sub0B', bar=109, foo=4)
│   └── Node('/root/sub0/sub0A')
└── Node('/root/sub1')
    ├── Node('/root/sub1/sub1A')
    ├── Node('/root/sub1/sub1B', bar=8)
    └── Node('/root/sub1/sub1C')
        └── Node('/root/sub1/sub1C/sub1Ca')
class anytree.node.nodemixin.NodeMixin[source]

Bases: object

separator = '/'

The NodeMixin class 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.

The children attribute can be used likewise. If None the NodeMixin has no children. The children attribute can be set to any iterable of NodeMixin instances. These instances become children of the node.

>>> from anytree import NodeMixin, RenderTree
>>> class MyBaseClass(object):  # Just an example of a base class
...     foo = 4
>>> class MyClass(MyBaseClass, NodeMixin):  # Add Node feature
...     def __init__(self, name, length, width, parent=None, children=None):
...         super(MyClass, self).__init__()
...         self.name = name
...         self.length = length
...         self.width = width
...         self.parent = parent
...         if children:
...             self.children = children

Construction via parent:

>>> my0 = MyClass('my0', 0, 0)
>>> my1 = MyClass('my1', 1, 0, parent=my0)
>>> my2 = MyClass('my2', 0, 2, parent=my0)
>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2

Construction via children:

>>> my0 = MyClass('my0', 0, 0, children=[
...     MyClass('my1', 1, 0),
...     MyClass('my2', 0, 2),
... ]
>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2

Both approaches can be mixed:

>>> my0 = MyClass('my0', 0, 0, children=[
...     MyClass('my1', 1, 0),
... ]
>>> my2 = MyClass('my2', 0, 2, parent=my0)
>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2
parent

Parent Node.

On set, the node is detached from any previous parent node and attached to the new node.

>>> from anytree import Node, RenderTree
>>> udo = Node("Udo")
>>> marc = Node("Marc")
>>> lian = Node("Lian", parent=marc)
>>> print(RenderTree(udo))
Node('/Udo')
>>> print(RenderTree(marc))
Node('/Marc')
└── Node('/Marc/Lian')

Attach

>>> marc.parent = udo
>>> print(RenderTree(udo))
Node('/Udo')
└── Node('/Udo/Marc')
    └── Node('/Udo/Marc/Lian')

Detach

To make a node to a root node, just set this attribute to None.

>>> marc.is_root
False
>>> marc.parent = None
>>> marc.is_root
True
children

All child nodes.

>>> from anytree import Node
>>> n = Node("n")
>>> a = Node("a", parent=n)
>>> b = Node("b", parent=n)
>>> c = Node("c", parent=n)
>>> n.children
(Node('/n/a'), Node('/n/b'), Node('/n/c'))

Modifying the children attribute modifies the tree.

Detach

The children attribute can be updated by setting to an iterable.

>>> n.children = [a, b]
>>> n.children
(Node('/n/a'), Node('/n/b'))

Node c is removed from the tree. In case of an existing reference, the node c does not vanish and is the root of its own tree.

>>> c
Node('/c')

Attach

>>> d = Node("d")
>>> d
Node('/d')
>>> n.children = [a, b, d]
>>> n.children
(Node('/n/a'), Node('/n/b'), Node('/n/d'))
>>> d
Node('/n/d')

Duplicate

A node can just be the children once. Duplicates cause a TreeError:

>>> n.children = [a, b, d, a]
Traceback (most recent call last):
    ...
anytree.node.exceptions.TreeError: Cannot add node Node('/n/a') multiple times as child.
path

Path of this Node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.path
(Node('/Udo'),)
>>> marc.path
(Node('/Udo'), Node('/Udo/Marc'))
>>> lian.path
(Node('/Udo'), Node('/Udo/Marc'), Node('/Udo/Marc/Lian'))
iter_path_reverse()[source]

Iterate up the tree from the current node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> for node in udo.iter_path_reverse():
...     print(node)
Node('/Udo')
>>> for node in marc.iter_path_reverse():
...     print(node)
Node('/Udo/Marc')
Node('/Udo')
>>> for node in lian.iter_path_reverse():
...     print(node)
Node('/Udo/Marc/Lian')
Node('/Udo/Marc')
Node('/Udo')
ancestors

All parent nodes and their parent nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.ancestors
()
>>> marc.ancestors
(Node('/Udo'),)
>>> lian.ancestors
(Node('/Udo'), Node('/Udo/Marc'))
anchestors

All parent nodes and their parent nodes - see ancestors.

The attribute anchestors is just a typo of ancestors. Please use ancestors. This attribute will be removed in the 3.0.0 release.

descendants

All child nodes and all their child nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> soe = Node("Soe", parent=lian)
>>> udo.descendants
(Node('/Udo/Marc'), Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lian/Soe'), Node('/Udo/Marc/Loui'))
>>> marc.descendants
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lian/Soe'), Node('/Udo/Marc/Loui'))
>>> lian.descendants
(Node('/Udo/Marc/Lian/Soe'),)
root

Tree Root Node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.root
Node('/Udo')
>>> marc.root
Node('/Udo')
>>> lian.root
Node('/Udo')
siblings

Tuple of nodes with the same parent.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> lazy = Node("Lazy", parent=marc)
>>> udo.siblings
()
>>> marc.siblings
()
>>> lian.siblings
(Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
>>> loui.siblings
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lazy'))
leaves

Tuple of all leaf nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> lazy = Node("Lazy", parent=marc)
>>> udo.leaves
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
>>> marc.leaves
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
is_leaf

Node has no children (External Node).

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.is_leaf
False
>>> marc.is_leaf
False
>>> lian.is_leaf
True
is_root

Node is tree root.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.is_root
True
>>> marc.is_root
False
>>> lian.is_root
False
height

Number of edges on the longest path to a leaf Node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.height
2
>>> marc.height
1
>>> lian.height
0
depth

Number of edges to the root Node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.depth
0
>>> marc.depth
1
>>> lian.depth
2
class anytree.node.symlinknode.SymlinkNode(target, parent=None, children=None, **kwargs)[source]

Bases: anytree.node.symlinknodemixin.SymlinkNodeMixin

Tree node which references to another tree node.

Parameters:

target – Symbolic Link Target. Another tree node, which is refered to.

Keyword Arguments:
 
  • parent – Reference to parent node.
  • children – Iterable with child nodes.
  • * – Any other given attribute is just stored as attribute in target.

The SymlinkNode has its own parent and its own child nodes. All other attribute accesses are just forwarded to the target node.

>>> from anytree import SymlinkNode, Node, RenderTree
>>> root = Node("root")
>>> s1 = Node("sub1", parent=root, bar=17)
>>> l = SymlinkNode(s1, parent=root, baz=18)
>>> l0 = Node("l0", parent=l)
>>> print(RenderTree(root))
Node('/root')
├── Node('/root/sub1', bar=17, baz=18)
└── SymlinkNode(Node('/root/sub1', bar=17, baz=18))
    └── Node('/root/sub1/l0')

Any modifications on the target node are also available on the linked node and vice-versa:

>>> s1.foo = 4
>>> s1.foo
4
>>> l.foo
4
>>> l.foo = 9
>>> s1.foo
9
>>> l.foo
9
class anytree.node.symlinknodemixin.SymlinkNodeMixin[source]

Bases: anytree.node.nodemixin.NodeMixin

The SymlinkNodeMixin class extends any Python class to a symbolic link to a tree node.

The class MUST have a target attribute refering to another tree node. The SymlinkNodeMixin class has its own parent and its own child nodes. All other attribute accesses are just forwarded to the target node. A minimal implementation looks like (see SymlinkNode for a full implemenation):

>>> from anytree import SymlinkNodeMixin, Node, RenderTree
>>> class SymlinkNode(SymlinkNodeMixin):
...     def __init__(self, target, parent=None, children=None):
...         self.target = target
...         self.parent = parent
...         if children:
...             self.children = children
...     def __repr__(self):
...         return "SymlinkNode(%r)" % (self.target)
>>> root = Node("root")
>>> s1 = Node("sub1", parent=root)
>>> l = SymlinkNode(s1, parent=root)
>>> l0 = Node("l0", parent=l)
>>> print(RenderTree(root))
Node('/root')
├── Node('/root/sub1')
└── SymlinkNode(Node('/root/sub1'))
    └── Node('/root/sub1/l0')

Any modifications on the target node are also available on the linked node and vice-versa:

>>> s1.foo = 4
>>> s1.foo
4
>>> l.foo
4
>>> l.foo = 9
>>> s1.foo
9
>>> l.foo
9
exception anytree.node.exceptions.TreeError[source]

Bases: exceptions.RuntimeError

Tree Error.

exception anytree.node.exceptions.LoopError[source]

Bases: anytree.node.exceptions.TreeError

Tree contains infinite loop.