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
91 from collections
import OrderedDict
as _default_dict
93 # fallback for setup.py which hasn't yet built _collections
98 __all__
= ["NoSectionError", "DuplicateSectionError", "NoOptionError",
99 "InterpolationError", "InterpolationDepthError",
100 "InterpolationSyntaxError", "ParsingError",
101 "MissingSectionHeaderError",
102 "ConfigParser", "SafeConfigParser", "RawConfigParser",
103 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
105 DEFAULTSECT
= "DEFAULT"
107 MAX_INTERPOLATION_DEPTH
= 10
112 class Error(Exception):
113 """Base class for ConfigParser exceptions."""
115 def _get_message(self
):
116 """Getter for 'message'; needed only to override deprecation in
118 return self
.__message
120 def _set_message(self
, value
):
121 """Setter for 'message'; needed only to override deprecation in
123 self
.__message
= value
125 # BaseException.message has been deprecated since Python 2.6. To prevent
126 # DeprecationWarning from popping up over this pre-existing attribute, use
127 # a new property that takes lookup precedence.
128 message
= property(_get_message
, _set_message
)
130 def __init__(self
, msg
=''):
132 Exception.__init
__(self
, msg
)
139 class NoSectionError(Error
):
140 """Raised when no section matches a requested option."""
142 def __init__(self
, section
):
143 Error
.__init
__(self
, 'No section: %r' % (section
,))
144 self
.section
= section
146 class DuplicateSectionError(Error
):
147 """Raised when a section is multiply-created."""
149 def __init__(self
, section
):
150 Error
.__init
__(self
, "Section %r already exists" % section
)
151 self
.section
= section
153 class NoOptionError(Error
):
154 """A requested option was not found."""
156 def __init__(self
, option
, section
):
157 Error
.__init
__(self
, "No option %r in section: %r" %
160 self
.section
= section
162 class InterpolationError(Error
):
163 """Base class for interpolation-related exceptions."""
165 def __init__(self
, option
, section
, msg
):
166 Error
.__init
__(self
, msg
)
168 self
.section
= section
170 class InterpolationMissingOptionError(InterpolationError
):
171 """A string substitution required a setting which was not available."""
173 def __init__(self
, option
, section
, rawval
, reference
):
174 msg
= ("Bad value substitution:\n"
179 % (section
, option
, reference
, rawval
))
180 InterpolationError
.__init
__(self
, option
, section
, msg
)
181 self
.reference
= reference
183 class InterpolationSyntaxError(InterpolationError
):
184 """Raised when the source text into which substitutions are made
185 does not conform to the required syntax."""
187 class InterpolationDepthError(InterpolationError
):
188 """Raised when substitutions are nested too deeply."""
190 def __init__(self
, option
, section
, rawval
):
191 msg
= ("Value interpolation too deeply recursive:\n"
195 % (section
, option
, rawval
))
196 InterpolationError
.__init
__(self
, option
, section
, msg
)
198 class ParsingError(Error
):
199 """Raised when a configuration file does not follow legal syntax."""
201 def __init__(self
, filename
):
202 Error
.__init
__(self
, 'File contains parsing errors: %s' % filename
)
203 self
.filename
= filename
206 def append(self
, lineno
, line
):
207 self
.errors
.append((lineno
, line
))
208 self
.message
+= '\n\t[line %2d]: %s' % (lineno
, line
)
210 class MissingSectionHeaderError(ParsingError
):
211 """Raised when a key-value pair is found before any section header."""
213 def __init__(self
, filename
, lineno
, line
):
216 'File contains no section headers.\nfile: %s, line: %d\n%r' %
217 (filename
, lineno
, line
))
218 self
.filename
= filename
223 class RawConfigParser
:
224 def __init__(self
, defaults
=None, dict_type
=_default_dict
):
225 self
._dict
= dict_type
226 self
._sections
= self
._dict
()
227 self
._defaults
= self
._dict
()
229 for key
, value
in defaults
.items():
230 self
._defaults
[self
.optionxform(key
)] = value
233 return self
._defaults
236 """Return a list of section names, excluding [DEFAULT]"""
237 # self._sections will never have [DEFAULT] in it
238 return self
._sections
.keys()
240 def add_section(self
, section
):
241 """Create a new section in the configuration.
243 Raise DuplicateSectionError if a section by the specified name
244 already exists. Raise ValueError if name is DEFAULT or any of it's
245 case-insensitive variants.
247 if section
.lower() == "default":
248 raise ValueError, 'Invalid section name: %s' % section
250 if section
in self
._sections
:
251 raise DuplicateSectionError(section
)
252 self
._sections
[section
] = self
._dict
()
254 def has_section(self
, section
):
255 """Indicate whether the named section is present in the configuration.
257 The DEFAULT section is not acknowledged.
259 return section
in self
._sections
261 def options(self
, section
):
262 """Return a list of option names for the given section name."""
264 opts
= self
._sections
[section
].copy()
266 raise NoSectionError(section
)
267 opts
.update(self
._defaults
)
268 if '__name__' in opts
:
272 def read(self
, filenames
):
273 """Read and parse a filename or a list of filenames.
275 Files that cannot be opened are silently ignored; this is
276 designed so that you can specify a list of potential
277 configuration file locations (e.g. current directory, user's
278 home directory, systemwide directory), and all existing
279 configuration files in the list will be read. A single
280 filename may also be given.
282 Return list of successfully read files.
284 if isinstance(filenames
, basestring
):
285 filenames
= [filenames
]
287 for filename
in filenames
:
292 self
._read
(fp
, filename
)
294 read_ok
.append(filename
)
297 def readfp(self
, fp
, filename
=None):
298 """Like read() but the argument must be a file-like object.
300 The `fp' argument must have a `readline' method. Optional
301 second argument is the `filename', which if not given, is
302 taken from fp.name. If fp has no `name' attribute, `<???>' is
309 except AttributeError:
311 self
._read
(fp
, filename
)
313 def get(self
, section
, option
):
314 opt
= self
.optionxform(option
)
315 if section
not in self
._sections
:
316 if section
!= DEFAULTSECT
:
317 raise NoSectionError(section
)
318 if opt
in self
._defaults
:
319 return self
._defaults
[opt
]
321 raise NoOptionError(option
, section
)
322 elif opt
in self
._sections
[section
]:
323 return self
._sections
[section
][opt
]
324 elif opt
in self
._defaults
:
325 return self
._defaults
[opt
]
327 raise NoOptionError(option
, section
)
329 def items(self
, section
):
331 d2
= self
._sections
[section
]
333 if section
!= DEFAULTSECT
:
334 raise NoSectionError(section
)
336 d
= self
._defaults
.copy()
342 def _get(self
, section
, conv
, option
):
343 return conv(self
.get(section
, option
))
345 def getint(self
, section
, option
):
346 return self
._get
(section
, int, option
)
348 def getfloat(self
, section
, option
):
349 return self
._get
(section
, float, option
)
351 _boolean_states
= {'1': True, 'yes': True, 'true': True, 'on': True,
352 '0': False, 'no': False, 'false': False, 'off': False}
354 def getboolean(self
, section
, option
):
355 v
= self
.get(section
, option
)
356 if v
.lower() not in self
._boolean
_states
:
357 raise ValueError, 'Not a boolean: %s' % v
358 return self
._boolean
_states
[v
.lower()]
360 def optionxform(self
, optionstr
):
361 return optionstr
.lower()
363 def has_option(self
, section
, option
):
364 """Check for the existence of a given option in a given section."""
365 if not section
or section
== DEFAULTSECT
:
366 option
= self
.optionxform(option
)
367 return option
in self
._defaults
368 elif section
not in self
._sections
:
371 option
= self
.optionxform(option
)
372 return (option
in self
._sections
[section
]
373 or option
in self
._defaults
)
375 def set(self
, section
, option
, value
):
377 if not section
or section
== DEFAULTSECT
:
378 sectdict
= self
._defaults
381 sectdict
= self
._sections
[section
]
383 raise NoSectionError(section
)
384 sectdict
[self
.optionxform(option
)] = value
387 """Write an .ini-format representation of the configuration state."""
389 fp
.write("[%s]\n" % DEFAULTSECT
)
390 for (key
, value
) in self
._defaults
.items():
391 fp
.write("%s = %s\n" % (key
, str(value
).replace('\n', '\n\t')))
393 for section
in self
._sections
:
394 fp
.write("[%s]\n" % section
)
395 for (key
, value
) in self
._sections
[section
].items():
396 if key
!= "__name__":
397 fp
.write("%s = %s\n" %
398 (key
, str(value
).replace('\n', '\n\t')))
401 def remove_option(self
, section
, option
):
402 """Remove an option."""
403 if not section
or section
== DEFAULTSECT
:
404 sectdict
= self
._defaults
407 sectdict
= self
._sections
[section
]
409 raise NoSectionError(section
)
410 option
= self
.optionxform(option
)
411 existed
= option
in sectdict
416 def remove_section(self
, section
):
417 """Remove a file section."""
418 existed
= section
in self
._sections
420 del self
._sections
[section
]
424 # Regular expressions for parsing section headers and options.
426 SECTCRE
= re
.compile(
428 r
'(?P<header>[^]]+)' # very permissive!
432 r
'(?P<option>[^:=\s][^:=]*)' # very permissive!
433 r
'\s*(?P<vi>[:=])\s*' # any number of space/tab,
434 # followed by separator
435 # (either : or =), followed
437 r
'(?P<value>.*)$' # everything up to eol
440 def _read(self
, fp
, fpname
):
441 """Parse a sectioned setup file.
443 The sections in setup file contains a title line at the top,
444 indicated by a name in square brackets (`[]'), plus key/value
445 options lines, indicated by `name: value' format lines.
446 Continuations are represented by an embedded newline then
447 leading whitespace. Blank lines, lines beginning with a '#',
448 and just about everything else are ignored.
450 cursect
= None # None, or a dictionary
453 e
= None # None, or an exception
459 # comment or blank line?
460 if line
.strip() == '' or line
[0] in '#;':
462 if line
.split(None, 1)[0].lower() == 'rem' and line
[0] in "rR":
463 # no leading whitespace
466 if line
[0].isspace() and cursect
is not None and optname
:
469 cursect
[optname
] = "%s\n%s" % (cursect
[optname
], value
)
470 # a section header or option header?
472 # is it a section header?
473 mo
= self
.SECTCRE
.match(line
)
475 sectname
= mo
.group('header')
476 if sectname
in self
._sections
:
477 cursect
= self
._sections
[sectname
]
478 elif sectname
== DEFAULTSECT
:
479 cursect
= self
._defaults
481 cursect
= self
._dict
()
482 cursect
['__name__'] = sectname
483 self
._sections
[sectname
] = cursect
484 # So sections can't start with a continuation line
486 # no section header in the file?
487 elif cursect
is None:
488 raise MissingSectionHeaderError(fpname
, lineno
, line
)
491 mo
= self
.OPTCRE
.match(line
)
493 optname
, vi
, optval
= mo
.group('option', 'vi', 'value')
494 if vi
in ('=', ':') and ';' in optval
:
495 # ';' is a comment delimiter only if it follows
496 # a spacing character
497 pos
= optval
.find(';')
498 if pos
!= -1 and optval
[pos
-1].isspace():
499 optval
= optval
[:pos
]
500 optval
= optval
.strip()
504 optname
= self
.optionxform(optname
.rstrip())
505 cursect
[optname
] = optval
507 # a non-fatal parsing error occurred. set up the
508 # exception but keep going. the exception will be
509 # raised at the end of the file and will contain a
510 # list of all bogus lines
512 e
= ParsingError(fpname
)
513 e
.append(lineno
, repr(line
))
514 # if any parsing errors occurred, raise an exception
519 class ConfigParser(RawConfigParser
):
521 def get(self
, section
, option
, raw
=False, vars=None):
522 """Get an option value for a given section.
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
540 for key
, value
in vars.items():
541 d
[self
.optionxform(key
)] = value
542 option
= self
.optionxform(option
)
546 raise NoOptionError(option
, section
)
551 return self
._interpolate
(section
, option
, value
, d
)
553 def items(self
, section
, raw
=False, vars=None):
554 """Return a list of tuples with (name, value) for each option
557 All % interpolations are expanded in the return values, based on the
558 defaults passed into the constructor, unless the optional argument
559 `raw' is true. Additional substitutions may be provided using the
560 `vars' argument, which must be a dictionary whose contents overrides
561 any pre-existing defaults.
563 The section DEFAULT is special.
565 d
= self
._defaults
.copy()
567 d
.update(self
._sections
[section
])
569 if section
!= DEFAULTSECT
:
570 raise NoSectionError(section
)
571 # Update with the entry specific variables
573 for key
, value
in vars.items():
574 d
[self
.optionxform(key
)] = value
576 if "__name__" in options
:
577 options
.remove("__name__")
579 return [(option
, d
[option
])
580 for option
in options
]
582 return [(option
, self
._interpolate
(section
, option
, d
[option
], d
))
583 for option
in options
]
585 def _interpolate(self
, section
, option
, rawval
, vars):
586 # do the string interpolation
588 depth
= MAX_INTERPOLATION_DEPTH
589 while depth
: # Loop through this until it's done
592 value
= self
._KEYCRE
.sub(self
._interpolation
_replace
, value
)
596 raise InterpolationMissingOptionError(
597 option
, section
, rawval
, e
.args
[0])
601 raise InterpolationDepthError(option
, section
, rawval
)
604 _KEYCRE
= re
.compile(r
"%\(([^)]*)\)s|.")
606 def _interpolation_replace(self
, match
):
611 return "%%(%s)s" % self
.optionxform(s
)
614 class SafeConfigParser(ConfigParser
):
616 def _interpolate(self
, section
, option
, rawval
, vars):
617 # do the string interpolation
619 self
._interpolate
_some
(option
, L
, rawval
, section
, vars, 1)
622 _interpvar_re
= re
.compile(r
"%\(([^)]+)\)s")
624 def _interpolate_some(self
, option
, accum
, rest
, section
, map, depth
):
625 if depth
> MAX_INTERPOLATION_DEPTH
:
626 raise InterpolationDepthError(option
, section
, rest
)
633 accum
.append(rest
[:p
])
635 # p is no longer used
641 m
= self
._interpvar
_re
.match(rest
)
643 raise InterpolationSyntaxError(option
, section
,
644 "bad interpolation variable reference %r" % rest
)
645 var
= self
.optionxform(m
.group(1))
646 rest
= rest
[m
.end():]
650 raise InterpolationMissingOptionError(
651 option
, section
, rest
, var
)
653 self
._interpolate
_some
(option
, accum
, v
,
654 section
, map, depth
+ 1)
658 raise InterpolationSyntaxError(
660 "'%%' must be followed by '%%' or '(', found: %r" % (rest
,))
662 def set(self
, section
, option
, value
):
663 """Set an option. Extend ConfigParser.set: check for string values."""
664 if not isinstance(value
, basestring
):
665 raise TypeError("option values must be strings")
666 # check for bad percent signs:
667 # first, replace all "good" interpolations
668 tmp_value
= value
.replace('%%', '')
669 tmp_value
= self
._interpvar
_re
.sub('', tmp_value
)
670 # then, check if there's a lone percent sign left
671 percent_index
= tmp_value
.find('%')
672 if percent_index
!= -1:
673 raise ValueError("invalid interpolation syntax in %r at "
674 "position %d" % (value
, percent_index
))
675 ConfigParser
.set(self
, section
, option
, value
)