Completed
Push — master ( a11b7e...3fb325 )
by Tom
8s
created

ppp_datamodel.utils.AttributesHolder   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 88.64%
Metric Value
dl 0
loc 67
ccs 39
cts 44
cp 0.8864
rs 10
wmc 21

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __hash__() 0 2 1
A __repr__() 0 3 2
A _parse_attributes() 0 2 1
A __ne__() 0 2 1
A __init__() 0 4 1
A has() 0 3 1
A __delattr__() 0 6 2
A __setattr__() 0 6 2
B get() 0 11 6
A _check_attributes() 0 8 2
A __eq__() 0 6 2
1 1
from .. import exceptions
2 1
from ..log import logger
3
4 1
class AttributesHolder(object):
5
    """Stores attributes and provides read-only access to them."""
6 1
    __slots__ = ('_attributes')
7 1
    _possible_attributes = None
8 1
    def __init__(self, *args, **attributes):
9 1
        attributes.update(dict(zip(self._possible_attributes, args)))
10 1
        self._check_attributes(attributes)
11 1
        self._parse_attributes(attributes)
12
13 1
    def _check_attributes(self, attributes, extra=None):
14
        """Check if attributes given to the constructor can be used to
15
        instanciate a valid node."""
16 1
        extra = extra or ()
17 1
        unknown_keys = set(attributes) - set(self._possible_attributes) - set(extra)
18 1
        if unknown_keys:
19 1
            logger.warning('%s got unknown attributes: %s' %
20
                            (self.__class__.__name__, unknown_keys))
21
22 1
    def __repr__(self):
23
        return '<%s %r>' % (self.__class__.__name__,
24
                {x:y for (x,y) in self._attributes.items()})
25
26 1
    def _parse_attributes(self, attributes):
27 1
        self._attributes = attributes
28
29 1
    def __eq__(self, other):
30
        """Tests equality with another AttributesHolder instance."""
31 1
        if isinstance(other, AttributesHolder):
32 1
            return self._attributes == other._attributes
33
        else:
34
            return False
35 1
    def __ne__(self, other):
36 1
        return not (self == other)
37
38 1
    def __hash__(self):
39
        return hash(frozenset(self._attributes.items()))
40
41 1
    def get(self, name, strict=True):
42
        """Get an attribute of the holder (read-only access)."""
43 1
        if not isinstance(name, str) or name.startswith('_'):
44
            raise AttributeError(self.__class__.__name__, name)
45 1
        elif strict and name not in self._possible_attributes:
46 1
            raise AttributeError('%s is not a valid attribute of %r.' %
47
                                 (name, self))
48 1
        elif name in self._attributes:
49 1
            return self._attributes[name]
50
        else:
51 1
            raise exceptions.AttributeNotProvided(name)
52 1
    __getattr__ = __getitem__ = get
53
54 1
    def __setattr__(self, name, value):
55 1
        if name.startswith('_'):
56 1
            super(AttributesHolder, self).__setattr__(name, value)
57
        else:
58 1
            raise TypeError('%s\'s attributes are not settable.' %
59
                    self.__class__.__name__)
60 1
    def __delattr__(self, name):
61 1
        if name.startswith('_'):
62
            super(AttributesHolder, self).__delattr__(name, value)
63
        else:
64 1
            raise TypeError('%s\'s attributes are not settable.' %
65
                    self.__class__.__name__)
66
67 1
    def has(self, name):
68
        """Check existence of an attribute."""
69 1
        return name in self._attributes
70 1
    __hasattr__ = __contains__ = has
71
72