1 """Configuration file parser.
3 A setup file consists of sections, lead by a "[section]" header,
4 and followed by "name: value" entries, with continuations and such in
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.
12 something: %(dir)s/whatever
14 would resolve the "%(dir)s" to the value of dir. All reference
15 expansions are done late, on demand.
17 Intrinsic defaults can be specified by passing them into the
18 ConfigParser constructor as a dictionary.
22 ConfigParser -- responsible for for parsing a list of
23 configuration files, and managing the parsed database.
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 it's value is the section's name.
34 return all the configuration section names, sans DEFAULT
37 return whether the given section exists
39 has_option(section, option)
40 return whether the given option exists in the given section
43 return list of configuration options for the named section
46 read and parse the list of named configuration files, given by
47 name. A single filename is also allowed. Non-existing files
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).
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.
62 getint(section, options)
63 like get(), but convert value to an integer
65 getfloat(section, options)
66 like get(), but convert value to a float
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.
73 items(section, raw=False, vars=None)
74 return a list of tuples with (name, value) for each option
77 remove_section(section)
78 remove the given file section and all its options
80 remove_option(section, option)
81 remove the given option from the given section
83 set(section, option, value)
87 write the configuration state in .ini format
92 __all__
= ["NoSectionError", "DuplicateSectionError", "NoOptionError",
93 "InterpolationError", "InterpolationDepthError",
94 "InterpolationSyntaxError", "ParsingError",
95 "MissingSectionHeaderError", "ConfigParser",
96 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
98 DEFAULTSECT
= "DEFAULT"
100 MAX_INTERPOLATION_DEPTH
= 10
105 class Error(Exception):
106 """Base class for ConfigParser exceptions."""
108 def __init__(self
, msg
=''):
110 Exception.__init
__(self
, msg
)
117 class NoSectionError(Error
):
118 """Raised when no section matches a requested option."""
120 def __init__(self
, section
):
121 Error
.__init
__(self
, 'No section: ' + `section`
)
122 self
.section
= section
124 class DuplicateSectionError(Error
):
125 """Raised when a section is multiply-created."""
127 def __init__(self
, section
):
128 Error
.__init
__(self
, "Section %r already exists" % section
)
129 self
.section
= section
131 class NoOptionError(Error
):
132 """A requested option was not found."""
134 def __init__(self
, option
, section
):
135 Error
.__init
__(self
, "No option %r in section: %r" %
138 self
.section
= section
140 class InterpolationError(Error
):
141 """Base class for interpolation-related exceptions."""
143 def __init__(self
, option
, section
, msg
):
144 Error
.__init
__(self
, msg
)
146 self
.section
= section
148 class InterpolationMissingOptionError(InterpolationError
):
149 """A string substitution required a setting which was not available."""
151 def __init__(self
, option
, section
, rawval
, reference
):
152 msg
= ("Bad value substitution:\n"
157 % (section
, option
, reference
, rawval
))
158 InterpolationError
.__init
__(self
, option
, section
, msg
)
159 self
.reference
= reference
161 class InterpolationSyntaxError(InterpolationError
):
162 """Raised when the source text into which substitutions are made
163 does not conform to the required syntax."""
165 class InterpolationDepthError(InterpolationError
):
166 """Raised when substitutions are nested too deeply."""
168 def __init__(self
, option
, section
, rawval
):
169 msg
= ("Value interpolation too deeply recursive:\n"
173 % (section
, option
, rawval
))
174 InterpolationError
.__init
__(self
, option
, section
, msg
)
176 class ParsingError(Error
):
177 """Raised when a configuration file does not follow legal syntax."""
179 def __init__(self
, filename
):
180 Error
.__init
__(self
, 'File contains parsing errors: %s' % filename
)
181 self
.filename
= filename
184 def append(self
, lineno
, line
):
185 self
.errors
.append((lineno
, line
))
186 self
.message
+= '\n\t[line %2d]: %s' % (lineno
, line
)
188 class MissingSectionHeaderError(ParsingError
):
189 """Raised when a key-value pair is found before any section header."""
191 def __init__(self
, filename
, lineno
, line
):
194 'File contains no section headers.\nfile: %s, line: %d\n%s' %
195 (filename
, lineno
, line
))
196 self
.filename
= filename
202 class RawConfigParser
:
203 def __init__(self
, defaults
=None):
208 self
._defaults
= defaults
211 return self
._defaults
214 """Return a list of section names, excluding [DEFAULT]"""
215 # self._sections will never have [DEFAULT] in it
216 return self
._sections
.keys()
218 def add_section(self
, section
):
219 """Create a new section in the configuration.
221 Raise DuplicateSectionError if a section by the specified name
224 if section
in self
._sections
:
225 raise DuplicateSectionError(section
)
226 self
._sections
[section
] = {}
228 def has_section(self
, section
):
229 """Indicate whether the named section is present in the configuration.
231 The DEFAULT section is not acknowledged.
233 return section
in self
._sections
235 def options(self
, section
):
236 """Return a list of option names for the given section name."""
238 opts
= self
._sections
[section
].copy()
240 raise NoSectionError(section
)
241 opts
.update(self
._defaults
)
242 if '__name__' in opts
:
246 def read(self
, filenames
):
247 """Read and parse a filename or a list of filenames.
249 Files that cannot be opened are silently ignored; this is
250 designed so that you can specify a list of potential
251 configuration file locations (e.g. current directory, user's
252 home directory, systemwide directory), and all existing
253 configuration files in the list will be read. A single
254 filename may also be given.
256 if isinstance(filenames
, basestring
):
257 filenames
= [filenames
]
258 for filename
in filenames
:
263 self
._read
(fp
, filename
)
266 def readfp(self
, fp
, filename
=None):
267 """Like read() but the argument must be a file-like object.
269 The `fp' argument must have a `readline' method. Optional
270 second argument is the `filename', which if not given, is
271 taken from fp.name. If fp has no `name' attribute, `<???>' is
278 except AttributeError:
280 self
._read
(fp
, filename
)
282 def get(self
, section
, option
):
283 opt
= self
.optionxform(option
)
284 if section
not in self
._sections
:
285 if section
!= DEFAULTSECT
:
286 raise NoSectionError(section
)
287 if opt
in self
._defaults
:
288 return self
._defaults
[opt
]
290 raise NoOptionError(option
, section
)
291 elif opt
in self
._sections
[section
]:
292 return self
._sections
[section
][opt
]
293 elif opt
in self
._defaults
:
294 return self
._defaults
[opt
]
296 raise NoOptionError(option
, section
)
298 def items(self
, section
):
300 d2
= self
._sections
[section
]
302 if section
!= DEFAULTSECT
:
303 raise NoSectionError(section
)
305 d
= self
._defaults
.copy()
311 def _get(self
, section
, conv
, option
):
312 return conv(self
.get(section
, option
))
314 def getint(self
, section
, option
):
315 return self
._get
(section
, int, option
)
317 def getfloat(self
, section
, option
):
318 return self
._get
(section
, float, option
)
320 _boolean_states
= {'1': True, 'yes': True, 'true': True, 'on': True,
321 '0': False, 'no': False, 'false': False, 'off': False}
323 def getboolean(self
, section
, option
):
324 v
= self
.get(section
, option
)
325 if v
.lower() not in self
._boolean
_states
:
326 raise ValueError, 'Not a boolean: %s' % v
327 return self
._boolean
_states
[v
.lower()]
329 def optionxform(self
, optionstr
):
330 return optionstr
.lower()
332 def has_option(self
, section
, option
):
333 """Check for the existence of a given option in a given section."""
334 if not section
or section
== DEFAULTSECT
:
335 option
= self
.optionxform(option
)
336 return option
in self
._defaults
337 elif section
not in self
._sections
:
340 option
= self
.optionxform(option
)
341 return (option
in self
._sections
[section
]
342 or option
in self
._defaults
)
344 def set(self
, section
, option
, value
):
346 if not section
or section
== DEFAULTSECT
:
347 sectdict
= self
._defaults
350 sectdict
= self
._sections
[section
]
352 raise NoSectionError(section
)
353 sectdict
[self
.optionxform(option
)] = value
356 """Write an .ini-format representation of the configuration state."""
358 fp
.write("[%s]\n" % DEFAULTSECT
)
359 for (key
, value
) in self
._defaults
.items():
360 fp
.write("%s = %s\n" % (key
, str(value
).replace('\n', '\n\t')))
362 for section
in self
._sections
:
363 fp
.write("[%s]\n" % section
)
364 for (key
, value
) in self
._sections
[section
].items():
365 if key
!= "__name__":
366 fp
.write("%s = %s\n" %
367 (key
, str(value
).replace('\n', '\n\t')))
370 def remove_option(self
, section
, option
):
371 """Remove an option."""
372 if not section
or section
== DEFAULTSECT
:
373 sectdict
= self
._defaults
376 sectdict
= self
._sections
[section
]
378 raise NoSectionError(section
)
379 option
= self
.optionxform(option
)
380 existed
= option
in sectdict
385 def remove_section(self
, section
):
386 """Remove a file section."""
387 existed
= section
in self
._sections
389 del self
._sections
[section
]
393 # Regular expressions for parsing section headers and options.
395 SECTCRE
= re
.compile(
397 r
'(?P<header>[^]]+)' # very permissive!
401 r
'(?P<option>[^:=\s][^:=]*)' # very permissive!
402 r
'\s*(?P<vi>[:=])\s*' # any number of space/tab,
403 # followed by separator
404 # (either : or =), followed
406 r
'(?P<value>.*)$' # everything up to eol
409 def _read(self
, fp
, fpname
):
410 """Parse a sectioned setup file.
412 The sections in setup file contains a title line at the top,
413 indicated by a name in square brackets (`[]'), plus key/value
414 options lines, indicated by `name: value' format lines.
415 Continuations are represented by an embedded newline then
416 leading whitespace. Blank lines, lines beginning with a '#',
417 and just about everything else are ignored.
419 cursect
= None # None, or a dictionary
422 e
= None # None, or an exception
428 # comment or blank line?
429 if line
.strip() == '' or line
[0] in '#;':
431 if line
.split(None, 1)[0].lower() == 'rem' and line
[0] in "rR":
432 # no leading whitespace
435 if line
[0].isspace() and cursect
is not None and optname
:
438 cursect
[optname
] = "%s\n%s" % (cursect
[optname
], value
)
439 # a section header or option header?
441 # is it a section header?
442 mo
= self
.SECTCRE
.match(line
)
444 sectname
= mo
.group('header')
445 if sectname
in self
._sections
:
446 cursect
= self
._sections
[sectname
]
447 elif sectname
== DEFAULTSECT
:
448 cursect
= self
._defaults
450 cursect
= {'__name__': sectname
}
451 self
._sections
[sectname
] = cursect
452 # So sections can't start with a continuation line
454 # no section header in the file?
455 elif cursect
is None:
456 raise MissingSectionHeaderError(fpname
, lineno
, `line`
)
459 mo
= self
.OPTCRE
.match(line
)
461 optname
, vi
, optval
= mo
.group('option', 'vi', 'value')
462 if vi
in ('=', ':') and ';' in optval
:
463 # ';' is a comment delimiter only if it follows
464 # a spacing character
465 pos
= optval
.find(';')
466 if pos
!= -1 and optval
[pos
-1].isspace():
467 optval
= optval
[:pos
]
468 optval
= optval
.strip()
472 optname
= self
.optionxform(optname
.rstrip())
473 cursect
[optname
] = optval
475 # a non-fatal parsing error occurred. set up the
476 # exception but keep going. the exception will be
477 # raised at the end of the file and will contain a
478 # list of all bogus lines
480 e
= ParsingError(fpname
)
481 e
.append(lineno
, `line`
)
482 # if any parsing errors occurred, raise an exception
487 class ConfigParser(RawConfigParser
):
489 def get(self
, section
, option
, raw
=False, vars=None):
490 """Get an option value for a given section.
492 All % interpolations are expanded in the return values, based on the
493 defaults passed into the constructor, unless the optional argument
494 `raw' is true. Additional substitutions may be provided using the
495 `vars' argument, which must be a dictionary whose contents overrides
496 any pre-existing defaults.
498 The section DEFAULT is special.
500 d
= self
._defaults
.copy()
502 d
.update(self
._sections
[section
])
504 if section
!= DEFAULTSECT
:
505 raise NoSectionError(section
)
506 # Update with the entry specific variables
509 option
= self
.optionxform(option
)
513 raise NoOptionError(option
, section
)
518 return self
._interpolate
(section
, option
, value
, d
)
520 def items(self
, section
, raw
=False, vars=None):
521 """Return a list of tuples with (name, value) for each option
524 All % interpolations are expanded in the return values, based on the
525 defaults passed into the constructor, unless the optional argument
526 `raw' is true. Additional substitutions may be provided using the
527 `vars' argument, which must be a dictionary whose contents overrides
528 any pre-existing defaults.
530 The section DEFAULT is special.
532 d
= self
._defaults
.copy()
534 d
.update(self
._sections
[section
])
536 if section
!= DEFAULTSECT
:
537 raise NoSectionError(section
)
538 # Update with the entry specific variables
542 if "__name__" in options
:
543 options
.remove("__name__")
545 for option
in options
:
546 yield (option
, d
[option
])
548 for option
in options
:
550 self
._interpolate
(section
, option
, d
[option
], d
))
552 def _interpolate(self
, section
, option
, rawval
, vars):
553 # do the string interpolation
555 depth
= MAX_INTERPOLATION_DEPTH
556 while depth
: # Loop through this until it's done
558 if value
.find("%(") != -1:
562 raise InterpolationMissingOptionError(
563 option
, section
, rawval
, e
[0])
566 if value
.find("%(") != -1:
567 raise InterpolationDepthError(option
, section
, rawval
)
571 class SafeConfigParser(ConfigParser
):
573 def _interpolate(self
, section
, option
, rawval
, vars):
574 # do the string interpolation
576 self
._interpolate
_some
(option
, L
, rawval
, section
, vars, 1)
579 _interpvar_match
= re
.compile(r
"%\(([^)]+)\)s").match
581 def _interpolate_some(self
, option
, accum
, rest
, section
, map, depth
):
582 if depth
> MAX_INTERPOLATION_DEPTH
:
583 raise InterpolationDepthError(option
, section
, rest
)
590 accum
.append(rest
[:p
])
592 # p is no longer used
598 m
= self
._interpvar
_match
(rest
)
600 raise InterpolationSyntaxError(
601 "bad interpolation variable reference", rest
)
603 rest
= rest
[m
.end():]
607 raise InterpolationMissingOptionError(
608 option
, section
, rest
, var
)
610 self
._interpolate
_some
(option
, accum
, v
,
611 section
, map, depth
+ 1)
615 raise InterpolationSyntaxError(
616 option
, section
, rest
,
617 "'%' must be followed by '%' or '(', found: " + `rest`
)