|
1 """Configuration file parser. |
|
2 |
|
3 A setup file consists of sections, lead by a "[section]" header, |
|
4 and followed by "name: value" entries, with continuations and such in |
|
5 the style of RFC 822. |
|
6 |
|
7 The option values can contain format strings which refer to other values in |
|
8 the same section, or values in a special [DEFAULT] section. |
|
9 |
|
10 For example: |
|
11 |
|
12 something: %(dir)s/whatever |
|
13 |
|
14 would resolve the "%(dir)s" to the value of dir. All reference |
|
15 expansions are done late, on demand. |
|
16 |
|
17 Intrinsic defaults can be specified by passing them into the |
|
18 ConfigParser constructor as a dictionary. |
|
19 |
|
20 class: |
|
21 |
|
22 ConfigParser -- responsible for parsing a list of |
|
23 configuration files, and managing the parsed database. |
|
24 |
|
25 methods: |
|
26 |
|
27 __init__(defaults=None) |
|
28 create the parser and specify a dictionary of intrinsic defaults. The |
|
29 keys must be strings, the values must be appropriate for %()s string |
|
30 interpolation. Note that `__name__' is always an intrinsic default; |
|
31 its value is the section's name. |
|
32 |
|
33 sections() |
|
34 return all the configuration section names, sans DEFAULT |
|
35 |
|
36 has_section(section) |
|
37 return whether the given section exists |
|
38 |
|
39 has_option(section, option) |
|
40 return whether the given option exists in the given section |
|
41 |
|
42 options(section) |
|
43 return list of configuration options for the named section |
|
44 |
|
45 read(filenames) |
|
46 read and parse the list of named configuration files, given by |
|
47 name. A single filename is also allowed. Non-existing files |
|
48 are ignored. Return list of successfully read files. |
|
49 |
|
50 readfp(fp, filename=None) |
|
51 read and parse one configuration file, given as a file object. |
|
52 The filename defaults to fp.name; it is only used in error |
|
53 messages (if fp has no `name' attribute, the string `<???>' is used). |
|
54 |
|
55 get(section, option, raw=False, vars=None) |
|
56 return a string value for the named option. All % interpolations are |
|
57 expanded in the return values, based on the defaults passed into the |
|
58 constructor and the DEFAULT section. Additional substitutions may be |
|
59 provided using the `vars' argument, which must be a dictionary whose |
|
60 contents override any pre-existing defaults. |
|
61 |
|
62 getint(section, options) |
|
63 like get(), but convert value to an integer |
|
64 |
|
65 getfloat(section, options) |
|
66 like get(), but convert value to a float |
|
67 |
|
68 getboolean(section, options) |
|
69 like get(), but convert value to a boolean (currently case |
|
70 insensitively defined as 0, false, no, off for False, and 1, true, |
|
71 yes, on for True). Returns False or True. |
|
72 |
|
73 items(section, raw=False, vars=None) |
|
74 return a list of tuples with (name, value) for each option |
|
75 in the section. |
|
76 |
|
77 remove_section(section) |
|
78 remove the given file section and all its options |
|
79 |
|
80 remove_option(section, option) |
|
81 remove the given option from the given section |
|
82 |
|
83 set(section, option, value) |
|
84 set the given option |
|
85 |
|
86 write(fp) |
|
87 write the configuration state in .ini format |
|
88 """ |
|
89 |
|
90 import re |
|
91 |
|
92 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", |
|
93 "InterpolationError", "InterpolationDepthError", |
|
94 "InterpolationSyntaxError", "ParsingError", |
|
95 "MissingSectionHeaderError", |
|
96 "ConfigParser", "SafeConfigParser", "RawConfigParser", |
|
97 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] |
|
98 |
|
99 DEFAULTSECT = "DEFAULT" |
|
100 |
|
101 MAX_INTERPOLATION_DEPTH = 10 |
|
102 |
|
103 |
|
104 |
|
105 # exception classes |
|
106 class Error(Exception): |
|
107 """Base class for ConfigParser exceptions.""" |
|
108 |
|
109 def __init__(self, msg=''): |
|
110 self.message = msg |
|
111 Exception.__init__(self, msg) |
|
112 |
|
113 def __repr__(self): |
|
114 return self.message |
|
115 |
|
116 __str__ = __repr__ |
|
117 |
|
118 class NoSectionError(Error): |
|
119 """Raised when no section matches a requested option.""" |
|
120 |
|
121 def __init__(self, section): |
|
122 Error.__init__(self, 'No section: %r' % (section,)) |
|
123 self.section = section |
|
124 |
|
125 class DuplicateSectionError(Error): |
|
126 """Raised when a section is multiply-created.""" |
|
127 |
|
128 def __init__(self, section): |
|
129 Error.__init__(self, "Section %r already exists" % section) |
|
130 self.section = section |
|
131 |
|
132 class NoOptionError(Error): |
|
133 """A requested option was not found.""" |
|
134 |
|
135 def __init__(self, option, section): |
|
136 Error.__init__(self, "No option %r in section: %r" % |
|
137 (option, section)) |
|
138 self.option = option |
|
139 self.section = section |
|
140 |
|
141 class InterpolationError(Error): |
|
142 """Base class for interpolation-related exceptions.""" |
|
143 |
|
144 def __init__(self, option, section, msg): |
|
145 Error.__init__(self, msg) |
|
146 self.option = option |
|
147 self.section = section |
|
148 |
|
149 class InterpolationMissingOptionError(InterpolationError): |
|
150 """A string substitution required a setting which was not available.""" |
|
151 |
|
152 def __init__(self, option, section, rawval, reference): |
|
153 msg = ("Bad value substitution:\n" |
|
154 "\tsection: [%s]\n" |
|
155 "\toption : %s\n" |
|
156 "\tkey : %s\n" |
|
157 "\trawval : %s\n" |
|
158 % (section, option, reference, rawval)) |
|
159 InterpolationError.__init__(self, option, section, msg) |
|
160 self.reference = reference |
|
161 |
|
162 class InterpolationSyntaxError(InterpolationError): |
|
163 """Raised when the source text into which substitutions are made |
|
164 does not conform to the required syntax.""" |
|
165 |
|
166 class InterpolationDepthError(InterpolationError): |
|
167 """Raised when substitutions are nested too deeply.""" |
|
168 |
|
169 def __init__(self, option, section, rawval): |
|
170 msg = ("Value interpolation too deeply recursive:\n" |
|
171 "\tsection: [%s]\n" |
|
172 "\toption : %s\n" |
|
173 "\trawval : %s\n" |
|
174 % (section, option, rawval)) |
|
175 InterpolationError.__init__(self, option, section, msg) |
|
176 |
|
177 class ParsingError(Error): |
|
178 """Raised when a configuration file does not follow legal syntax.""" |
|
179 |
|
180 def __init__(self, filename): |
|
181 Error.__init__(self, 'File contains parsing errors: %s' % filename) |
|
182 self.filename = filename |
|
183 self.errors = [] |
|
184 |
|
185 def append(self, lineno, line): |
|
186 self.errors.append((lineno, line)) |
|
187 self.message += '\n\t[line %2d]: %s' % (lineno, line) |
|
188 |
|
189 class MissingSectionHeaderError(ParsingError): |
|
190 """Raised when a key-value pair is found before any section header.""" |
|
191 |
|
192 def __init__(self, filename, lineno, line): |
|
193 Error.__init__( |
|
194 self, |
|
195 'File contains no section headers.\nfile: %s, line: %d\n%r' % |
|
196 (filename, lineno, line)) |
|
197 self.filename = filename |
|
198 self.lineno = lineno |
|
199 self.line = line |
|
200 |
|
201 |
|
202 |
|
203 class RawConfigParser: |
|
204 def __init__(self, defaults=None): |
|
205 self._sections = {} |
|
206 self._defaults = {} |
|
207 if defaults: |
|
208 for key, value in defaults.items(): |
|
209 self._defaults[self.optionxform(key)] = value |
|
210 |
|
211 def defaults(self): |
|
212 return self._defaults |
|
213 |
|
214 def sections(self): |
|
215 """Return a list of section names, excluding [DEFAULT]""" |
|
216 # self._sections will never have [DEFAULT] in it |
|
217 return self._sections.keys() |
|
218 |
|
219 def add_section(self, section): |
|
220 """Create a new section in the configuration. |
|
221 |
|
222 Raise DuplicateSectionError if a section by the specified name |
|
223 already exists. |
|
224 """ |
|
225 if section in self._sections: |
|
226 raise DuplicateSectionError(section) |
|
227 self._sections[section] = {} |
|
228 |
|
229 def has_section(self, section): |
|
230 """Indicate whether the named section is present in the configuration. |
|
231 |
|
232 The DEFAULT section is not acknowledged. |
|
233 """ |
|
234 return section in self._sections |
|
235 |
|
236 def options(self, section): |
|
237 """Return a list of option names for the given section name.""" |
|
238 try: |
|
239 opts = self._sections[section].copy() |
|
240 except KeyError: |
|
241 raise NoSectionError(section) |
|
242 opts.update(self._defaults) |
|
243 if '__name__' in opts: |
|
244 del opts['__name__'] |
|
245 return opts.keys() |
|
246 |
|
247 def read(self, filenames): |
|
248 """Read and parse a filename or a list of filenames. |
|
249 |
|
250 Files that cannot be opened are silently ignored; this is |
|
251 designed so that you can specify a list of potential |
|
252 configuration file locations (e.g. current directory, user's |
|
253 home directory, systemwide directory), and all existing |
|
254 configuration files in the list will be read. A single |
|
255 filename may also be given. |
|
256 |
|
257 Return list of successfully read files. |
|
258 """ |
|
259 if isinstance(filenames, basestring): |
|
260 filenames = [filenames] |
|
261 read_ok = [] |
|
262 for filename in filenames: |
|
263 try: |
|
264 fp = open(filename) |
|
265 except IOError: |
|
266 continue |
|
267 self._read(fp, filename) |
|
268 fp.close() |
|
269 read_ok.append(filename) |
|
270 return read_ok |
|
271 |
|
272 def readfp(self, fp, filename=None): |
|
273 """Like read() but the argument must be a file-like object. |
|
274 |
|
275 The `fp' argument must have a `readline' method. Optional |
|
276 second argument is the `filename', which if not given, is |
|
277 taken from fp.name. If fp has no `name' attribute, `<???>' is |
|
278 used. |
|
279 |
|
280 """ |
|
281 if filename is None: |
|
282 try: |
|
283 filename = fp.name |
|
284 except AttributeError: |
|
285 filename = '<???>' |
|
286 self._read(fp, filename) |
|
287 |
|
288 def get(self, section, option): |
|
289 opt = self.optionxform(option) |
|
290 if section not in self._sections: |
|
291 if section != DEFAULTSECT: |
|
292 raise NoSectionError(section) |
|
293 if opt in self._defaults: |
|
294 return self._defaults[opt] |
|
295 else: |
|
296 raise NoOptionError(option, section) |
|
297 elif opt in self._sections[section]: |
|
298 return self._sections[section][opt] |
|
299 elif opt in self._defaults: |
|
300 return self._defaults[opt] |
|
301 else: |
|
302 raise NoOptionError(option, section) |
|
303 |
|
304 def items(self, section): |
|
305 try: |
|
306 d2 = self._sections[section] |
|
307 except KeyError: |
|
308 if section != DEFAULTSECT: |
|
309 raise NoSectionError(section) |
|
310 d2 = {} |
|
311 d = self._defaults.copy() |
|
312 d.update(d2) |
|
313 if "__name__" in d: |
|
314 del d["__name__"] |
|
315 return d.items() |
|
316 |
|
317 def _get(self, section, conv, option): |
|
318 return conv(self.get(section, option)) |
|
319 |
|
320 def getint(self, section, option): |
|
321 return self._get(section, int, option) |
|
322 |
|
323 def getfloat(self, section, option): |
|
324 return self._get(section, float, option) |
|
325 |
|
326 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, |
|
327 '0': False, 'no': False, 'false': False, 'off': False} |
|
328 |
|
329 def getboolean(self, section, option): |
|
330 v = self.get(section, option) |
|
331 if v.lower() not in self._boolean_states: |
|
332 raise ValueError, 'Not a boolean: %s' % v |
|
333 return self._boolean_states[v.lower()] |
|
334 |
|
335 def optionxform(self, optionstr): |
|
336 return optionstr.lower() |
|
337 |
|
338 def has_option(self, section, option): |
|
339 """Check for the existence of a given option in a given section.""" |
|
340 if not section or section == DEFAULTSECT: |
|
341 option = self.optionxform(option) |
|
342 return option in self._defaults |
|
343 elif section not in self._sections: |
|
344 return False |
|
345 else: |
|
346 option = self.optionxform(option) |
|
347 return (option in self._sections[section] |
|
348 or option in self._defaults) |
|
349 |
|
350 def set(self, section, option, value): |
|
351 """Set an option.""" |
|
352 if not section or section == DEFAULTSECT: |
|
353 sectdict = self._defaults |
|
354 else: |
|
355 try: |
|
356 sectdict = self._sections[section] |
|
357 except KeyError: |
|
358 raise NoSectionError(section) |
|
359 sectdict[self.optionxform(option)] = value |
|
360 |
|
361 def write(self, fp): |
|
362 """Write an .ini-format representation of the configuration state.""" |
|
363 if self._defaults: |
|
364 fp.write("[%s]\n" % DEFAULTSECT) |
|
365 for (key, value) in self._defaults.items(): |
|
366 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) |
|
367 fp.write("\n") |
|
368 for section in self._sections: |
|
369 fp.write("[%s]\n" % section) |
|
370 for (key, value) in self._sections[section].items(): |
|
371 if key != "__name__": |
|
372 fp.write("%s = %s\n" % |
|
373 (key, str(value).replace('\n', '\n\t'))) |
|
374 fp.write("\n") |
|
375 |
|
376 def remove_option(self, section, option): |
|
377 """Remove an option.""" |
|
378 if not section or section == DEFAULTSECT: |
|
379 sectdict = self._defaults |
|
380 else: |
|
381 try: |
|
382 sectdict = self._sections[section] |
|
383 except KeyError: |
|
384 raise NoSectionError(section) |
|
385 option = self.optionxform(option) |
|
386 existed = option in sectdict |
|
387 if existed: |
|
388 del sectdict[option] |
|
389 return existed |
|
390 |
|
391 def remove_section(self, section): |
|
392 """Remove a file section.""" |
|
393 existed = section in self._sections |
|
394 if existed: |
|
395 del self._sections[section] |
|
396 return existed |
|
397 |
|
398 # |
|
399 # Regular expressions for parsing section headers and options. |
|
400 # |
|
401 SECTCRE = re.compile( |
|
402 r'\[' # [ |
|
403 r'(?P<header>[^]]+)' # very permissive! |
|
404 r'\]' # ] |
|
405 ) |
|
406 OPTCRE = re.compile( |
|
407 r'(?P<option>[^:=\s][^:=]*)' # very permissive! |
|
408 r'\s*(?P<vi>[:=])\s*' # any number of space/tab, |
|
409 # followed by separator |
|
410 # (either : or =), followed |
|
411 # by any # space/tab |
|
412 r'(?P<value>.*)$' # everything up to eol |
|
413 ) |
|
414 |
|
415 def _read(self, fp, fpname): |
|
416 """Parse a sectioned setup file. |
|
417 |
|
418 The sections in setup file contains a title line at the top, |
|
419 indicated by a name in square brackets (`[]'), plus key/value |
|
420 options lines, indicated by `name: value' format lines. |
|
421 Continuations are represented by an embedded newline then |
|
422 leading whitespace. Blank lines, lines beginning with a '#', |
|
423 and just about everything else are ignored. |
|
424 """ |
|
425 cursect = None # None, or a dictionary |
|
426 optname = None |
|
427 lineno = 0 |
|
428 e = None # None, or an exception |
|
429 while True: |
|
430 line = fp.readline() |
|
431 if not line: |
|
432 break |
|
433 lineno = lineno + 1 |
|
434 # comment or blank line? |
|
435 if line.strip() == '' or line[0] in '#;': |
|
436 continue |
|
437 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": |
|
438 # no leading whitespace |
|
439 continue |
|
440 # continuation line? |
|
441 if line[0].isspace() and cursect is not None and optname: |
|
442 value = line.strip() |
|
443 if value: |
|
444 cursect[optname] = "%s\n%s" % (cursect[optname], value) |
|
445 # a section header or option header? |
|
446 else: |
|
447 # is it a section header? |
|
448 mo = self.SECTCRE.match(line) |
|
449 if mo: |
|
450 sectname = mo.group('header') |
|
451 if sectname in self._sections: |
|
452 cursect = self._sections[sectname] |
|
453 elif sectname == DEFAULTSECT: |
|
454 cursect = self._defaults |
|
455 else: |
|
456 cursect = {'__name__': sectname} |
|
457 self._sections[sectname] = cursect |
|
458 # So sections can't start with a continuation line |
|
459 optname = None |
|
460 # no section header in the file? |
|
461 elif cursect is None: |
|
462 raise MissingSectionHeaderError(fpname, lineno, line) |
|
463 # an option line? |
|
464 else: |
|
465 mo = self.OPTCRE.match(line) |
|
466 if mo: |
|
467 optname, vi, optval = mo.group('option', 'vi', 'value') |
|
468 if vi in ('=', ':') and ';' in optval: |
|
469 # ';' is a comment delimiter only if it follows |
|
470 # a spacing character |
|
471 pos = optval.find(';') |
|
472 if pos != -1 and optval[pos-1].isspace(): |
|
473 optval = optval[:pos] |
|
474 optval = optval.strip() |
|
475 # allow empty values |
|
476 if optval == '""': |
|
477 optval = '' |
|
478 optname = self.optionxform(optname.rstrip()) |
|
479 cursect[optname] = optval |
|
480 else: |
|
481 # a non-fatal parsing error occurred. set up the |
|
482 # exception but keep going. the exception will be |
|
483 # raised at the end of the file and will contain a |
|
484 # list of all bogus lines |
|
485 if not e: |
|
486 e = ParsingError(fpname) |
|
487 e.append(lineno, repr(line)) |
|
488 # if any parsing errors occurred, raise an exception |
|
489 if e: |
|
490 raise e |
|
491 |
|
492 |
|
493 class ConfigParser(RawConfigParser): |
|
494 |
|
495 def get(self, section, option, raw=False, vars=None): |
|
496 """Get an option value for a given section. |
|
497 |
|
498 All % interpolations are expanded in the return values, based on the |
|
499 defaults passed into the constructor, unless the optional argument |
|
500 `raw' is true. Additional substitutions may be provided using the |
|
501 `vars' argument, which must be a dictionary whose contents overrides |
|
502 any pre-existing defaults. |
|
503 |
|
504 The section DEFAULT is special. |
|
505 """ |
|
506 d = self._defaults.copy() |
|
507 try: |
|
508 d.update(self._sections[section]) |
|
509 except KeyError: |
|
510 if section != DEFAULTSECT: |
|
511 raise NoSectionError(section) |
|
512 # Update with the entry specific variables |
|
513 if vars: |
|
514 for key, value in vars.items(): |
|
515 d[self.optionxform(key)] = value |
|
516 option = self.optionxform(option) |
|
517 try: |
|
518 value = d[option] |
|
519 except KeyError: |
|
520 raise NoOptionError(option, section) |
|
521 |
|
522 if raw: |
|
523 return value |
|
524 else: |
|
525 return self._interpolate(section, option, value, d) |
|
526 |
|
527 def items(self, section, raw=False, vars=None): |
|
528 """Return a list of tuples with (name, value) for each option |
|
529 in the section. |
|
530 |
|
531 All % interpolations are expanded in the return values, based on the |
|
532 defaults passed into the constructor, unless the optional argument |
|
533 `raw' is true. Additional substitutions may be provided using the |
|
534 `vars' argument, which must be a dictionary whose contents overrides |
|
535 any pre-existing defaults. |
|
536 |
|
537 The section DEFAULT is special. |
|
538 """ |
|
539 d = self._defaults.copy() |
|
540 try: |
|
541 d.update(self._sections[section]) |
|
542 except KeyError: |
|
543 if section != DEFAULTSECT: |
|
544 raise NoSectionError(section) |
|
545 # Update with the entry specific variables |
|
546 if vars: |
|
547 for key, value in vars.items(): |
|
548 d[self.optionxform(key)] = value |
|
549 options = d.keys() |
|
550 if "__name__" in options: |
|
551 options.remove("__name__") |
|
552 if raw: |
|
553 return [(option, d[option]) |
|
554 for option in options] |
|
555 else: |
|
556 return [(option, self._interpolate(section, option, d[option], d)) |
|
557 for option in options] |
|
558 |
|
559 def _interpolate(self, section, option, rawval, vars): |
|
560 # do the string interpolation |
|
561 value = rawval |
|
562 depth = MAX_INTERPOLATION_DEPTH |
|
563 while depth: # Loop through this until it's done |
|
564 depth -= 1 |
|
565 if "%(" in value: |
|
566 value = self._KEYCRE.sub(self._interpolation_replace, value) |
|
567 try: |
|
568 value = value % vars |
|
569 except KeyError, e: |
|
570 raise InterpolationMissingOptionError( |
|
571 option, section, rawval, e[0]) |
|
572 else: |
|
573 break |
|
574 if "%(" in value: |
|
575 raise InterpolationDepthError(option, section, rawval) |
|
576 return value |
|
577 |
|
578 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") |
|
579 |
|
580 def _interpolation_replace(self, match): |
|
581 s = match.group(1) |
|
582 if s is None: |
|
583 return match.group() |
|
584 else: |
|
585 return "%%(%s)s" % self.optionxform(s) |
|
586 |
|
587 |
|
588 class SafeConfigParser(ConfigParser): |
|
589 |
|
590 def _interpolate(self, section, option, rawval, vars): |
|
591 # do the string interpolation |
|
592 L = [] |
|
593 self._interpolate_some(option, L, rawval, section, vars, 1) |
|
594 return ''.join(L) |
|
595 |
|
596 _interpvar_match = re.compile(r"%\(([^)]+)\)s").match |
|
597 |
|
598 def _interpolate_some(self, option, accum, rest, section, map, depth): |
|
599 if depth > MAX_INTERPOLATION_DEPTH: |
|
600 raise InterpolationDepthError(option, section, rest) |
|
601 while rest: |
|
602 p = rest.find("%") |
|
603 if p < 0: |
|
604 accum.append(rest) |
|
605 return |
|
606 if p > 0: |
|
607 accum.append(rest[:p]) |
|
608 rest = rest[p:] |
|
609 # p is no longer used |
|
610 c = rest[1:2] |
|
611 if c == "%": |
|
612 accum.append("%") |
|
613 rest = rest[2:] |
|
614 elif c == "(": |
|
615 m = self._interpvar_match(rest) |
|
616 if m is None: |
|
617 raise InterpolationSyntaxError(option, section, |
|
618 "bad interpolation variable reference %r" % rest) |
|
619 var = self.optionxform(m.group(1)) |
|
620 rest = rest[m.end():] |
|
621 try: |
|
622 v = map[var] |
|
623 except KeyError: |
|
624 raise InterpolationMissingOptionError( |
|
625 option, section, rest, var) |
|
626 if "%" in v: |
|
627 self._interpolate_some(option, accum, v, |
|
628 section, map, depth + 1) |
|
629 else: |
|
630 accum.append(v) |
|
631 else: |
|
632 raise InterpolationSyntaxError( |
|
633 option, section, |
|
634 "'%%' must be followed by '%%' or '(', found: %r" % (rest,)) |
|
635 |
|
636 def set(self, section, option, value): |
|
637 """Set an option. Extend ConfigParser.set: check for string values.""" |
|
638 if not isinstance(value, basestring): |
|
639 raise TypeError("option values must be strings") |
|
640 ConfigParser.set(self, section, option, value) |