Failed Conditions
Branch Makman2/conf-parser-auto-trim (6dfaa8)
by Mischa
01:32
created

coalib.misc.StringConverter.__prepare_list()   C

Complexity

Conditions 8

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 8
dl 0
loc 17
rs 6.6667
1
from collections import Iterable, OrderedDict
2
import re
3
from coalib.misc.Constants import Constants
4
from coalib.parsing.StringProcessing import unescaped_split, unescape
5
6
7
class StringConverter:
8
    """
9
    Converts strings to other things as needed. If you need some kind of string
10
    conversion that is not implemented here, consider adding it so everyone
11
    gets something out of it.
12
    """
13
14
    def __init__(self,
15
                 value,
16
                 strip_whitespaces=True,
17
                 list_delimiters=None,
18
                 dict_delimiter=":",
19
                 remove_empty_iter_elements=True):
20
        if list_delimiters is None:
21
            list_delimiters = [",", ";"]
22
23
        if not isinstance(list_delimiters, Iterable):
24
            raise TypeError("list_delimiters has to be an Iterable.")
25
        if not isinstance(strip_whitespaces, bool):
26
            raise TypeError("strip_whitespaces has to be a bool parameter")
27
28
        self.__strip_whitespaces = strip_whitespaces
29
        self.__list_delimiters = list_delimiters
30
        self.__dict_delimiter = dict_delimiter
31
        self.__remove_empty_iter_elements = remove_empty_iter_elements
32
33
        self.__escaped_list = None
34
        self.__unescaped_list = None
35
        self.__dict = None
36
        self.value = value
37
38
    def __str__(self):
39
        return unescape(self.value)
40
41
    def __bool__(self):
42
        if str(self).lower() in Constants.TRUE_STRINGS:
43
            return True
44
        if str(self).lower() in Constants.FALSE_STRINGS:
45
            return False
46
        raise ValueError
47
48
    def __len__(self):
49
        return len(str(self))
50
51
    def __int__(self):
52
        return int(str(self))
53
54
    def __float__(self):
55
        return float(str(self))
56
57
    def __iter__(self, remove_backslashes=True):
58
        """
59
        Converts the value to a list using the delimiters given at construction
60
        time.
61
62
        Note that escaped values will be unescaped and escaped list delimiters
63
        will be allowed in values. If you need the escapes you should not
64
        use this routine.
65
66
        :param remove_backslashes: Whether or not to remove the backslashes
67
                                   after conversion.
68
        :return:                   An iterator over all values.
69
        """
70
        if remove_backslashes:
71
            return iter(self.__unescaped_list)
72
        else:
73
            return iter(self.__escaped_list)
74
75
    def __getitem__(self, item):
76
        return self.__dict.__getitem__(item)
77
78
    def keys(self):
79
        return self.__dict.keys()
80
81
    def __get_raw_list(self):
82
        pattern = ("(?:" +
83
                   "|".join(re.escape(v) for v in self.__list_delimiters) +
84
                   ")")
85
86
        return list(unescaped_split(pattern,
87
                                    self.value,
88
                                    use_regex=True))
89
90
    def __prepare_list(self):
91
        self.__escaped_list = self.__get_raw_list()
92
        self.__unescaped_list = [unescape(elem)
93
                                 for elem in self.__escaped_list]
94
        if self.__strip_whitespaces:
95
            self.__unescaped_list = [elem.strip()
96
                                     for elem in self.__unescaped_list]
97
            self.__escaped_list = [elem.strip()
98
                                   for elem in self.__escaped_list]
99
100
        if self.__remove_empty_iter_elements:
101
            # Need to do after stripping, cant use builtin functionality of
102
            # split.
103
            while "" in self.__unescaped_list:
104
                self.__unescaped_list.remove("")
105
            while "" in self.__escaped_list:
106
                self.__escaped_list.remove("")
107
108
    def __prepare_dict(self):
109
        # We must keep order here, user can drop it later.
110
        self.__dict = OrderedDict()
111
        for elem in self.__get_raw_list():
112
            key_val = [unescape(item)
113
                       for item in unescaped_split(self.__dict_delimiter,
114
                                                   elem,
115
                                                   max_split=1)]
116
117
            if self.__strip_whitespaces:
118
                key_val = [item.strip() for item in key_val]
119
120
            if not any(item != "" for item in key_val):
121
                continue
122
123
            if len(key_val) < 2:
124
                self.__dict[key_val[0]] = ""
125
            else:
126
                self.__dict[key_val[0]] = key_val[1]
127
128
    @property
129
    def value(self):
130
        return self.__value
131
132
    @value.setter
133
    def value(self, newval):
134
        self.__value = str(newval)
135
        if self.__strip_whitespaces:
136
            self.__value = self.__value.strip()
137
138
        self.__prepare_list()
139
        self.__prepare_dict()
140
141
    def __eq__(self, other):
142
        return isinstance(other, StringConverter) and self.value == other.value
143
144
    def __ne__(self, other):
145
        return not self.__eq__(other)
146