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 _get_message(self
):
110 """Getter for 'message'; needed only to override deprecation in
112 return self
.__message
114 def _set_message(self
, value
):
115 """Setter for 'message'; needed only to override deprecation in
117 self
.__message
= value
119 # BaseException.message has been deprecated since Python 2.6. To prevent
120 # DeprecationWarning from popping up over this pre-existing attribute, use
121 # a new property that takes lookup precedence.
122 message
= property(_get_message
, _set_message
)
124 def __init__(self
, msg
=''):
126 Exception.__init
__(self
, msg
)
133 class NoSectionError(Error
):
134 """Raised when no section matches a requested option."""
136 def __init__(self
, section
):
137 Error
.__init
__(self
, 'No section: %r' % (section
,))
138 self
.section
= section
140 class DuplicateSectionError(Error
):
141 """Raised when a section is multiply-created."""
143 def __init__(self
, section
):
144 Error
.__init
__(self
, "Section %r already exists" % section
)
145 self
.section
= section
147 class NoOptionError(Error
):
148 """A requested option was not found."""
150 def __init__(self
, option
, section
):
151 Error
.__init
__(self
, "No option %r in section: %r" %
154 self
.section
= section
156 class InterpolationError(Error
):
157 """Base class for interpolation-related exceptions."""
159 def __init__(self
, option
, section
, msg
):
160 Error
.__init
__(self
, msg
)
162 self
.section
= section
164 class InterpolationMissingOptionError(InterpolationError
):
165 """A string substitution required a setting which was not available."""
167 def __init__(self
, option
, section
, rawval
, reference
):
168 msg
= ("Bad value substitution:\n"
173 % (section
, option
, reference
, rawval
))
174 InterpolationError
.__init
__(self
, option
, section
, msg
)
175 self
.reference
= reference
177 class InterpolationSyntaxError(InterpolationError
):
178 """Raised when the source text into which substitutions are made
179 does not conform to the required syntax."""
181 class InterpolationDepthError(InterpolationError
):
182 """Raised when substitutions are nested too deeply."""
184 def __init__(self
, option
, section
, rawval
):
185 msg
= ("Value interpolation too deeply recursive:\n"
189 % (section
, option
, rawval
))
190 InterpolationError
.__init
__(self
, option
, section
, msg
)
192 class ParsingError(Error
):
193 """Raised when a configuration file does not follow legal syntax."""
195 def __init__(self
, filename
):
196 Error
.__init
__(self
, 'File contains parsing errors: %s' % filename
)
197 self
.filename
= filename
200 def append(self
, lineno
, line
):
201 self
.errors
.append((lineno
, line
))
202 self
.message
+= '\n\t[line %2d]: %s' % (lineno
, line
)
204 class MissingSectionHeaderError(ParsingError
):
205 """Raised when a key-value pair is found before any section header."""
207 def __init__(self
, filename
, lineno
, line
):
210 'File contains no section headers.\nfile: %s, line: %d\n%r' %
211 (filename
, lineno
, line
))
212 self
.filename
= filename
217 class RawConfigParser
:
218 def __init__(self
, defaults
=None, dict_type
=dict):
219 self
._dict
= dict_type
220 self
._sections
= self
._dict
()
221 self
._defaults
= self
._dict
()
223 for key
, value
in defaults
.items():
224 self
._defaults
[self
.optionxform(key
)] = value
227 return self
._defaults
230 """Return a list of section names, excluding [DEFAULT]"""
231 # self._sections will never have [DEFAULT] in it
232 return self
._sections
.keys()
234 def add_section(self
, section
):
235 """Create a new section in the configuration.
237 Raise DuplicateSectionError if a section by the specified name
240 if section
in self
._sections
:
241 raise DuplicateSectionError(section
)
242 self
._sections
[section
] = self
._dict
()
244 def has_section(self
, section
):
245 """Indicate whether the named section is present in the configuration.
247 The DEFAULT section is not acknowledged.
249 return section
in self
._sections
251 def options(self
, section
):
252 """Return a list of option names for the given section name."""
254 opts
= self
._sections
[section
].copy()
256 raise NoSectionError(section
)
257 opts
.update(self
._defaults
)
258 if '__name__' in opts
:
262 def read(self
, filenames
):
263 """Read and parse a filename or a list of filenames.
265 Files that cannot be opened are silently ignored; this is
266 designed so that you can specify a list of potential
267 configuration file locations (e.g. current directory, user's
268 home directory, systemwide directory), and all existing
269 configuration files in the list will be read. A single
270 filename may also be given.
272 Return list of successfully read files.
274 if isinstance(filenames
, basestring
):
275 filenames
= [filenames
]
277 for filename
in filenames
:
282 self
._read
(fp
, filename
)
284 read_ok
.append(filename
)
287 def readfp(self
, fp
, filename
=None):
288 """Like read() but the argument must be a file-like object.
290 The `fp' argument must have a `readline' method. Optional
291 second argument is the `filename', which if not given, is
292 taken from fp.name. If fp has no `name' attribute, `<???>' is
299 except AttributeError:
301 self
._read
(fp
, filename
)
303 def get(self
, section
, option
):
304 opt
= self
.optionxform(option
)
305 if section
not in self
._sections
:
306 if section
!= DEFAULTSECT
:
307 raise NoSectionError(section
)
308 if opt
in self
._defaults
:
309 return self
._defaults
[opt
]
311 raise NoOptionError(option
, section
)
312 elif opt
in self
._sections
[section
]:
313 return self
._sections
[section
][opt
]
314 elif opt
in self
._defaults
:
315 return self
._defaults
[opt
]
317 raise NoOptionError(option
, section
)
319 def items(self
, section
):
321 d2
= self
._sections
[section
]
323 if section
!= DEFAULTSECT
:
324 raise NoSectionError(section
)
326 d
= self
._defaults
.copy()
332 def _get(self
, section
, conv
, option
):
333 return conv(self
.get(section
, option
))
335 def getint(self
, section
, option
):
336 return self
._get
(section
, int, option
)
338 def getfloat(self
, section
, option
):
339 return self
._get
(section
, float, option
)
341 _boolean_states
= {'1': True, 'yes': True, 'true': True, 'on': True,
342 '0': False, 'no': False, 'false': False, 'off': False}
344 def getboolean(self
, section
, option
):
345 v
= self
.get(section
, option
)
346 if v
.lower() not in self
._boolean
_states
:
347 raise ValueError, 'Not a boolean: %s' % v
348 return self
._boolean
_states
[v
.lower()]
350 def optionxform(self
, optionstr
):
351 return optionstr
.lower()
353 def has_option(self
, section
, option
):
354 """Check for the existence of a given option in a given section."""
355 if not section
or section
== DEFAULTSECT
:
356 option
= self
.optionxform(option
)
357 return option
in self
._defaults
358 elif section
not in self
._sections
:
361 option
= self
.optionxform(option
)
362 return (option
in self
._sections
[section
]
363 or option
in self
._defaults
)
365 def set(self
, section
, option
, value
):
367 if not section
or section
== DEFAULTSECT
:
368 sectdict
= self
._defaults
371 sectdict
= self
._sections
[section
]
373 raise NoSectionError(section
)
374 sectdict
[self
.optionxform(option
)] = value
377 """Write an .ini-format representation of the configuration state."""
379 fp
.write("[%s]\n" % DEFAULTSECT
)
380 for (key
, value
) in self
._defaults
.items():
381 fp
.write("%s = %s\n" % (key
, str(value
).replace('\n', '\n\t')))
383 for section
in self
._sections
:
384 fp
.write("[%s]\n" % section
)
385 for (key
, value
) in self
._sections
[section
].items():
386 if key
!= "__name__":
387 fp
.write("%s = %s\n" %
388 (key
, str(value
).replace('\n', '\n\t')))
391 def remove_option(self
, section
, option
):
392 """Remove an option."""
393 if not section
or section
== DEFAULTSECT
:
394 sectdict
= self
._defaults
397 sectdict
= self
._sections
[section
]
399 raise NoSectionError(section
)
400 option
= self
.optionxform(option
)
401 existed
= option
in sectdict
406 def remove_section(self
, section
):
407 """Remove a file section."""
408 existed
= section
in self
._sections
410 del self
._sections
[section
]
414 # Regular expressions for parsing section headers and options.
416 SECTCRE
= re
.compile(
418 r
'(?P<header>[^]]+)' # very permissive!
422 r
'(?P<option>[^:=\s][^:=]*)' # very permissive!
423 r
'\s*(?P<vi>[:=])\s*' # any number of space/tab,
424 # followed by separator
425 # (either : or =), followed
427 r
'(?P<value>.*)$' # everything up to eol
430 def _read(self
, fp
, fpname
):
431 """Parse a sectioned setup file.
433 The sections in setup file contains a title line at the top,
434 indicated by a name in square brackets (`[]'), plus key/value
435 options lines, indicated by `name: value' format lines.
436 Continuations are represented by an embedded newline then
437 leading whitespace. Blank lines, lines beginning with a '#',
438 and just about everything else are ignored.
440 cursect
= None # None, or a dictionary
443 e
= None # None, or an exception
449 # comment or blank line?
450 if line
.strip() == '' or line
[0] in '#;':
452 if line
.split(None, 1)[0].lower() == 'rem' and line
[0] in "rR":
453 # no leading whitespace
456 if line
[0].isspace() and cursect
is not None and optname
:
459 cursect
[optname
] = "%s\n%s" % (cursect
[optname
], value
)
460 # a section header or option header?
462 # is it a section header?
463 mo
= self
.SECTCRE
.match(line
)
465 sectname
= mo
.group('header')
466 if sectname
in self
._sections
:
467 cursect
= self
._sections
[sectname
]
468 elif sectname
== DEFAULTSECT
:
469 cursect
= self
._defaults
471 cursect
= self
._dict
()
472 cursect
['__name__'] = sectname
473 self
._sections
[sectname
] = cursect
474 # So sections can't start with a continuation line
476 # no section header in the file?
477 elif cursect
is None:
478 raise MissingSectionHeaderError(fpname
, lineno
, line
)
481 mo
= self
.OPTCRE
.match(line
)
483 optname
, vi
, optval
= mo
.group('option', 'vi', 'value')
484 if vi
in ('=', ':') and ';' in optval
:
485 # ';' is a comment delimiter only if it follows
486 # a spacing character
487 pos
= optval
.find(';')
488 if pos
!= -1 and optval
[pos
-1].isspace():
489 optval
= optval
[:pos
]
490 optval
= optval
.strip()
494 optname
= self
.optionxform(optname
.rstrip())
495 cursect
[optname
] = optval
497 # a non-fatal parsing error occurred. set up the
498 # exception but keep going. the exception will be
499 # raised at the end of the file and will contain a
500 # list of all bogus lines
502 e
= ParsingError(fpname
)
503 e
.append(lineno
, repr(line
))
504 # if any parsing errors occurred, raise an exception
509 class ConfigParser(RawConfigParser
):
511 def get(self
, section
, option
, raw
=False, vars=None):
512 """Get an option value for a given section.
514 All % interpolations are expanded in the return values, based on the
515 defaults passed into the constructor, unless the optional argument
516 `raw' is true. Additional substitutions may be provided using the
517 `vars' argument, which must be a dictionary whose contents overrides
518 any pre-existing defaults.
520 The section DEFAULT is special.
522 d
= self
._defaults
.copy()
524 d
.update(self
._sections
[section
])
526 if section
!= DEFAULTSECT
:
527 raise NoSectionError(section
)
528 # Update with the entry specific variables
530 for key
, value
in vars.items():
531 d
[self
.optionxform(key
)] = value
532 option
= self
.optionxform(option
)
536 raise NoOptionError(option
, section
)
541 return self
._interpolate
(section
, option
, value
, d
)
543 def items(self
, section
, raw
=False, vars=None):
544 """Return a list of tuples with (name, value) for each option
547 All % interpolations are expanded in the return values, based on the
548 defaults passed into the constructor, unless the optional argument
549 `raw' is true. Additional substitutions may be provided using the
550 `vars' argument, which must be a dictionary whose contents overrides
551 any pre-existing defaults.
553 The section DEFAULT is special.
555 d
= self
._defaults
.copy()
557 d
.update(self
._sections
[section
])
559 if section
!= DEFAULTSECT
:
560 raise NoSectionError(section
)
561 # Update with the entry specific variables
563 for key
, value
in vars.items():
564 d
[self
.optionxform(key
)] = value
566 if "__name__" in options
:
567 options
.remove("__name__")
569 return [(option
, d
[option
])
570 for option
in options
]
572 return [(option
, self
._interpolate
(section
, option
, d
[option
], d
))
573 for option
in options
]
575 def _interpolate(self
, section
, option
, rawval
, vars):
576 # do the string interpolation
578 depth
= MAX_INTERPOLATION_DEPTH
579 while depth
: # Loop through this until it's done
582 value
= self
._KEYCRE
.sub(self
._interpolation
_replace
, value
)
586 raise InterpolationMissingOptionError(
587 option
, section
, rawval
, e
[0])
591 raise InterpolationDepthError(option
, section
, rawval
)
594 _KEYCRE
= re
.compile(r
"%\(([^)]*)\)s|.")
596 def _interpolation_replace(self
, match
):
601 return "%%(%s)s" % self
.optionxform(s
)
604 class SafeConfigParser(ConfigParser
):
606 def _interpolate(self
, section
, option
, rawval
, vars):
607 # do the string interpolation
609 self
._interpolate
_some
(option
, L
, rawval
, section
, vars, 1)
612 _interpvar_re
= re
.compile(r
"%\(([^)]+)\)s")
613 _badpercent_re
= re
.compile(r
"%[^%]|%$")
615 def _interpolate_some(self
, option
, accum
, rest
, section
, map, depth
):
616 if depth
> MAX_INTERPOLATION_DEPTH
:
617 raise InterpolationDepthError(option
, section
, rest
)
624 accum
.append(rest
[:p
])
626 # p is no longer used
632 m
= self
._interpvar
_re
.match(rest
)
634 raise InterpolationSyntaxError(option
, section
,
635 "bad interpolation variable reference %r" % rest
)
636 var
= self
.optionxform(m
.group(1))
637 rest
= rest
[m
.end():]
641 raise InterpolationMissingOptionError(
642 option
, section
, rest
, var
)
644 self
._interpolate
_some
(option
, accum
, v
,
645 section
, map, depth
+ 1)
649 raise InterpolationSyntaxError(
651 "'%%' must be followed by '%%' or '(', found: %r" % (rest
,))
653 def set(self
, section
, option
, value
):
654 """Set an option. Extend ConfigParser.set: check for string values."""
655 if not isinstance(value
, basestring
):
656 raise TypeError("option values must be strings")
657 # check for bad percent signs:
658 # first, replace all "good" interpolations
659 tmp_value
= self
._interpvar
_re
.sub('', value
)
660 # then, check if there's a lone percent sign left
661 m
= self
._badpercent
_re
.search(tmp_value
)
663 raise ValueError("invalid interpolation syntax in %r at "
664 "position %d" % (value
, m
.start()))
665 ConfigParser
.set(self
, section
, option
, value
)