Completed
Push — master ( 4c11f7...bc6698 )
by Oleksandr
01:42
created

ParsableEvent   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 28
Duplicated Lines 0 %

Test Coverage

Coverage 41.67%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 5
c 1
b 0
f 0
dl 0
loc 28
ccs 5
cts 12
cp 0.4167
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A transform() 0 6 2
A from_s() 0 7 2
A matcher() 0 6 1
1
# coding: utf-8
2
3 1
import abc
4
5 1
import six
6
7
8 1
class BaseStructure(object):
9 1
    __slots__ = []
10
11 1
    def __eq__(self, other):
12 1
        if not isinstance(other, self.__class__):
13 1
            return NotImplemented
14
15 1
        if self.__class__ != other.__class__:
16
            return False
17
18 1
        return all([
19
            getattr(self, x) == getattr(other, x)
20
            for x in self.__slots__
21
        ])
22
23 1
    def __ne__(self, other):
24 1
        return not (self == other)
25
26 1
    def __hash__(self):
27 1
        return hash(tuple(
28
            getattr(self, x) for x in self.__slots__
29
        ))
30
31 1
    def to_primitive(self, context=None):
32 1
        fields = ((key, getattr(self, key)) for key in self.__slots__)
33 1
        return {
34
            key: self._to_primitive(value, context)
35
            for key, value in fields
36
        }
37
38 1
    @staticmethod
39
    def _to_primitive(instance, context):
40 1
        if hasattr(instance, 'to_primitive'):
41 1
            return instance.to_primitive(context)
42 1
        elif hasattr(instance, 'isoformat'):
43 1
            return instance.isoformat()
44
        else:
45 1
            return instance
46
47
48 1
class Event(six.with_metaclass(abc.ABCMeta, BaseStructure)):
49
    """
50
    Base event structure.
51
52
    """
53
54 1
    def __init__(self, **kwargs):
55
        for key in self.__slots__:
56
            setattr(self, key, kwargs[key])
57
58
        super(Event, self).__init__()
59
60 1
    @property
61
    def name(self):
62
        return self.__class__.__name__
63
64 1
    @abc.abstractproperty
65
    def verbose_name(self):
66
        """
67
        Human-readable name of event.
68
69
        """
70
71 1
    def to_primitive(self, context=None):
72
        primitive = super(Event, self).to_primitive(context)
73
        primitive.update({
74
            'name': self.name,
75
            'verbose_name': six.text_type(self.verbose_name),
76
        })
77
        return primitive
78
79
    def __repr__(self):
80
        return "<Event {0} {1}>".format(self.name, self.to_primitive())
81
82
83 1
class ParsableEvent(Event):
84
    """
85
    Base event which can be parsed from string.
86
87
    """
88 1
    transformers = tuple()
89
90 1
    @classmethod
91
    def transform(cls, data):
92
        for transformer in cls.transformers:
93
            transformer(data)
94
95
        return data
96
97 1
    @abc.abstractproperty
98
    def matcher(self):
99
        """
100
        A callable for matching strings.
101
102
        """
103
104 1
    @classmethod
105
    def from_s(cls, s):
106
        match = cls.matcher(s)
107
108
        if match:
109
            data = cls.transform(match.groupdict())
110
            return cls(**data)
111