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
203 class RawConfigParser
:
204 def __init__(self
, defaults
=None):
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
] = {}
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
= {'__name__': sectname
}
457 self
._sections
[sectname
] = cursect
458 # So sections can't start with a continuation line
460 # no section header in the file?
461 elif cursect
is None:
462 raise MissingSectionHeaderError(fpname
, lineno
, line
)
465 mo
= self
.OPTCRE
.match(line
)
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()
478 optname
= self
.optionxform(optname
.rstrip())
479 cursect
[optname
] = optval
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
486 e
= ParsingError(fpname
)
487 e
.append(lineno
, repr(line
))
488 # if any parsing errors occurred, raise an exception
493 class ConfigParser(RawConfigParser
):
495 def get(self
, section
, option
, raw
=False, vars=None):
496 """Get an option value for a given section.
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.
504 The section DEFAULT is special.
506 d
= self
._defaults
.copy()
508 d
.update(self
._sections
[section
])
510 if section
!= DEFAULTSECT
:
511 raise NoSectionError(section
)
512 # Update with the entry specific variables
514 for key
, value
in vars.items():
515 d
[self
.optionxform(key
)] = value
516 option
= self
.optionxform(option
)
520 raise NoOptionError(option
, section
)
525 return self
._interpolate
(section
, option
, value
, d
)
527 def items(self
, section
, raw
=False, vars=None):
528 """Return a list of tuples with (name, value) for each option
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.
537 The section DEFAULT is special.
539 d
= self
._defaults
.copy()
541 d
.update(self
._sections
[section
])
543 if section
!= DEFAULTSECT
:
544 raise NoSectionError(section
)
545 # Update with the entry specific variables
547 for key
, value
in vars.items():
548 d
[self
.optionxform(key
)] = value
550 if "__name__" in options
:
551 options
.remove("__name__")
553 return [(option
, d
[option
])
554 for option
in options
]
556 return [(option
, self
._interpolate
(section
, option
, d
[option
], d
))
557 for option
in options
]
559 def _interpolate(self
, section
, option
, rawval
, vars):
560 # do the string interpolation
562 depth
= MAX_INTERPOLATION_DEPTH
563 while depth
: # Loop through this until it's done
566 value
= self
._KEYCRE
.sub(self
._interpolation
_replace
, value
)
570 raise InterpolationMissingOptionError(
571 option
, section
, rawval
, e
[0])
575 raise InterpolationDepthError(option
, section
, rawval
)
578 _KEYCRE
= re
.compile(r
"%\(([^)]*)\)s|.")
580 def _interpolation_replace(self
, match
):
585 return "%%(%s)s" % self
.optionxform(s
)
588 class SafeConfigParser(ConfigParser
):
590 def _interpolate(self
, section
, option
, rawval
, vars):
591 # do the string interpolation
593 self
._interpolate
_some
(option
, L
, rawval
, section
, vars, 1)
596 _interpvar_match
= re
.compile(r
"%\(([^)]+)\)s").match
598 def _interpolate_some(self
, option
, accum
, rest
, section
, map, depth
):
599 if depth
> MAX_INTERPOLATION_DEPTH
:
600 raise InterpolationDepthError(option
, section
, rest
)
607 accum
.append(rest
[:p
])
609 # p is no longer used
615 m
= self
._interpvar
_match
(rest
)
617 raise InterpolationSyntaxError(option
, section
,
618 "bad interpolation variable reference %r" % rest
)
619 var
= self
.optionxform(m
.group(1))
620 rest
= rest
[m
.end():]
624 raise InterpolationMissingOptionError(
625 option
, section
, rest
, var
)
627 self
._interpolate
_some
(option
, accum
, v
,
628 section
, map, depth
+ 1)
632 raise InterpolationSyntaxError(
634 "'%%' must be followed by '%%' or '(', found: %r" % (rest
,))
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
)