Completed
Push — master ( 9ea16f...a11b7e )
by Thomas
8s
created

ppp_datamodel.nodes.AbstractNode.wrapper()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6
Metric Value
cc 2
dl 0
loc 5
ccs 0
cts 0
cp 0
crap 6
rs 9.4285
1
"""Contains the base class for PPP nodes."""
2
3 1
from ..utils.typedattributesholder import TypedAttributesHolder
4 1
from ..utils.serializableattributesholder import SerializableAttributesHolder
5 1
from ..log import logger
6 1
from .. import exceptions
7
8 1
class SerializableTypedAttributesHolder(SerializableAttributesHolder, TypedAttributesHolder):
9
10 1
    @staticmethod
11
    def _test_can_import_json(data):
12
        """Sanity check on input JSON data"""
13 1
        if 'type' not in data:
14 1
            raise exceptions.AttributeNotProvided('type')
15 1
        if data['type'] not in TYPE_TO_CLASS:
16 1
            raise exceptions.UnknownNodeType(data['type'])
17
18 1
    @classmethod
19
    def _select_class(cls, data):
20 1
        return TYPE_TO_CLASS[data['type']]
21
22 1
    def __eq__(self, other):
23 1
        if isinstance(other, dict):
24
            return self == SerializableTypedAttributesHolder.from_dict(other)
25 1
        else:
26 1
            return super(SerializableTypedAttributesHolder, self).__eq__(other)
27 1
28
    def __hash__(self):
29 1
        return super(SerializableTypedAttributesHolder, self).__hash__()
30
31
TYPE_TO_CLASS = {}
32 1
def register(cls):
33
    """Register a class to make it available to the deserializer."""
34
    assert cls._type
35 1
    TYPE_TO_CLASS[cls._type] = cls
36
    return cls
37 1
38
class AbstractNode(SerializableTypedAttributesHolder):
39 1
    """SerializableAttributesHolder with methods for making operations
40 1
    on trees."""
41 1
    def fold(self, predicate):
42 1
        """Takes a predicate and applies it to each node starting from the
43
        leaves and making the return value propagate."""
44 1
        childs = {x:y.fold(predicate) for (x,y) in self._attributes.items()
45 1
                  if isinstance(y, SerializableTypedAttributesHolder)}
46
        return predicate(self, childs)
47
48 1
    def traverse(self, predicate):
49
        def wrapper(tree):
50
            if isinstance(tree, SerializableTypedAttributesHolder):
51
                return tree.traverse(predicate)
52
            else:
53
                return tree
54
        arguments = {x: wrapper(y)
55
                     for (x, y) in self._attributes.items()
56
                     if x != 'type'}
57
        return predicate(self.__class__(**arguments))
58