Source code for treevalue.tree.common.base

from abc import ABCMeta, abstractmethod
from typing import List, Union, Callable, Any

from treevalue.utils import build_tree


[docs]class BaseTree(metaclass=ABCMeta): """ Overview: Base abstract structure of a tree data class. """
[docs] @abstractmethod def __getitem__(self, key): """ Overview: Get item from this tree node, raw value and tree node returns. Arguments: - key (:obj:`str`): Key of the sub tree node. Returns: - return (:obj:`Any`): Tree node or raw value (if the sub node is value node). Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t['a'] # 1 >>> t['x'] # Tree({'c': 3, 'd': 4}) >>> t['x']['c'] # 3 """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def __setitem__(self, key, value): """ Overview: Set item to this tree node, raw value and tree node supported. Arguments: - key (:obj:`str`): Key of the sub tree node. - value (:obj:`Any`): Given mode or value to be set. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t['a'] = 3 >>> t # Tree({'a': 3, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t['x']['e'] = 10 >>> t # Tree({'a': 3, 'b': 2, 'x': {'c': 3, 'd': 4, 'e': 10}}) """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def __delitem__(self, key): """ Overview: Delete item from this tree node. Arguments: - key (:obj:`str`): Key of the sub tree node. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> del t['a'] >>> t # Tree({'b': 2, 'x': {'c': 3, 'd': 4}}) >>> del t['x']['c'] >>> t # Tree({'b': 2, 'x': {'d': 4}}) """ raise NotImplementedError # pragma: no cover
[docs] def json(self): """ Overview: Get full json data of this tree. Returns: - json (:obj:`dict`): Json data Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t.json() # {'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}} """ return { key: value.json() if isinstance(value, BaseTree) else value for key, value in self.items() }
[docs] @abstractmethod def view(self, path: List[str]): """ Overview: Get view of the current tree. Arguments: - path (:obj:`List[str]`): Viewing path. Returns: - viewed_tree (:obj:`TreeView`): Viewed tree. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t1 = t['x'] >>> t2 = t.view(["x"]) >>> >>> t1['c'] # 3 >>> t2['c'] # 3 >>> >>> t.x = Tree({'c': 5, 'd': 6}) >>> t1['c'] # 3 >>> t2['c'] # 5 """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def clone(self, copy_value: Union[None, bool, Callable, Any] = None): """ Overview: Fully clone this tree. Arguments: - copy_value (:obj:`Union[None, bool, Callable, Any]`): Deep copy value or not, \ default is `None` which means do not deep copy the values. \ If deep copy is required, just set it to `True`. Returns: - cloned (:obj:`Tree`): Cloned new tree. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t2 = t.clone() >>> t2 # Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> t2 is t # False >>> t2['x'] is t['x'] # False """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def items(self): """ Overview: Get item iterator of this tree node. Returns: - iter (:obj:`iter`): Item iterator of this tree node. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> for key, value in t.items(): >>> print(key, value) The output should be >>> a 1 >>> b 2 >>> x <Tree 0x7f74f6daaf60 keys: ['c', 'd']> """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def keys(self): """ Overview: Get key iterator of this tree node. Returns: - iter (:obj:`iter`): Key iterator of this tree node. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> for key in t.keys(): >>> print(key) The output should be >>> a >>> b >>> x """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def values(self): """ Overview: Get value iterator of this tree node. Returns: - iter (:obj:`iter`): Value iterator of this tree node. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}}) >>> for value in t.values(): >>> print(value) The output should be >>> 1 >>> 2 >>> <Tree 0x7f74f6daaf60 keys: ['c', 'd']> """ raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def actual(self): """ Overview: Get actual tree node of current tree object. If this is a `Tree` object, just return itself. If this is a `TreeView` object, it will return the actually viewed tree node. Returns: - actual (:obj:`Tree`): Actual tree node. """ raise NotImplementedError # pragma: no cover
def __len__(self): return len(self.keys()) def __bool__(self): return len(self.keys()) > 0
[docs] def __hash__(self): return hash(tuple([(key, value) for key, value in sorted(self.items())]))
[docs] def __eq__(self, other): if other is self: return True elif isinstance(other, BaseTree): if set(self.keys()) == set(other.keys()): for key in self.keys(): if self[key] != other[key]: return False return True else: return False else: return False
[docs] def __repr__(self): return '<{cls} {id} keys: {keys}>'.format( cls=self.__class__.__name__, id=hex(id(self.actual())), keys=repr(sorted(self.keys())) )
[docs] def __str__(self): """ Overview: Return tree-formatted string. Returns: - string (:obj:`str`): Tree-formatted string. Example: >>> t = Tree({'a': 1, 'b': 2, 'x': {'c': 3, 'd': 4}, 'z': [1, 2], 'v': raw({'1': '2'})}) >>> print(t) The output will be >>> <Tree 0x7f9fa48b9588 keys: ['a', 'b', 'v', 'x', 'z']> >>> ├── 'a' --> 1 >>> ├── 'b' --> 2 >>> ├── 'v' --> {'1': '2'} >>> ├── 'x' --> <Tree 0x7f9fa48b95c0 keys: ['c', 'd']> >>> │ ├── 'c' --> 3 >>> │ └── 'd' --> 4 >>> └── 'z' --> [1, 2] """ return str(build_tree( self, represent=lambda value: repr(value), iterate=lambda value: value.items(), recurse=lambda value: isinstance(value, BaseTree), ))