configtree.tree

class configtree.tree.ITree

Abstract base class for Tree and BranchProxy.

Useful for type checking:

>>> tree = Tree({'x.y': 1})
>>> tree
Tree({'x.y': 1})
>>> isinstance(tree, ITree)
True
>>> tree['x']
BranchProxy('x'): {'y': 1}
>>> isinstance(tree, ITree)
True
class configtree.tree.Tree(data=None)

Tree is a dictionary like object, which supports nested keys.

Examples:

>>> tree = Tree()
>>> tree['a.b.c'] = 1
>>> tree['a'] == {'b.c': 1}
True
>>> tree['a.b'] == {'c': 1}
True
>>> tree['a']['b'] == {'c': 1}
True
>>> tree['a.b']['d'] = 2
>>> tree['a.b'] == {'c': 1, 'd': 2}
True

The tree object is unable to create an empty branch on demand:

>>> branch = tree['x.y']                        # DOCTEST: +ellipsis
Traceback (most recent call last):
...
KeyError: 'x.y'

Use branch() for this purposes. It explicitly creates a BranchProxy object tied to the specified key:

>>> branch = tree.branch('x.y')
>>> branch['z'] = 3
>>> tree == {'a.b.c': 1, 'a.b.d': 2, 'x.y.z': 3}
True

An empty branch automatically collapses from the Tree:

>>> del branch['z']
>>> 'x.y' in tree
False

The tree object doesn’t perform any implicit type inspection and conversion. It means what you put into the tree is what you will get from one later. Even when you put one branch to another, the Tree won’t create a copy:

>>> tree['x'] = tree['a']
>>> tree['x.b.c']                               # DOCTEST: +ellipsis
Traceback (most recent call last):
...
KeyError: 'x.b.c'
>>> tree['x']['b.c']
1
>>> tree['x']['b.c'] = 3
>>> tree['a.b.c']
3

It’s a road to debug hell, don’t follow it. If you want to copy a branch, use update() method.

>>> tree = Tree({'a.b.c': 1})
>>> tree.branch('x').update(tree['a'])
>>> tree == {'a.b.c': 1, 'x.b.c': 1}
True
>>> tree['x.b.c'] = 3
>>> tree == {'a.b.c': 1, 'x.b.c': 3}
True

The tree object provides complete collections.abc.MutableMapping interface. So that it can be used where built-in dict is expected. Additionally, the following methods are available that extend class functionality.

branch(key)

Returns a BranchProxy object for specified key

rare_keys()

Returns an iterator over the first level keys.

>>> tree = Tree({'a.b.c': 1, 'k': 2, 'x.y.z': 3})
>>> sorted(list(tree.rare_keys())) == ['a', 'k', 'x']
True
rare_values()

Returns an iterator over the first level values.

See rare_keys().

rare_items()

Returns an iterator over the first level items.

See rare_keys()

copy()

Returns a shallow copy of the tree. The result has the same type.

rare_copy()

Returns a rarefied copy of the tree.

>>> tree = Tree({'x.y.z': 1})
>>> tree.rare_copy()
{'x': {'y': {'z': 1}}}
class configtree.tree.BranchProxy(key, owner)

Branch Proxy is a helper object. This kind of object is created on demand when you expose an intermediate key of the Tree object:

>>> tree = Tree({'a.b.c': 1})
>>> branch = tree['a.b']
>>> isinstance(branch, BranchProxy)
True

The class methods are similar to Tree ones. Each method is just proxied to corresponding owner’s one.

copy()

Returns a shallow copy of the branch. The result has the same type as the branch owner, i.e. Tree or derrived from one.

configtree.tree.flatten(d)

Generator which flattens out passed nested mapping objects.

It’s useful in combination with Tree constructor or Tree.update():

>>> nested = {'a': {'b': {'c': 1}}}
>>> Tree(nested)                        # without flatten
Tree({'a': {'b': {'c': 1}}})
>>> Tree(flatten(nested))               # with flatten
Tree({'a.b.c': 1})
configtree.tree.rarefy(tree)

Converts passed flatten mapping object into a nested dictionary.

It works oppositely to flatten().

>>> rarefy(Tree({'a.b.c' : 1}))
{'a': {'b': {'c': 1}}}
>>> rarefy({'a.b.c' : 1})
{'a': {'b': {'c': 1}}}