Passed
Push — develop ( c6fa42...950d5f )
by Dean
02:50
created

merge()   B

Complexity

Conditions 5

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 12
cts 12
cp 1
rs 8.5454
cc 5
crap 5
1 1
from datetime import datetime
2 1
import collections
3 1
import hashlib
4 1
import re
5 1
import unicodedata
6
7
8 1
def all(items):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in all.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
9
    for item in items:
10
        if not item:
11
            return False
12
    return True
13
14
15 1
def dict_path(d, path):
16 1
    if not isinstance(path, (list, tuple)):
17 1
        raise ValueError()
18
19 1
    for keys in path:
20 1
        if type(keys) is not list:
21 1
            keys = [keys]
22
23 1
        value = None
24
25 1
        for key in keys:
26 1
            if key not in d:
27 1
                continue
28
29 1
            value = d[key]
30
31 1
        if value is None:
32 1
            value = {}
33
34 1
        for key in keys:
35 1
            d[key] = value
36
37 1
        d = value
38
39 1
    return d
40
41
42 1
def flatten(text):
43 1
    if text is None:
44 1
        return None
45
46
    # Normalize `text` to ascii
47 1
    text = normalize(text)
48
49
    # Remove special characters
50 1
    text = re.sub('[^A-Za-z0-9\s]+', '', text)
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \s was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
51
52
    # Merge duplicate spaces
53 1
    text = ' '.join(text.split())
54
55
    # Convert to lower-case
56 1
    return text.lower()
57
58
59 1
def json_date_serializer(obj):
60 1
    if isinstance(obj, datetime):
61 1
        return obj.strftime('%Y-%m-%dT%H:%M:%S.%f')
62
63
    raise TypeError('Type %r is not serializable', type(obj))
64
65
66 1
def merge(a, b, recursive=False):
67 1
    if not b:
68 1
        return a
69
70 1
    if not recursive:
71 1
        a.update(b)
72 1
        return a
73
74
    # Merge child dictionaries
75 1
    for k, v in b.iteritems():
76 1
        if isinstance(v, collections.Mapping):
77 1
            r = merge(a.get(k, {}), v, recursive=True)
78 1
            a[k] = r
79
        else:
80 1
            a[k] = b[k]
81
82 1
    return a
83
84
85 1
def md5(value):
86
    # Generate MD5 hash of `value`
87
    m = hashlib.md5()
88
    m.update(value)
89
90
    return m.hexdigest()
91
92
93 1
def normalize(text):
94 1
    if text is None:
95 1
        return None
96
97
    # Normalize unicode characters
98 1
    if type(text) is unicode:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'unicode'
Loading history...
99 1
        text = unicodedata.normalize('NFKD', text)
100
101
    # Ensure text is ASCII, ignore unknown characters
102 1
    return text.encode('ascii', 'ignore')
103
104
105 1
def pms_path():
106 1
    file_path = __file__.lower()
107
108 1
    if 'plug-ins' not in file_path:
109 1
        return None
110
111
    return __file__[:file_path.index('plug-ins')]
112
113
114 1
def resolve(value, *args, **kwargs):
115 1
    if hasattr(value, '__call__'):
116 1
        return value(*args, **kwargs)
117
118 1
    return value
119
120
121 1
def to_integer(value):
122 1
    if value is None:
123 1
        return None
124
125 1
    try:
126 1
        return int(value)
127 1
    except:
0 ignored issues
show
Coding Style Best Practice introduced by
General except handlers without types should be used sparingly.

Typically, you would use general except handlers when you intend to specifically handle all types of errors, f.e. when logging. Otherwise, such general error handlers can mask errors in your application that you want to know of.

Loading history...
128 1
        return None
129
130
131 1
def to_tuple(value):
132 1
    if type(value) is tuple:
133 1
        return value
134
135 1
    return value,
136
137
138 1
def try_convert(value, value_type, default=None):
139 1
    try:
140 1
        return value_type(value)
141 1
    except ValueError:
142 1
        return default
143 1
    except TypeError:
144
        return default
145