Passed
Push — master ( db2481...3bd527 )
by Fabio
03:28
created

benedict.dicts.parse.parse_dict   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 222
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 30
eloc 95
dl 0
loc 222
rs 10
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A ParseDict.get_list() 0 8 1
A ParseDict.__init__() 0 5 1
A ParseDict.get_str_list() 0 7 1
A ParseDict.get_datetime_list() 0 8 1
A ParseDict.get_datetime() 0 9 1
A ParseDict.get_slug() 0 7 1
A ParseDict.get_int() 0 7 1
A ParseDict.get_decimal() 0 7 1
A ParseDict._get_values_list() 0 11 2
A ParseDict.get_float() 0 7 1
A ParseDict.get_float_list() 0 7 1
A ParseDict.get_decimal_list() 0 7 1
A ParseDict.get_phonenumber() 0 8 1
A ParseDict.get_bool() 0 7 1
A ParseDict.get_bool_list() 0 7 1
A ParseDict.get_email() 0 9 1
A ParseDict.get_dict() 0 7 1
A ParseDict.get_list_item() 0 14 3
A ParseDict.get_str() 0 8 1
A ParseDict.get_int_list() 0 7 1
A ParseDict.get_slug_list() 0 7 1
B ParseDict._get_value() 0 26 6
1
# -*- coding: utf-8 -*-
2
3
from benedict.dicts.parse import parse_util
4
from benedict.utils import type_util
5
6
from decimal import Decimal
7
8
9
class ParseDict(dict):
10
11
    def __init__(self, *args, **kwargs):
12
        """
13
        Constructs a new instance.
14
        """
15
        super(ParseDict, self).__init__(*args, **kwargs)
16
17
    def _get_value(self, key, default, choices,
18
                   parser_func, parser_kwargs=None):
19
        """
20
        Get value by key, or keypath core method.
21
        If choices and value is in choices return value otherwise default.
22
        """
23
24
        # Get raw value from self.
25
        value = self.get(key, None)
26
        # If value is None return default value.
27
        if value is None:
28
            return default
29
30
        # If not of the desired type, try to parse it using parser_func.
31
        value = parser_func(value, **(parser_kwargs or {}))
32
        # If value is None after parsing return default value.
33
        if value is None:
34
            return default
35
36
        # If choices and value in choices return value otherwise default.
37
        if type_util.is_list_or_tuple(choices) and len(choices):
38
            if value in choices:
39
                return value
40
            return default
41
42
        return value
43
44
    def _get_values_list(self, key, default, separator,
45
                         parser_func, parser_kwargs=None):
46
        """
47
        Get value by key or keypath trying to return it as list of bool values.
48
        If separator is specified and value is a string it will be splitted.
49
        """
50
        if key not in self:
51
            return default or []
52
        values_list = self.get_list(key, [], separator)
53
        return [parser_func(value, **(parser_kwargs or {}))
54
                for value in values_list]
55
56
    def get_bool(self, key, default=False):
57
        """
58
        Get value by key or keypath trying to return it as bool.
59
        Values like `1`, `true`, `yes`, `on` will be returned as `True`.
60
        """
61
        return self._get_value(
62
            key, default, [True, False], parse_util.parse_bool)
63
64
    def get_bool_list(self, key, default=None, separator=','):
65
        """
66
        Get value by key or keypath trying to return it as list of bool values.
67
        If separator is specified and value is a string it will be splitted.
68
        """
69
        return self._get_values_list(
70
            key, default, separator, parse_util.parse_bool)
71
72
    def get_datetime(self, key, default=None, format=None, choices=None):
73
        """
74
        Get value by key or keypath trying to return it as datetime.
75
        If format is not specified it will be autodetected.
76
        If choices and value is in choices return value otherwise default.
77
        """
78
        return self._get_value(
79
            key, default, choices, parse_util.parse_datetime,
80
            {'format': format})
81
82
    def get_datetime_list(self, key, default=None, format=None, separator=','):
83
        """
84
        Get value by key or keypath trying to return it as list of datetime values.
85
        If separator is specified and value is a string it will be splitted.
86
        """
87
        return self._get_values_list(
88
            key, default, separator, parse_util.parse_datetime,
89
            {'format': format})
90
91
    def get_decimal(self, key, default=Decimal('0.0'), choices=None):
92
        """
93
        Get value by key or keypath trying to return it as Decimal.
94
        If choices and value is in choices return value otherwise default.
95
        """
