Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: chainedconfigparser.py

Issue 29743581: Issue 6552 - Support arbitrary manifest values (Closed) Base URL: https://hg.adblockplus.org/buildtools/file/a3db4a1a49e8
Left Patch Set: Created April 18, 2018, 2:41 p.m.
Right Patch Set: Created April 19, 2018, 11:42 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | packagerChrome.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import os 5 import os
6 import io 6 import io
7 import ConfigParser 7 import ConfigParser
8 from StringIO import StringIO 8 from StringIO import StringIO
9 9
10 10
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 150
151 def option_source(self, section, option): 151 def option_source(self, section, option):
152 option = self.optionxform(option) 152 option = self.optionxform(option)
153 try: 153 try:
154 return self._origin[(section, option)] 154 return self._origin[(section, option)]
155 except KeyError: 155 except KeyError:
156 if not self.has_section(section): 156 if not self.has_section(section):
157 raise ConfigParser.NoSectionError(section) 157 raise ConfigParser.NoSectionError(section)
158 raise ConfigParser.NoOptionError(option, section) 158 raise ConfigParser.NoOptionError(option, section)
159 159
160 def section_as_dict(self, section, additional={}): 160 def serialize_section_if_present(self, section, base):
Vasily Kuznetsov 2018/04/19 14:40:10 What this method does seems more like parsing than
Sebastian Noack 2018/04/19 15:02:59 In the end it gets serialized (as JSON). But you m
161 """Parse a given section into a dictionary. 161 """Serialize a given section as a dictionary into `base`.
162 162
163 Parse arbitrary key/value pairs from 'section' of the current 163 Parse arbitrary key/value pairs from 'section' of the current
164 configuration into a dictionary and merge it with the optional 164 configuration into a dictionary and deep merge it into `base`.
165 parameter `additional`.
166 165
167 The following rules need to be considered: 166 The following rules need to be considered:
168 167
169 * An option's key may be declared as a series of nested dictionary keys, 168 * An option's key may be declared as a series of nested dictionary keys,
170 seperated by '.'. 169 seperated by '.'.
171 * Declaring an option's value in a new line (even if only one is given) 170 * Declaring an option's value in a new line (even if only one is given)
172 will define the option's value as an array. 171 will define the option's value as a list.
173 * When an option's value is defined as an array, no other nested 172 * When an option's value is defined as a list, no other nested
174 objects may follow. 173 objects may follow.
175 * An array is expandable by the ConfigParser's '+=' token (Note: A 174 * A list is expandable by the ConfigParser's '+=' token (Note: A
176 previously declared string will be converted into an array). 175 previously declared string will be converted into a list).
177 * Values may be marked as `number` or `bool` by prefixing them 176 * Values may be marked as `number` or `bool` by prefixing them
178 accordingly (this also applies to values in an array): 177 accordingly (this also applies to values in a list):
179 * bool:<value> 178 * bool:<value>
180 * number:<value> 179 * number:<value>
181 180
182 Example: 181 Example:
183 { 182 {
184 foo = foo "foo": "foo", 183 foo = foo "foo": "foo",
185 asd = "asd": ["asd"], 184 asd = "asd": ["asd"],
186 asd "bar": { 185 asd "bar": {
187 bar.baz = a "baz": ["a", "c", "d"] 186 bar.baz = a "baz": ["a", "c", "d"]
188 baz.foo = a }, 187 baz.foo = a },
189 baz.z = "baz": { 188 baz.z = "baz": {
190 bar "foo": "a", 189 bar "foo": "a",
191 bool:true ===> "z": ["bar", true] 190 bool:true ===> "z": ["bar", true]
192 bar.baz += }, 191 bar.baz += },
193 c "bad": true, 192 c "bad": true,
194 d "good": false, 193 d "good": false,
195 bad = bool:true "is": { 194 bad = bool:true "is": {
196 good = bool:false "integer": 1, 195 good = bool:false "integer": 1,
197 is.integer = number:1 "float": 1.4 196 is.integer = number:1 "float": 1.4
198 is.float = number:1.4 } 197 is.float = number:1.4 }
199 } 198 }
200 """ 199 """
201 def parse_values(v): 200 def parse_value(v):
202 if isinstance(v, list):
203 return [parse_values(x) for x in v]
Sebastian Noack 2018/04/18 15:59:00 Checking for lists and recursively calling this fu
tlucas 2018/04/19 10:01:39 Done.
204
205 if v.startswith('number:'): 201 if v.startswith('number:'):
206 v = v.split(':', 1)[1] 202 v = v.split(':', 1)[1]
207 try: 203 try:
208 v = int(v) 204 return int(v)
Sebastian Noack 2018/04/18 15:58:59 Nit: I wouldn't reassign v, but just return the pa
tlucas 2018/04/19 10:01:39 Done.
209 except ValueError: 205 except ValueError:
210 v = float(v) 206 return float(v)
211 elif v == 'bool:true': 207 if v == 'bool:true':
212 v = True 208 return True
213 elif v == 'bool:false': 209 if v == 'bool:false':
214 v = False 210 return False
215 return v 211 return v
216 212
217 def setdefault_recursive(target, keys, value): 213 if self.has_section(section):
218 if len(keys) == 1: 214 for k, v in self.items(section):
219 target.setdefault(keys[0], parse_values(value)) 215 parents = k.split('.')
220 else: 216 tail = parents.pop()
221 current = target.setdefault(keys[0], {}) 217 current = base
222 setdefault_recursive(current, keys[1:], value) 218 for name in parents:
223 219 current = base.setdefault(name, {})
224 data = self.items(section) 220
225 result = {} 221 if '\n' in v:
226 222 current[tail] = [parse_value(x) for x in v.splitlines() if x ]
227 for k, v in data: 223 else:
228 if '\n' in v: 224 current[tail] = parse_value(v)
229 v = [x for x in v.splitlines() if x]
230
231 setdefault_recursive(result, k.split('.'), v)
Sebastian Noack 2018/04/18 15:59:00 The recursion here is unnecessary: parents = k.
tlucas 2018/04/19 10:01:39 Done.
232
233 result.update(additional)
Sebastian Noack 2018/04/18 15:58:59 Well, the point of passing the generated part of t
tlucas 2018/04/19 10:01:40 Done.
234
235 return result
236 225
237 def readfp(self, fp, filename=None): 226 def readfp(self, fp, filename=None):
238 raise NotImplementedError 227 raise NotImplementedError
239 228
240 def set(self, section, option, value=None): 229 def set(self, section, option, value=None):
241 raise NotImplementedError 230 raise NotImplementedError
242 231
243 def add_section(self, section): 232 def add_section(self, section):
244 raise NotImplementedError 233 raise NotImplementedError
245 234
246 def remove_option(self, section, option): 235 def remove_option(self, section, option):
247 raise NotImplementedError 236 raise NotImplementedError
248 237
249 def remove_section(self, section): 238 def remove_section(self, section):
250 raise NotImplementedError 239 raise NotImplementedError
LEFTRIGHT
« no previous file | packagerChrome.py » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld