Update to 2.7.3
[profile/ivi/python.git] / Lib / ConfigParser.py
1 """Configuration file parser.
2
3 A setup file consists of sections, lead by a "[section]" header,
4 and followed by "name: value" entries, with continuations and such in
5 the style of RFC 822.
6
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.
9
10 For example:
11
12     something: %(dir)s/whatever
13
14 would resolve the "%(dir)s" to the value of dir.  All reference
15 expansions are done late, on demand.
16
17 Intrinsic defaults can be specified by passing them into the
18 ConfigParser constructor as a dictionary.
19
20 class:
21
22 ConfigParser -- responsible for parsing a list of
23                 configuration files, and managing the parsed database.
24
25     methods:
26
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.
32
33     sections()
34         return all the configuration section names, sans DEFAULT
35
36     has_section(section)
37         return whether the given section exists
38
39     has_option(section, option)
40         return whether the given option exists in the given section
41
42     options(section)
43         return list of configuration options for the named section
44
45     read(filenames)
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.
49
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).
54
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.
61
62     getint(section, options)
63         like get(), but convert value to an integer
64
65     getfloat(section, options)
66         like get(), but convert value to a float
67
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.
72
73     items(section, raw=False, vars=None)
74         return a list of tuples with (name, value) for each option
75         in the section.
76
77     remove_section(section)
78         remove the given file section and all its options
79
80     remove_option(section, option)
81         remove the given option from the given section
82
83     set(section, option, value)
84         set the given option
85
86     write(fp)
87         write the configuration state in .ini format
88 """
89
90 try:
91     from collections import OrderedDict as _default_dict
92 except ImportError:
93     # fallback for setup.py which hasn't yet built _collections
94     _default_dict = dict
95
96 import re
97
98 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
99            "InterpolationError", "InterpolationDepthError",
100            "InterpolationSyntaxError", "ParsingError",
101            "MissingSectionHeaderError",
102            "ConfigParser", "SafeConfigParser", "RawConfigParser",
103            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
104
105 DEFAULTSECT = "DEFAULT"
106
107 MAX_INTERPOLATION_DEPTH = 10
108
109
110
111 # exception classes
112 class Error(Exception):
113     """Base class for ConfigParser exceptions."""
114
115     def _get_message(self):
116         """Getter for 'message'; needed only to override deprecation in
117         BaseException."""
118         return self.__message
119
120     def _set_message(self, value):
121         """Setter for 'message'; needed only to override deprecation in
122         BaseException."""
123         self.__message = value
124
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)
129
130     def __init__(self, msg=''):
131         self.message = msg
132         Exception.__init__(self, msg)
133
134     def __repr__(self):
135         return self.message
136
137     __str__ = __repr__
138
139 class NoSectionError(Error):
140     """Raised when no section matches a requested option."""
141
142     def __init__(self, section):
143         Error.__init__(self, 'No section: %r' % (section,))
144         self.section = section
145         self.args = (section, )
146
147 class DuplicateSectionError(Error):
148     """Raised when a section is multiply-created."""
149
150     def __init__(self, section):
151         Error.__init__(self, "Section %r already exists" % section)
152         self.section = section
153         self.args = (section, )
154
155 class NoOptionError(Error):
156     """A requested option was not found."""
157
158     def __init__(self, option, section):
159         Error.__init__(self, "No option %r in section: %r" %
160                        (option, section))
161         self.option = option
162         self.section = section
163         self.args = (option, section)
164
165 class InterpolationError(Error):
166     """Base class for interpolation-related exceptions."""
167
168     def __init__(self, option, section, msg):
169         Error.__init__(self, msg)
170         self.option = option
171         self.section = section
172         self.args = (option, section, msg)
173
174 class InterpolationMissingOptionError(InterpolationError):
175     """A string substitution required a setting which was not available."""
176
177     def __init__(self, option, section, rawval, reference):
178         msg = ("Bad value substitution:\n"
179                "\tsection: [%s]\n"
180                "\toption : %s\n"
181                "\tkey    : %s\n"
182                "\trawval : %s\n"
183                % (section, option, reference, rawval))
184         InterpolationError.__init__(self, option, section, msg)
185         self.reference = reference
186         self.args = (option, section, rawval, reference)
187
188 class InterpolationSyntaxError(InterpolationError):
189     """Raised when the source text into which substitutions are made
190     does not conform to the required syntax."""
191
192 class InterpolationDepthError(InterpolationError):
193     """Raised when substitutions are nested too deeply."""
194
195     def __init__(self, option, section, rawval):
196         msg = ("Value interpolation too deeply recursive:\n"
197                "\tsection: [%s]\n"
198                "\toption : %s\n"
199                "\trawval : %s\n"
200                % (section, option, rawval))
201         InterpolationError.__init__(self, option, section, msg)
202         self.args = (option, section, rawval)
203
204 class ParsingError(Error):
205     """Raised when a configuration file does not follow legal syntax."""
206
207     def __init__(self, filename):
208         Error.__init__(self, 'File contains parsing errors: %s' % filename)
209         self.filename = filename
210         self.errors = []
211         self.args = (filename, )
212
213     def append(self, lineno, line):
214         self.errors.append((lineno, line))
215         self.message += '\n\t[line %2d]: %s' % (lineno, line)
216
217 class MissingSectionHeaderError(ParsingError):
218     """Raised when a key-value pair is found before any section header."""
219
220     def __init__(self, filename, lineno, line):
221         Error.__init__(
222             self,
223             'File contains no section headers.\nfile: %s, line: %d\n%r' %
224             (filename, lineno, line))
225         self.filename = filename
226         self.lineno = lineno
227         self.line = line
228         self.args = (filename, lineno, line)
229
230
231 class RawConfigParser:
232     def __init__(self, defaults=None, dict_type=_default_dict,
233                  allow_no_value=False):
234         self._dict = dict_type
235         self._sections = self._dict()
236         self._defaults = self._dict()
237         if allow_no_value:
238             self._optcre = self.OPTCRE_NV
239         else:
240             self._optcre = self.OPTCRE
241         if defaults:
242             for key, value in defaults.items():
243                 self._defaults[self.optionxform(key)] = value
244
245     def defaults(self):
246         return self._defaults
247
248     def sections(self):
249         """Return a list of section names, excluding [DEFAULT]"""
250         # self._sections will never have [DEFAULT] in it
251         return self._sections.keys()
252
253     def add_section(self, section):
254         """Create a new section in the configuration.
255
256         Raise DuplicateSectionError if a section by the specified name
257         already exists. Raise ValueError if name is DEFAULT or any of it's
258         case-insensitive variants.
259         """
260         if section.lower() == "default":
261             raise ValueError, 'Invalid section name: %s' % section
262
263         if section in self._sections:
264             raise DuplicateSectionError(section)
265         self._sections[section] = self._dict()
266
267     def has_section(self, section):
268         """Indicate whether the named section is present in the configuration.
269
270         The DEFAULT section is not acknowledged.
271         """
272         return section in self._sections
273
274     def options(self, section):
275         """Return a list of option names for the given section name."""
276         try:
277             opts = self._sections[section].copy()
278         except KeyError:
279             raise NoSectionError(section)
280         opts.update(self._defaults)
281         if '__name__' in opts:
282             del opts['__name__']
283         return opts.keys()
284
285     def read(self, filenames):
286         """Read and parse a filename or a list of filenames.
287
288         Files that cannot be opened are silently ignored; this is
289         designed so that you can specify a list of potential
290         configuration file locations (e.g. current directory, user's
291         home directory, systemwide directory), and all existing
292         configuration files in the list will be read.  A single
293         filename may also be given.
294
295         Return list of successfully read files.
296         """
297         if isinstance(filenames, basestring):
298             filenames = [filenames]
299         read_ok = []
300         for filename in filenames:
301             try:
302                 fp = open(filename)
303             except IOError:
304                 continue
305             self._read(fp, filename)
306             fp.close()
307             read_ok.append(filename)
308         return read_ok
309
310     def readfp(self, fp, filename=None):
311         """Like read() but the argument must be a file-like object.
312
313         The `fp' argument must have a `readline' method.  Optional
314         second argument is the `filename', which if not given, is
315         taken from fp.name.  If fp has no `name' attribute, `<???>' is
316         used.
317
318         """
319         if filename is None:
320             try:
321                 filename = fp.name
322             except AttributeError:
323                 filename = '<???>'
324         self._read(fp, filename)
325
326     def get(self, section, option):
327         opt = self.optionxform(option)
328         if section not in self._sections:
329             if section != DEFAULTSECT:
330                 raise NoSectionError(section)
331             if opt in self._defaults:
332                 return self._defaults[opt]
333             else:
334                 raise NoOptionError(option, section)
335         elif opt in self._sections[section]:
336             return self._sections[section][opt]
337         elif opt in self._defaults:
338             return self._defaults[opt]
339         else:
340             raise NoOptionError(option, section)
341
342     def items(self, section):
343         try:
344             d2 = self._sections[section]
345         except KeyError:
346             if section != DEFAULTSECT:
347                 raise NoSectionError(section)
348             d2 = self._dict()
349         d = self._defaults.copy()
350         d.update(d2)
351         if "__name__" in d:
352             del d["__name__"]
353         return d.items()
354
355     def _get(self, section, conv, option):
356         return conv(self.get(section, option))
357
358     def getint(self, section, option):
359         return self._get(section, int, option)
360
361     def getfloat(self, section, option):
362         return self._get(section, float, option)
363
364     _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
365                        '0': False, 'no': False, 'false': False, 'off': False}
366
367     def getboolean(self, section, option):
368         v = self.get(section, option)
369         if v.lower() not in self._boolean_states:
370             raise ValueError, 'Not a boolean: %s' % v
371         return self._boolean_states[v.lower()]
372
373     def optionxform(self, optionstr):
374         return optionstr.lower()
375
376     def has_option(self, section, option):
377         """Check for the existence of a given option in a given section."""
378         if not section or section == DEFAULTSECT:
379             option = self.optionxform(option)
380             return option in self._defaults
381         elif section not in self._sections:
382             return False
383         else:
384             option = self.optionxform(option)
385             return (option in self._sections[section]
386                     or option in self._defaults)
387
388     def set(self, section, option, value=None):
389         """Set an option."""
390         if not section or section == DEFAULTSECT:
391             sectdict = self._defaults
392         else:
393             try:
394                 sectdict = self._sections[section]
395             except KeyError:
396                 raise NoSectionError(section)
397         sectdict[self.optionxform(option)] = value
398
399     def write(self, fp):
400         """Write an .ini-format representation of the configuration state."""
401         if self._defaults:
402             fp.write("[%s]\n" % DEFAULTSECT)
403             for (key, value) in self._defaults.items():
404                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
405             fp.write("\n")
406         for section in self._sections:
407             fp.write("[%s]\n" % section)
408             for (key, value) in self._sections[section].items():
409                 if key == "__name__":
410                     continue
411                 if (value is not None) or (self._optcre == self.OPTCRE):
412                     key = " = ".join((key, str(value).replace('\n', '\n\t')))
413                 fp.write("%s\n" % (key))
414             fp.write("\n")
415
416     def remove_option(self, section, option):
417         """Remove an option."""
418         if not section or section == DEFAULTSECT:
419             sectdict = self._defaults
420         else:
421             try:
422                 sectdict = self._sections[section]
423             except KeyError:
424                 raise NoSectionError(section)
425         option = self.optionxform(option)
426         existed = option in sectdict
427         if existed:
428             del sectdict[option]
429         return existed
430
431     def remove_section(self, section):
432         """Remove a file section."""
433         existed = section in self._sections
434         if existed:
435             del self._sections[section]
436         return existed
437
438     #
439     # Regular expressions for parsing section headers and options.
440     #
441     SECTCRE = re.compile(
442         r'\['                                 # [
443         r'(?P<header>[^]]+)'                  # very permissive!
444         r'\]'                                 # ]
445         )
446     OPTCRE = re.compile(
447         r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
448         r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
449                                               # followed by separator
450                                               # (either : or =), followed
451                                               # by any # space/tab
452         r'(?P<value>.*)$'                     # everything up to eol
453         )
454     OPTCRE_NV = re.compile(
455         r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
456         r'\s*(?:'                             # any number of space/tab,
457         r'(?P<vi>[:=])\s*'                    # optionally followed by
458                                               # separator (either : or
459                                               # =), followed by any #
460                                               # space/tab
461         r'(?P<value>.*))?$'                   # everything up to eol
462         )
463
464     def _read(self, fp, fpname):
465         """Parse a sectioned setup file.
466
467         The sections in setup file contains a title line at the top,
468         indicated by a name in square brackets (`[]'), plus key/value
469         options lines, indicated by `name: value' format lines.
470         Continuations are represented by an embedded newline then
471         leading whitespace.  Blank lines, lines beginning with a '#',
472         and just about everything else are ignored.
473         """
474         cursect = None                        # None, or a dictionary
475         optname = None
476         lineno = 0
477         e = None                              # None, or an exception
478         while True:
479             line = fp.readline()
480             if not line:
481                 break
482             lineno = lineno + 1
483             # comment or blank line?
484             if line.strip() == '' or line[0] in '#;':
485                 continue
486             if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
487                 # no leading whitespace
488                 continue
489             # continuation line?
490             if line[0].isspace() and cursect is not None and optname:
491                 value = line.strip()
492                 if value:
493                     cursect[optname].append(value)
494             # a section header or option header?
495             else:
496                 # is it a section header?
497                 mo = self.SECTCRE.match(line)
498                 if mo:
499                     sectname = mo.group('header')
500                     if sectname in self._sections:
501                         cursect = self._sections[sectname]
502                     elif sectname == DEFAULTSECT:
503                         cursect = self._defaults
504                     else:
505                         cursect = self._dict()
506                         cursect['__name__'] = sectname
507                         self._sections[sectname] = cursect
508                     # So sections can't start with a continuation line
509                     optname = None
510                 # no section header in the file?
511                 elif cursect is None:
512                     raise MissingSectionHeaderError(fpname, lineno, line)
513                 # an option line?
514                 else:
515                     mo = self._optcre.match(line)
516                     if mo:
517                         optname, vi, optval = mo.group('option', 'vi', 'value')
518                         optname = self.optionxform(optname.rstrip())
519                         # This check is fine because the OPTCRE cannot
520                         # match if it would set optval to None
521                         if optval is not None:
522                             if vi in ('=', ':') and ';' in optval:
523                                 # ';' is a comment delimiter only if it follows
524                                 # a spacing character
525                                 pos = optval.find(';')
526                                 if pos != -1 and optval[pos-1].isspace():
527                                     optval = optval[:pos]
528                             optval = optval.strip()
529                             # allow empty values
530                             if optval == '""':
531                                 optval = ''
532                             cursect[optname] = [optval]
533                         else:
534                             # valueless option handling
535                             cursect[optname] = optval
536                     else:
537                         # a non-fatal parsing error occurred.  set up the
538                         # exception but keep going. the exception will be
539                         # raised at the end of the file and will contain a
540                         # list of all bogus lines
541                         if not e:
542                             e = ParsingError(fpname)
543                         e.append(lineno, repr(line))
544         # if any parsing errors occurred, raise an exception
545         if e:
546             raise e
547
548         # join the multi-line values collected while reading
549         all_sections = [self._defaults]
550         all_sections.extend(self._sections.values())
551         for options in all_sections:
552             for name, val in options.items():
553                 if isinstance(val, list):
554                     options[name] = '\n'.join(val)
555
556 import UserDict as _UserDict
557
558 class _Chainmap(_UserDict.DictMixin):
559     """Combine multiple mappings for successive lookups.
560
561     For example, to emulate Python's normal lookup sequence:
562
563         import __builtin__
564         pylookup = _Chainmap(locals(), globals(), vars(__builtin__))
565     """
566
567     def __init__(self, *maps):
568         self._maps = maps
569
570     def __getitem__(self, key):
571         for mapping in self._maps:
572             try:
573                 return mapping[key]
574             except KeyError:
575                 pass
576         raise KeyError(key)
577
578     def keys(self):
579         result = []
580         seen = set()
581         for mapping in self._maps:
582             for key in mapping:
583                 if key not in seen:
584                     result.append(key)
585                     seen.add(key)
586         return result
587
588 class ConfigParser(RawConfigParser):
589
590     def get(self, section, option, raw=False, vars=None):
591         """Get an option value for a given section.
592
593         If `vars' is provided, it must be a dictionary. The option is looked up
594         in `vars' (if provided), `section', and in `defaults' in that order.
595
596         All % interpolations are expanded in the return values, unless the
597         optional argument `raw' is true. Values for interpolation keys are
598         looked up in the same manner as the option.
599
600         The section DEFAULT is special.
601         """
602         sectiondict = {}
603         try:
604             sectiondict = self._sections[section]
605         except KeyError:
606             if section != DEFAULTSECT:
607                 raise NoSectionError(section)
608         # Update with the entry specific variables
609         vardict = {}
610         if vars:
611             for key, value in vars.items():
612                 vardict[self.optionxform(key)] = value
613         d = _Chainmap(vardict, sectiondict, self._defaults)
614         option = self.optionxform(option)
615         try:
616             value = d[option]
617         except KeyError:
618             raise NoOptionError(option, section)
619
620         if raw or value is None:
621             return value
622         else:
623             return self._interpolate(section, option, value, d)
624
625     def items(self, section, raw=False, vars=None):
626         """Return a list of tuples with (name, value) for each option
627         in the section.
628
629         All % interpolations are expanded in the return values, based on the
630         defaults passed into the constructor, unless the optional argument
631         `raw' is true.  Additional substitutions may be provided using the
632         `vars' argument, which must be a dictionary whose contents overrides
633         any pre-existing defaults.
634
635         The section DEFAULT is special.
636         """
637         d = self._defaults.copy()
638         try:
639             d.update(self._sections[section])
640         except KeyError:
641             if section != DEFAULTSECT:
642                 raise NoSectionError(section)
643         # Update with the entry specific variables
644         if vars:
645             for key, value in vars.items():
646                 d[self.optionxform(key)] = value
647         options = d.keys()
648         if "__name__" in options:
649             options.remove("__name__")
650         if raw:
651             return [(option, d[option])
652                     for option in options]
653         else:
654             return [(option, self._interpolate(section, option, d[option], d))
655                     for option in options]
656
657     def _interpolate(self, section, option, rawval, vars):
658         # do the string interpolation
659         value = rawval
660         depth = MAX_INTERPOLATION_DEPTH
661         while depth:                    # Loop through this until it's done
662             depth -= 1
663             if value and "%(" in value:
664                 value = self._KEYCRE.sub(self._interpolation_replace, value)
665                 try:
666                     value = value % vars
667                 except KeyError, e:
668                     raise InterpolationMissingOptionError(
669                         option, section, rawval, e.args[0])
670             else:
671                 break
672         if value and "%(" in value:
673             raise InterpolationDepthError(option, section, rawval)
674         return value
675
676     _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
677
678     def _interpolation_replace(self, match):
679         s = match.group(1)
680         if s is None:
681             return match.group()
682         else:
683             return "%%(%s)s" % self.optionxform(s)
684
685
686 class SafeConfigParser(ConfigParser):
687
688     def _interpolate(self, section, option, rawval, vars):
689         # do the string interpolation
690         L = []
691         self._interpolate_some(option, L, rawval, section, vars, 1)
692         return ''.join(L)
693
694     _interpvar_re = re.compile(r"%\(([^)]+)\)s")
695
696     def _interpolate_some(self, option, accum, rest, section, map, depth):
697         if depth > MAX_INTERPOLATION_DEPTH:
698             raise InterpolationDepthError(option, section, rest)
699         while rest:
700             p = rest.find("%")
701             if p < 0:
702                 accum.append(rest)
703                 return
704             if p > 0:
705                 accum.append(rest[:p])
706                 rest = rest[p:]
707             # p is no longer used
708             c = rest[1:2]
709             if c == "%":
710                 accum.append("%")
711                 rest = rest[2:]
712             elif c == "(":
713                 m = self._interpvar_re.match(rest)
714                 if m is None:
715                     raise InterpolationSyntaxError(option, section,
716                         "bad interpolation variable reference %r" % rest)
717                 var = self.optionxform(m.group(1))
718                 rest = rest[m.end():]
719                 try:
720                     v = map[var]
721                 except KeyError:
722                     raise InterpolationMissingOptionError(
723                         option, section, rest, var)
724                 if "%" in v:
725                     self._interpolate_some(option, accum, v,
726                                            section, map, depth + 1)
727                 else:
728                     accum.append(v)
729             else:
730                 raise InterpolationSyntaxError(
731                     option, section,
732                     "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
733
734     def set(self, section, option, value=None):
735         """Set an option.  Extend ConfigParser.set: check for string values."""
736         # The only legal non-string value if we allow valueless
737         # options is None, so we need to check if the value is a
738         # string if:
739         # - we do not allow valueless options, or
740         # - we allow valueless options but the value is not None
741         if self._optcre is self.OPTCRE or value:
742             if not isinstance(value, basestring):
743                 raise TypeError("option values must be strings")
744         if value is not None:
745             # check for bad percent signs:
746             # first, replace all "good" interpolations
747             tmp_value = value.replace('%%', '')
748             tmp_value = self._interpvar_re.sub('', tmp_value)
749             # then, check if there's a lone percent sign left
750             if '%' in tmp_value:
751                 raise ValueError("invalid interpolation syntax in %r at "
752                                 "position %d" % (value, tmp_value.find('%')))
753         ConfigParser.set(self, section, option, value)