96
        return self._get_value(
97
            key, default, choices, parse_util.parse_decimal)
98
99
    def get_decimal_list(self, key, default=None, separator=','):
100
        """
101
        Get value by key or keypath trying to return it as list of Decimal values.
102
        If separator is specified and value is a string it will be splitted.
103
        """
104
        return self._get_values_list(
105
            key, default, separator, parse_util.parse_decimal)
106
107
    def get_dict(self, key, default=None):
108
        """
109
        Get value by key or keypath trying to return it as dict.
110
        If value is a json string it will be automatically decoded.
111
        """
112
        return self._get_value(
113
            key, default or {}, None, parse_util.parse_dict)
114
115
    def get_email(self, key, default='', choices=None, check_blacklist=True):
116
        """
117
        Get email by key or keypath and return it.
118
        If value is blacklisted it will be automatically ignored.
119
        If check_blacklist is False, it will be not ignored even if blacklisted.
120
        """
121
        return self._get_value(
122
            key, default, choices, parse_util.parse_email,
123
            {'check_blacklist': check_blacklist})
124
125
    def get_float(self, key, default=0.0, choices=None):
126
        """
127
        Get value by key or keypath trying to return it as float.
128
        If choices and value is in choices return value otherwise default.
129
        """
130
        return self._get_value(
131
            key, default, choices, parse_util.parse_float)
132
133
    def get_float_list(self, key, default=None, separator=','):
134
        """
135
        Get value by key or keypath trying to return it as list of float values.
136
        If separator is specified and value is a string it will be splitted.
137
        """
138
        return self._get_values_list(
139
            key, default, separator, parse_util.parse_float)
140
141
    def get_int(self, key, default=0, choices=None):
142
        """
143
        Get value by key or keypath trying to return it as int.
144
        If choices and value is in choices return value otherwise default.
145
        """
146
        return self._get_value(
147
            key, default, choices, parse_util.parse_int)
148
149
    def get_int_list(self, key, default=None, separator=','):
150
        """
151
        Get value by key or keypath trying to return it as list of int values.
152
        If separator is specified and value is a string it will be splitted.
153
        """
154
        return self._get_values_list(
155
            key, default, separator, parse_util.parse_int)
156
157
    def get_list(self, key, default=None, separator=','):
158
        """
159
        Get value by key or keypath trying to return it as list.
160
        If separator is specified and value is a string it will be splitted.
161
        """
162
        return self._get_value(
163
            key, default or [], None, parse_util.parse_list,
164
            {'separator': separator})
165
166
    def get_list_item(self, key, index=0, default=None, separator=','):
167
        """
168
        Get list by key or keypath and return value at the specified index.
169
        If separator is specified and list value is a string it will be splitted.
170
        """
171
        values = self.get_list(key, None, separator)
172
        if values:
173
            try:
174
                value = values[index]
175
                return value
176
            except IndexError:
177
                return default
178
        else:
179
            return default
180
181
    def get_phonenumber(self, key, country_code=None, default=None):
182
        """
183
        Get phonenumber by key or keypath and return a dict with different formats (e164, international, national).
184
        If country code is specified (alpha 2 code), it will be used to parse phone number correctly.
185
        """
186
        return self._get_value(
187
            key, default or {}, None, parse_util.parse_phonenumber,
188
            {'country_code': country_code})
189
190
    def get_slug(self, key, default='', choices=None):
191
        """
192
        Get value by key or keypath trying to return it as slug.
193
        If choices and value is in choices return value otherwise default.
194
        """
195
        return self._get_value(
196
            key, default, choices, parse_util.parse_slug)
197
198
    def get_slug_list(self, key, default=None, separator=','):
199
        """
200
        Get value by key or keypath trying to return it as list of slug values.
201
        If separator is specified and value is a string it will be splitted.
202
        """
203
        return self._get_values_list(
204
            key, default, separator, parse_util.parse_slug)
205
206
    def get_str(self, key, default='', choices=None):
207
        """
208
        Get value by key or keypath trying to return it as string.
209
        Encoding issues will be automatically fixed.
210
        If choices and value is in choices return value otherwise default.
211
        """
212
        return self._get_value(
213
            key, default, choices, parse_util.parse_str)
214
215
    def get_str_list(self, key, default=None, separator=','):
216
        """
217
        Get value by key or keypath trying to return it as list of str values.
218
        If separator is specified and value is a string it will be splitted.
219
        """
220
        return self._get_values_list(
221
            key, default, separator, parse_util.parse_str)
222