BooleanResource   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 16
Duplicated Lines 0 %

Test Coverage

Coverage 72.72%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 16
ccs 8
cts 11
cp 0.7272
rs 10
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A _parse_value() 0 9 3
A _format_value() 0 3 2
1
"""Contains the class representing a resource leaf."""
2
3 1
import sys
4 1
from ..log import logger
5 1
from .abstractnode import register, AbstractNode
6
7 1
__all__ = ['Resource', 'StringResource', 'MathLatexResource',
8
           'BooleanResource', 'TimeResource',
9
           'JsonldResource']
10
11 1
if sys.version_info[0] >= 3:
12 1
    basestring = str
13
14 1
EXTRA_ATTRIBUTES = {
15
        'string': ('language',),
16
        'boolean': (),
17
        'time': ('calendar',),
18
        }
19
20 1
VALUE_TYPE_TO_CLASS = {}
21 1
def register_valuetype(cls):
22 1
    VALUE_TYPE_TO_CLASS[cls._value_type] = cls
23 1
    return cls
24
25
26 1
@register
27 1
@register_valuetype
28 1
class Resource(AbstractNode):
29
    """Represents a resource.
30
    https://github.com/ProjetPP/Documentation/blob/master/data-model.md#resource
31
    """
32 1
    __slots__ = ()
33 1
    _type = 'resource'
34 1
    _value_type = 'unknown'
35 1
    _possible_attributes = ('value', 'value_type')
36
37 1
    @classmethod
38
    def _select_class(cls, data):
39 1
        type_ = data.get('value-type', 'string')
40 1
        if type_ not in VALUE_TYPE_TO_CLASS:
41 1
            logger.warning('Unknown value-type: %s' % type_)
42 1
            type_ = 'string'
43 1
        return VALUE_TYPE_TO_CLASS[type_]
44
45 1
    def _check_attributes(self, attributes):
46 1
        super(Resource, self)._check_attributes(attributes)
47 1
        if not isinstance(attributes['value'], basestring):
48 1
            raise TypeError('%s\'s value must be a string, not %r.' %
49
                    (self.__class__.__name__, attributes['value']))
50
51 1
    def _parse_attributes(self, attributes):
52 1
        attributes['value'] = self._parse_value(attributes.get('value', None),
53
                                                attributes)
54 1
        super(Resource, self)._parse_attributes(attributes)
55
56 1
    @staticmethod
57
    def _parse_value(value, attributes):
58 1
        return value
59
60 1
    @staticmethod
61
    def _format_value(value):
62 1
        return value
63
64 1
    def as_dict(self):
65 1
        d = super(Resource, self).as_dict()
66 1
        type_ = d.get('value-type', self._value_type)
67 1
        value = d.get('value')
68 1
        d['value'] = self._format_value(value)
69 1
        if type_ not in ('string', 'unknown') or 'value-type' in d:
70 1
            d['value-type'] = type_
71 1
        return d
72
73 1
@register_valuetype
74 1
class StringResource(Resource):
75 1
    _value_type = 'string'
76 1
    _possible_attributes = Resource._possible_attributes + ('language',)
77
78 1
@register_valuetype
79 1
class MathLatexResource(Resource):
80 1
    _value_type = 'math-latex'
81 1
    _possible_attributes = Resource._possible_attributes + ('latex',)
82
83 1
@register_valuetype
84 1
class BooleanResource(Resource):
85 1
    _value_type = 'boolean'
86
87 1
    @staticmethod
88
    def _parse_value(value, attributes):
89 1
        if value in ('1', 'true'):
90 1
            return True
91
        elif value in ('0', 'false'):
92
            return False
93
        else:
94
            raise ValueError('Could not parse value %r of value-type %s'%
95
                             (value, type_))
96 1
    @staticmethod
97
    def _format_value(value):
98 1
        return 'true' if value else 'false'
99
100 1
@register_valuetype
101 1
class TimeResource(Resource):
102 1
    _value_type = 'time'
103 1
    _possible_attributes = Resource._possible_attributes + ('calendar',)
104
105 1
    @staticmethod
106
    def _parse_value(value, attributes):
107 1
        return value
108
109 1
    @staticmethod
110
    def _format_value(value):
111
        return value
112
113 1
def freeze_dicts(d):
114
    if isinstance(d, dict):
115
        return frozenset(map(lambda x:(x[0], freeze_dicts(x[1])), d.items()))
116
    elif isinstance(d, list):
117
        return tuple(map(freeze_dicts, d))
118
    else:
119
        return d
120
121 1
@register_valuetype
122 1
class JsonldResource(Resource):
123 1
    _value_type = 'resource-jsonld'
124 1
    _possible_attributes = Resource._possible_attributes + ('graph',)
125
126 1
    @classmethod
127
    def deserialize_attribute(cls, key, value):
128 1
        if key == 'graph':
129 1
            return value
130
        else:
131
            super(JsonldResource, self).deserialize_attribute(key, value)
132
133 1
    def __hash__(self):
134 1
        raise TypeError('%s instances are not hashable.' % self.__class__)
135
136 1
    def get_uris(self):
137 1
        uris = set()
138 1
        if '@id' in self.graph:
139
            uris.add(self.graph['@id'])
140 1
        same_as = self.graph.get('sameAs', [])
141 1
        if isinstance(same_as, str):
142 1
            same_as = [same_as]
143 1
        assert isinstance(same_as, list)
144 1
        uris.update(same_as)
145 1
        return uris
146
147 1
    def __eq__(self, other):
148 1
        if not isinstance(other, JsonldResource):
149
            return False
150 1
        return self.graph == other.graph or \
151
                bool(self.get_uris() & other.get_uris())
152