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 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 its 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
48 are ignored. Return list of successfully read 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",
96 "ConfigParser", "SafeConfigParser", "RawConfigParser",
97 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
99 DEFAULTSECT
= "DEFAULT"
101 MAX_INTERPOLATION_DEPTH
= 10
106 class Error(Exception):
107 """Base class for ConfigParser exceptions."""
109 def __init__(self
, msg
=''):
111 Exception.__init
__(self
, msg
)
118 class NoSectionError(Error
):
119 """Raised when no section matches a requested option."""
121 def __init__(self
, section
):
122 Error
.__init
__(self
, 'No section: %r' % (section
,))
123 self
.section
= section
125 class DuplicateSectionError(Error
):
126 """Raised when a section is multiply-created."""
128 def __init__(self
, section
):
129 Error
.__init
__(self
, "Section %r already exists" % section
)
130 self
.section
= section
132 class NoOptionError(Error
):
133 """A requested option was not found."""
135 def __init__(self
, option
, section
):
136 Error
.__init
__(self
, "No option %r in section: %r" %
139 self
.section
= section
141 class InterpolationError(Error
):
142 """Base class for interpolation-related exceptions."""
144 def __init__(self
, option
, section
, msg
):
145 Error
.__init
__(self
, msg
)
147 self
.section
= section
149 class InterpolationMissingOptionError(InterpolationError
):
150 """A string substitution required a setting which was not available."""
152 def __init__(self
, option
, section
, rawval
, reference
):
153 msg
= ("Bad value substitution:\n"
158 % (section
, option
, reference
, rawval
))
159 InterpolationError
.__init
__(self
, option
, section
, msg
)
160 self
.reference
= reference
162 class InterpolationSyntaxError(InterpolationError
):
163 """Raised when the source text into which substitutions are made
164 does not conform to the required syntax."""
166 class InterpolationDepthError(InterpolationError
):
167 """Raised when substitutions are nested too deeply."""
169 def __init__(self
, option
, section
, rawval
):
170 msg
= ("Value interpolation too deeply recursive:\n"
174 % (section
, option
, rawval
))
175 InterpolationError
.__init
__(self
, option
, section
, msg
)
177 class ParsingError(Error
):
178 """Raised when a configuration file does not follow legal syntax."""
180 def __init__(self
, filename
):
181 Error
.__init
__(self
, 'File contains parsing errors: %s' % filename
)
182 self
.filename
= filename
185 def append(self
, lineno
, line
):
186 self
.errors
.append((lineno
, line
))
187 self
.message
+= '\n\t[line %2d]: %s' % (lineno
, line
)
189 class MissingSectionHeaderError(ParsingError
):
190 """Raised when a key-value pair is found before any section header."""
192 def __init__(self
, filename
, lineno
, line
):
195 'File contains no section headers.\nfile: %s, line: %d\n%r' %
196 (filename
, lineno
, line
))
197 self
.filename
= filename
202 class RawConfigParser
:
203 def __init__(self
, defaults
=None, dict_type
=dict):
204 self
._dict
= dict_type
205 self
._sections
= self
._dict
()
206 self
._defaults
= self
._dict
()
208 for key
, value
in defaults
.items():
209 self
._defaults
[self
.optionxform(key
)] = value
212 return self
._defaults
215 """Return a list of section names, excluding [DEFAULT]"""
216 # self._sections will never have [DEFAULT] in it
217 return self
._sections
.keys()
219 def add_section(self
, section
):
220 """Create a new section in the configuration.
222 Raise DuplicateSectionError if a section by the specified name
225 if section
in self
._sections
:
226 raise DuplicateSectionError(section
)
227 self
._sections
[section
] = self
._dict
()
229 def has_section(self
, section
):
230 """Indicate whether the named section is present in the configuration.
232 The DEFAULT section is not acknowledged.
234 return section
in self
._sections
236 def options(self
, section
):
237 """Return a list of option names for the given section name."""
239 opts
= self
._sections
[section
].copy()
241 raise NoSectionError(section
)
242 opts
.update(self
._defaults
)
243 if '__name__' in opts
:
247 def read(self
, filenames
):
248 """Read and parse a filename or a list of filenames.
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.
257 Return list of successfully read files.
259 if isinstance(filenames
, basestring
):
260 filenames
= [filenames
]
262 for filename
in filenames
:
267 self
._read
(fp
, filename
)
269 read_ok
.append(filename
)
272 def readfp(self
, fp
, filename
=None):
273 """Like read() but the argument must be a file-like object.
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
284 except AttributeError:
286 self
._read
(fp
, filename
)
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
]
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
]
302 raise NoOptionError(option
, section
)
304 def items(self
, section
):
306 d2
= self
._sections
[section
]
308 if section
!= DEFAULTSECT
:
309 raise NoSectionError(section
)
311 d
= self
._defaults
.copy()
317 def _get(self
, section
, conv
, option
):
318 return conv(self
.get(section
, option
))
320 def getint(self
, section
, option
):
321 return self
._get
(section
, int, option
)
323 def getfloat(self
, section
, option
):
324 return self
._get
(section
, float, option
)
326 _boolean_states
= {'1': True, 'yes': True, 'true': True, 'on': True,
327 '0': False, 'no': False, 'false': False, 'off': False}
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()]
335 def optionxform(self
, optionstr
):
336 return optionstr
.lower()
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
:
346 option
= self
.optionxform(option
)
347 return (option
in self
._sections
[section
]
348 or option
in self
._defaults
)
350 def set(self
, section
, option
, value
):
352 if not section
or section
== DEFAULTSECT
:
353 sectdict
= self
._defaults
356 sectdict
= self
._sections
[section
]
358 raise NoSectionError(section
)
359 sectdict
[self
.optionxform(option
)] = value
362 """Write an .ini-format representation of the configuration state."""
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')))
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')))
376 def remove_option(self
, section
, option
):
377 """Remove an option."""
378 if not section
or section
== DEFAULTSECT
:
379 sectdict
= self
._defaults
382 sectdict
= self
._sections
[section
]
384 raise NoSectionError(section
)
385 option
= self
.optionxform(option
)
386 existed
= option
in sectdict
391 def remove_section(self
, section
):
392 """Remove a file section."""
393 existed
= section
in self
._sections
395 del self
._sections
[section
]
399 # Regular expressions for parsing section headers and options.
401 SECTCRE
= re
.compile(
403 r
'(?P<header>[^]]+)' # very permissive!
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
412 r
'(?P<value>.*)$' # everything up to eol
415 def _read(self
, fp
, fpname
):
416 """Parse a sectioned setup file.
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.
425 cursect
= None # None, or a dictionary
428 e
= None # None, or an exception
434 # comment or blank line?
435 if line
.strip() == '' or line
[0] in '#;':
437 if line
.split(None, 1)[0].lower() == 'rem' and line
[0] in "rR":
438 # no leading whitespace
441 if line
[0].isspace() and cursect
is not None and optname
:
444 cursect
[optname
] = "%s\n%s" % (cursect
[optname
], value
)
445 # a section header or option header?
447 # is it a section header?
448 mo
= self
.SECTCRE
.match(line
)
450 sectname
= mo
.group('header')
451 if sectname
in self
._sections
:
452 cursect
= self
._sections
[sectname
]
453 elif sectname
== DEFAULTSECT
:
454 cursect
= self
._defaults
456 cursect
= self
._dict
()
457 cursect
['__name__'] = sectname
458 self
._sections
[sectname
] = cursect
459 # So sections can't start with a continuation line
461 # no section header in the file?
462 elif cursect
is None:
463 raise MissingSectionHeaderError(fpname
, lineno
, line
)
466 mo
= self
.OPTCRE
.match(line
)
468 optname
, vi
, optval
= mo
.group('option', 'vi', 'value')
469 if vi
in ('=', ':') and ';' in optval
:
470 # ';' is a comment delimiter only if it follows
471 # a spacing character
472 pos
= optval
.find(';')
473 if pos
!= -1 and optval
[pos
-1].isspace():
474 optval
= optval
[:pos
]
475 optval
= optval
.strip()
479 optname
= self
.optionxform(optname
.rstrip())
480 cursect
[optname
] = optval
482 # a non-fatal parsing error occurred. set up the
483 # exception but keep going. the exception will be
484 # raised at the end of the file and will contain a
485 # list of all bogus lines
487 e
= ParsingError(fpname
)
488 e
.append(lineno
, repr(line
))
489 # if any parsing errors occurred, raise an exception
494 class ConfigParser(RawConfigParser
):
496 def get(self
, section
, option
, raw
=False, vars=None):
497 """Get an option value for a given section.
499 All % interpolations are expanded in the return values, based on the
500 defaults passed into the constructor, unless the optional argument
501 `raw' is true. Additional substitutions may be provided using the
502 `vars' argument, which must be a dictionary whose contents overrides
503 any pre-existing defaults.
505 The section DEFAULT is special.
507 d
= self
._defaults
.copy()
509 d
.update(self
._sections
[section
])
511 if section
!= DEFAULTSECT
:
512 raise NoSectionError(section
)
513 # Update with the entry specific variables
515 for key
, value
in vars.items():
516 d
[self
.optionxform(key
)] = value
517 option
= self
.optionxform(option
)
521 raise NoOptionError(option
, section
)
526 return self
._interpolate
(section
, option
, value
, d
)
528 def items(self
, section
, raw
=False, vars=None):
529 """Return a list of tuples with (name, value) for each option
532 All % interpolations are expanded in the return values, based on the
533 defaults passed into the constructor, unless the optional argument
534 `raw' is true. Additional substitutions may be provided using the
535 `vars' argument, which must be a dictionary whose contents overrides
536 any pre-existing defaults.
538 The section DEFAULT is special.
540 d
= self
._defaults
.copy()
542 d
.update(self
._sections
[section
])
544 if section
!= DEFAULTSECT
:
545 raise NoSectionError(section
)
546 # Update with the entry specific variables
548 for key
, value
in vars.items():
549 d
[self
.optionxform(key
)] = value
551 if "__name__" in options
:
552 options
.remove("__name__")
554 return [(option
, d
[option
])
555 for option
in options
]
557 return [(option
, self
._interpolate
(section
, option
, d
[option
], d
))
558 for option
in options
]
560 def _interpolate(self
, section
, option
, rawval
, vars):
561 # do the string interpolation
563 depth
= MAX_INTERPOLATION_DEPTH
564 while depth
: # Loop through this until it's done
567 value
= self
._KEYCRE
.sub(self
._interpolation
_replace
, value
)
571 raise InterpolationMissingOptionError(
572 option
, section
, rawval
, e
[0])
576 raise InterpolationDepthError(option
, section
, rawval
)
579 _KEYCRE
= re
.compile(r
"%\(([^)]*)\)s|.")
581 def _interpolation_replace(self
, match
):
586 return "%%(%s)s" % self
.optionxform(s
)
589 class SafeConfigParser(ConfigParser
):
591 def _interpolate(self
, section
, option
, rawval
, vars):
592 # do the string interpolation
594 self
._interpolate
_some
(option
, L
, rawval
, section
, vars, 1)
597 _interpvar_match
= re
.compile(r
"%\(([^)]+)\)s").match
599 def _interpolate_some(self
, option
, accum
, rest
, section
, map, depth
):
600 if depth
> MAX_INTERPOLATION_DEPTH
:
601 raise InterpolationDepthError(option
, section
, rest
)
608 accum
.append(rest
[:p
])
610 # p is no longer used
616 m
= self
._interpvar
_match
(rest
)
618 raise InterpolationSyntaxError(option
, section
,
619 "bad interpolation variable reference %r" % rest
)
620 var
= self
.optionxform(m
.group(1))
621 rest
= rest
[m
.end():]
625 raise InterpolationMissingOptionError(
626 option
, section
, rest
, var
)
628 self
._interpolate
_some
(option
, accum
, v
,
629 section
, map, depth
+ 1)
633 raise InterpolationSyntaxError(
635 "'%%' must be followed by '%%' or '(', found: %r" % (rest
,))
637 def set(self
, section
, option
, value
):
638 """Set an option. Extend ConfigParser.set: check for string values."""
639 if not isinstance(value
, basestring
):
640 raise TypeError("option values must be strings")
641 ConfigParser
.set(self
, section
, option
, value
)