Passed
Push — master ( 929d80...68a360 )
by Fabio
04:07
created

benedict.dicts.utility   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 28
eloc 54
dl 0
loc 71
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A UtilityDict.dump() 0 7 2
A UtilityDict.cast() 0 6 3
A UtilityDict.deepcopy() 0 2 1
C UtilityDict.clean() 0 10 10
A UtilityDict.__init__() 0 2 1
A UtilityDict.dump_items() 0 2 2
A UtilityDict.filter() 0 10 4
A UtilityDict.subset() 0 5 2
A UtilityDict.remove() 0 6 3
1
# -*- coding: utf-8 -*-
2
3
from six import string_types
4
5
import copy
6
import json
7
8
9
class UtilityDict(dict):
10
11
    def __init__(self, *args, **kwargs):
12
        super(UtilityDict, self).__init__(*args, **kwargs)
13
14
    @classmethod
15
    def cast(cls, value):
16
        if isinstance(value, dict) and not isinstance(value, cls):
17
            return cls(value)
18
        else:
19
            return None
20
21
    def clean(self, strings=True, dicts=True, lists=True):
22
        keys = list(self.keys())
23
        for key in keys:
24
            value = self.get(key, None)
25
            if not value:
26
                if value is None or \
27
                        strings and isinstance(value, string_types) or \
28
                        dicts and isinstance(value, dict) or \
29
                        lists and isinstance(value, (list, tuple, )):
30
                    del self[key]
31
32
    def deepcopy(self):
33
        return copy.deepcopy(self)
34
35
    @staticmethod
36
    def dump(data):
37
        def encoder(obj):
38
            json_types = (bool, dict, float, int, list, tuple, ) + string_types
39
            if not isinstance(obj, json_types):
40
                return str(obj)
41
        return json.dumps(data, indent=4, sort_keys=True, default=encoder)
42
43
    def dump_items(self, key=None):
44
        return self.dump(self.get(key) if key else self)
45
46
    def filter(self, predicate):
47
        if not callable(predicate):
48
            raise ValueError('predicate argument must be a callable.')
49
        d = {}
50
        keys = self.keys()
51
        for key in keys:
52
            val = self.get(key, None)
53
            if predicate(key, val):
54
                d[key] = val
55
        return d
56
57
    def remove(self, keys):
58
        for key in keys:
59
            try:
60
                del self[key]
61
            except KeyError:
62
                continue
63
            # print('REMOVE', key)
64
            # self.pop(key, 1)
65
66
    def subset(self, keys):
67
        d = self.__class__()
68
        for key in keys:
69
            d[key] = self.get(key, None)
70
        return d
71