PyXR

c:\python24\lib \ ConfigParser.py



0001 """Configuration file parser.
0002 
0003 A setup file consists of sections, lead by a "[section]" header,
0004 and followed by "name: value" entries, with continuations and such in
0005 the style of RFC 822.
0006 
0007 The option values can contain format strings which refer to other values in
0008 the same section, or values in a special [DEFAULT] section.
0009 
0010 For example:
0011 
0012     something: %(dir)s/whatever
0013 
0014 would resolve the "%(dir)s" to the value of dir.  All reference
0015 expansions are done late, on demand.
0016 
0017 Intrinsic defaults can be specified by passing them into the
0018 ConfigParser constructor as a dictionary.
0019 
0020 class:
0021 
0022 ConfigParser -- responsible for parsing a list of
0023                 configuration files, and managing the parsed database.
0024 
0025     methods:
0026 
0027     __init__(defaults=None)
0028         create the parser and specify a dictionary of intrinsic defaults.  The
0029         keys must be strings, the values must be appropriate for %()s string
0030         interpolation.  Note that `__name__' is always an intrinsic default;
0031         it's value is the section's name.
0032 
0033     sections()
0034         return all the configuration section names, sans DEFAULT
0035 
0036     has_section(section)
0037         return whether the given section exists
0038 
0039     has_option(section, option)
0040         return whether the given option exists in the given section
0041 
0042     options(section)
0043         return list of configuration options for the named section
0044 
0045     read(filenames)
0046         read and parse the list of named configuration files, given by
0047         name.  A single filename is also allowed.  Non-existing files
0048         are ignored.  Return list of successfully read files.
0049 
0050     readfp(fp, filename=None)
0051         read and parse one configuration file, given as a file object.
0052         The filename defaults to fp.name; it is only used in error
0053         messages (if fp has no `name' attribute, the string `<???>' is used).
0054 
0055     get(section, option, raw=False, vars=None)
0056         return a string value for the named option.  All % interpolations are
0057         expanded in the return values, based on the defaults passed into the
0058         constructor and the DEFAULT section.  Additional substitutions may be
0059         provided using the `vars' argument, which must be a dictionary whose
0060         contents override any pre-existing defaults.
0061 
0062     getint(section, options)
0063         like get(), but convert value to an integer
0064 
0065     getfloat(section, options)
0066         like get(), but convert value to a float
0067 
0068     getboolean(section, options)
0069         like get(), but convert value to a boolean (currently case
0070         insensitively defined as 0, false, no, off for False, and 1, true,
0071         yes, on for True).  Returns False or True.
0072 
0073     items(section, raw=False, vars=None)
0074         return a list of tuples with (name, value) for each option
0075         in the section.
0076 
0077     remove_section(section)
0078         remove the given file section and all its options
0079 
0080     remove_option(section, option)
0081         remove the given option from the given section
0082 
0083     set(section, option, value)
0084         set the given option
0085 
0086     write(fp)
0087         write the configuration state in .ini format
0088 """
0089 
0090 import re
0091 
0092 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
0093            "InterpolationError", "InterpolationDepthError",
0094            "InterpolationSyntaxError", "ParsingError",
0095            "MissingSectionHeaderError",
0096            "ConfigParser", "SafeConfigParser", "RawConfigParser",
0097            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
0098 
0099 DEFAULTSECT = "DEFAULT"
0100 
0101 MAX_INTERPOLATION_DEPTH = 10
0102 
0103 
0104 
0105 # exception classes
0106 class Error(Exception):
0107     """Base class for ConfigParser exceptions."""
0108 
0109     def __init__(self, msg=''):
0110         self.message = msg
0111         Exception.__init__(self, msg)
0112 
0113     def __repr__(self):
0114         return self.message
0115 
0116     __str__ = __repr__
0117 
0118 class NoSectionError(Error):
0119     """Raised when no section matches a requested option."""
0120 
0121     def __init__(self, section):
0122         Error.__init__(self, 'No section: %r' % (section,))
0123         self.section = section
0124 
0125 class DuplicateSectionError(Error):
0126     """Raised when a section is multiply-created."""
0127 
0128     def __init__(self, section):
0129         Error.__init__(self, "Section %r already exists" % section)
0130         self.section = section
0131 
0132 class NoOptionError(Error):
0133     """A requested option was not found."""
0134 
0135     def __init__(self, option, section):
0136         Error.__init__(self, "No option %r in section: %r" %
0137                        (option, section))
0138         self.option = option
0139         self.section = section
0140 
0141 class InterpolationError(Error):
0142     """Base class for interpolation-related exceptions."""
0143 
0144     def __init__(self, option, section, msg):
0145         Error.__init__(self, msg)
0146         self.option = option
0147         self.section = section
0148 
0149 class InterpolationMissingOptionError(InterpolationError):
0150     """A string substitution required a setting which was not available."""
0151 
0152     def __init__(self, option, section, rawval, reference):
0153         msg = ("Bad value substitution:\n"
0154                "\tsection: [%s]\n"
0155                "\toption : %s\n"
0156                "\tkey    : %s\n"
0157                "\trawval : %s\n"
0158                % (section, option, reference, rawval))
0159         InterpolationError.__init__(self, option, section, msg)
0160         self.reference = reference
0161 
0162 class InterpolationSyntaxError(InterpolationError):
0163     """Raised when the source text into which substitutions are made
0164     does not conform to the required syntax."""
0165 
0166 class InterpolationDepthError(InterpolationError):
0167     """Raised when substitutions are nested too deeply."""
0168 
0169     def __init__(self, option, section, rawval):
0170         msg = ("Value interpolation too deeply recursive:\n"
0171                "\tsection: [%s]\n"
0172                "\toption : %s\n"
0173                "\trawval : %s\n"
0174                % (section, option, rawval))
0175         InterpolationError.__init__(self, option, section, msg)
0176 
0177 class ParsingError(Error):
0178     """Raised when a configuration file does not follow legal syntax."""
0179 
0180     def __init__(self, filename):
0181         Error.__init__(self, 'File contains parsing errors: %s' % filename)
0182         self.filename = filename
0183         self.errors = []
0184 
0185     def append(self, lineno, line):
0186         self.errors.append((lineno, line))
0187         self.message += '\n\t[line %2d]: %s' % (lineno, line)
0188 
0189 class MissingSectionHeaderError(ParsingError):
0190     """Raised when a key-value pair is found before any section header."""
0191 
0192     def __init__(self, filename, lineno, line):
0193         Error.__init__(
0194             self,
0195             'File contains no section headers.\nfile: %s, line: %d\n%r' %
0196             (filename, lineno, line))
0197         self.filename = filename
0198         self.lineno = lineno
0199         self.line = line
0200 
0201 
0202 
0203 class RawConfigParser:
0204     def __init__(self, defaults=None):
0205         self._sections = {}
0206         self._defaults = {}
0207         if defaults:
0208             for key, value in defaults.items():
0209                 self._defaults[self.optionxform(key)] = value
0210 
0211     def defaults(self):
0212         return self._defaults
0213 
0214     def sections(self):
0215         """Return a list of section names, excluding [DEFAULT]"""
0216         # self._sections will never have [DEFAULT] in it
0217         return self._sections.keys()
0218 
0219     def add_section(self, section):
0220         """Create a new section in the configuration.
0221 
0222         Raise DuplicateSectionError if a section by the specified name
0223         already exists.
0224         """
0225         if section in self._sections:
0226             raise DuplicateSectionError(section)
0227         self._sections[section] = {}
0228 
0229     def has_section(self, section):
0230         """Indicate whether the named section is present in the configuration.
0231 
0232         The DEFAULT section is not acknowledged.
0233         """
0234         return section in self._sections
0235 
0236     def options(self, section):
0237         """Return a list of option names for the given section name."""
0238         try:
0239             opts = self._sections[section].copy()
0240         except KeyError:
0241             raise NoSectionError(section)
0242         opts.update(self._defaults)
0243         if '__name__' in opts:
0244             del opts['__name__']
0245         return opts.keys()
0246 
0247     def read(self, filenames):
0248         """Read and parse a filename or a list of filenames.
0249 
0250         Files that cannot be opened are silently ignored; this is
0251         designed so that you can specify a list of potential
0252         configuration file locations (e.g. current directory, user's
0253         home directory, systemwide directory), and all existing
0254         configuration files in the list will be read.  A single
0255         filename may also be given.
0256 
0257         Return list of successfully read files.
0258         """
0259         if isinstance(filenames, basestring):
0260             filenames = [filenames]
0261         read_ok = []
0262         for filename in filenames:
0263             try:
0264                 fp = open(filename)
0265             except IOError:
0266                 continue
0267             self._read(fp, filename)
0268             fp.close()
0269             read_ok.append(filename)
0270         return read_ok
0271 
0272     def readfp(self, fp, filename=None):
0273         """Like read() but the argument must be a file-like object.
0274 
0275         The `fp' argument must have a `readline' method.  Optional
0276         second argument is the `filename', which if not given, is
0277         taken from fp.name.  If fp has no `name' attribute, `<???>' is
0278         used.
0279 
0280         """
0281         if filename is None:
0282             try:
0283                 filename = fp.name
0284             except AttributeError:
0285                 filename = '<???>'
0286         self._read(fp, filename)
0287 
0288     def get(self, section, option):
0289         opt = self.optionxform(option)
0290         if section not in self._sections:
0291             if section != DEFAULTSECT:
0292                 raise NoSectionError(section)
0293             if opt in self._defaults:
0294                 return self._defaults[opt]
0295             else:
0296                 raise NoOptionError(option, section)
0297         elif opt in self._sections[section]:
0298             return self._sections[section][opt]
0299         elif opt in self._defaults:
0300             return self._defaults[opt]
0301         else:
0302             raise NoOptionError(option, section)
0303 
0304     def items(self, section):
0305         try:
0306             d2 = self._sections[section]
0307         except KeyError:
0308             if section != DEFAULTSECT:
0309                 raise NoSectionError(section)
0310             d2 = {}
0311         d = self._defaults.copy()
0312         d.update(d2)
0313         if "__name__" in d:
0314             del d["__name__"]
0315         return d.items()
0316 
0317     def _get(self, section, conv, option):
0318         return conv(self.get(section, option))
0319 
0320     def getint(self, section, option):
0321         return self._get(section, int, option)
0322 
0323     def getfloat(self, section, option):
0324         return self._get(section, float, option)
0325 
0326     _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
0327                        '0': False, 'no': False, 'false': False, 'off': False}
0328 
0329     def getboolean(self, section, option):
0330         v = self.get(section, option)
0331         if v.lower() not in self._boolean_states:
0332             raise ValueError, 'Not a boolean: %s' % v
0333         return self._boolean_states[v.lower()]
0334 
0335     def optionxform(self, optionstr):
0336         return optionstr.lower()
0337 
0338     def has_option(self, section, option):
0339         """Check for the existence of a given option in a given section."""
0340         if not section or section == DEFAULTSECT:
0341             option = self.optionxform(option)
0342             return option in self._defaults
0343         elif section not in self._sections:
0344             return False
0345         else:
0346             option = self.optionxform(option)
0347             return (option in self._sections[section]
0348                     or option in self._defaults)
0349 
0350     def set(self, section, option, value):
0351         """Set an option."""
0352         if not section or section == DEFAULTSECT:
0353             sectdict = self._defaults
0354         else:
0355             try:
0356                 sectdict = self._sections[section]
0357             except KeyError:
0358                 raise NoSectionError(section)
0359         sectdict[self.optionxform(option)] = value
0360 
0361     def write(self, fp):
0362         """Write an .ini-format representation of the configuration state."""
0363         if self._defaults:
0364             fp.write("[%s]\n" % DEFAULTSECT)
0365             for (key, value) in self._defaults.items():
0366                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
0367             fp.write("\n")
0368         for section in self._sections:
0369             fp.write("[%s]\n" % section)
0370             for (key, value) in self._sections[section].items():
0371                 if key != "__name__":
0372                     fp.write("%s = %s\n" %
0373                              (key, str(value).replace('\n', '\n\t')))
0374             fp.write("\n")
0375 
0376     def remove_option(self, section, option):
0377         """Remove an option."""
0378         if not section or section == DEFAULTSECT:
0379             sectdict = self._defaults
0380         else:
0381             try:
0382                 sectdict = self._sections[section]
0383             except KeyError:
0384                 raise NoSectionError(section)
0385         option = self.optionxform(option)
0386         existed = option in sectdict
0387         if existed:
0388             del sectdict[option]
0389         return existed
0390 
0391     def remove_section(self, section):
0392         """Remove a file section."""
0393         existed = section in self._sections
0394         if existed:
0395             del self._sections[section]
0396         return existed
0397 
0398     #
0399     # Regular expressions for parsing section headers and options.
0400     #
0401     SECTCRE = re.compile(
0402         r'\['                                 # [
0403         r'(?P<header>[^]]+)'                  # very permissive!
0404         r'\]'                                 # ]
0405         )
0406     OPTCRE = re.compile(
0407         r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
0408         r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
0409                                               # followed by separator
0410                                               # (either : or =), followed
0411                                               # by any # space/tab
0412         r'(?P<value>.*)$'                     # everything up to eol
0413         )
0414 
0415     def _read(self, fp, fpname):
0416         """Parse a sectioned setup file.
0417 
0418         The sections in setup file contains a title line at the top,
0419         indicated by a name in square brackets (`[]'), plus key/value
0420         options lines, indicated by `name: value' format lines.
0421         Continuations are represented by an embedded newline then
0422         leading whitespace.  Blank lines, lines beginning with a '#',
0423         and just about everything else are ignored.
0424         """
0425         cursect = None                            # None, or a dictionary
0426         optname = None
0427         lineno = 0
0428         e = None                                  # None, or an exception
0429         while True:
0430             line = fp.readline()
0431             if not line:
0432                 break
0433             lineno = lineno + 1
0434             # comment or blank line?
0435             if line.strip() == '' or line[0] in '#;':
0436                 continue
0437             if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
0438                 # no leading whitespace
0439                 continue
0440             # continuation line?
0441             if line[0].isspace() and cursect is not None and optname:
0442                 value = line.strip()
0443                 if value:
0444                     cursect[optname] = "%s\n%s" % (cursect[optname], value)
0445             # a section header or option header?
0446             else:
0447                 # is it a section header?
0448                 mo = self.SECTCRE.match(line)
0449                 if mo:
0450                     sectname = mo.group('header')
0451                     if sectname in self._sections:
0452                         cursect = self._sections[sectname]
0453                     elif sectname == DEFAULTSECT:
0454                         cursect = self._defaults
0455                     else:
0456                         cursect = {'__name__': sectname}
0457                         self._sections[sectname] = cursect
0458                     # So sections can't start with a continuation line
0459                     optname = None
0460                 # no section header in the file?
0461                 elif cursect is None:
0462                     raise MissingSectionHeaderError(fpname, lineno, line)
0463                 # an option line?
0464                 else:
0465                     mo = self.OPTCRE.match(line)
0466                     if mo:
0467                         optname, vi, optval = mo.group('option', 'vi', 'value')
0468                         if vi in ('=', ':') and ';' in optval:
0469                             # ';' is a comment delimiter only if it follows
0470                             # a spacing character
0471                             pos = optval.find(';')
0472                             if pos != -1 and optval[pos-1].isspace():
0473                                 optval = optval[:pos]
0474                         optval = optval.strip()
0475                         # allow empty values
0476                         if optval == '""':
0477                             optval = ''
0478                         optname = self.optionxform(optname.rstrip())
0479                         cursect[optname] = optval
0480                     else:
0481                         # a non-fatal parsing error occurred.  set up the
0482                         # exception but keep going. the exception will be
0483                         # raised at the end of the file and will contain a
0484                         # list of all bogus lines
0485                         if not e:
0486                             e = ParsingError(fpname)
0487                         e.append(lineno, repr(line))
0488         # if any parsing errors occurred, raise an exception
0489         if e:
0490             raise e
0491 
0492 
0493 class ConfigParser(RawConfigParser):
0494 
0495     def get(self, section, option, raw=False, vars=None):
0496         """Get an option value for a given section.
0497 
0498         All % interpolations are expanded in the return values, based on the
0499         defaults passed into the constructor, unless the optional argument
0500         `raw' is true.  Additional substitutions may be provided using the
0501         `vars' argument, which must be a dictionary whose contents overrides
0502         any pre-existing defaults.
0503 
0504         The section DEFAULT is special.
0505         """
0506         d = self._defaults.copy()
0507         try:
0508             d.update(self._sections[section])
0509         except KeyError:
0510             if section != DEFAULTSECT:
0511                 raise NoSectionError(section)
0512         # Update with the entry specific variables
0513         if vars:
0514             for key, value in vars.items():
0515                 d[self.optionxform(key)] = value
0516         option = self.optionxform(option)
0517         try:
0518             value = d[option]
0519         except KeyError:
0520             raise NoOptionError(option, section)
0521 
0522         if raw:
0523             return value
0524         else:
0525             return self._interpolate(section, option, value, d)
0526 
0527     def items(self, section, raw=False, vars=None):
0528         """Return a list of tuples with (name, value) for each option
0529         in the section.
0530 
0531         All % interpolations are expanded in the return values, based on the
0532         defaults passed into the constructor, unless the optional argument
0533         `raw' is true.  Additional substitutions may be provided using the
0534         `vars' argument, which must be a dictionary whose contents overrides
0535         any pre-existing defaults.
0536 
0537         The section DEFAULT is special.
0538         """
0539         d = self._defaults.copy()
0540         try:
0541             d.update(self._sections[section])
0542         except KeyError:
0543             if section != DEFAULTSECT:
0544                 raise NoSectionError(section)
0545         # Update with the entry specific variables
0546         if vars:
0547             for key, value in vars.items():
0548                 d[self.optionxform(key)] = value
0549         options = d.keys()
0550         if "__name__" in options:
0551             options.remove("__name__")
0552         if raw:
0553             return [(option, d[option])
0554                     for option in options]
0555         else:
0556             return [(option, self._interpolate(section, option, d[option], d))
0557                     for option in options]
0558 
0559     def _interpolate(self, section, option, rawval, vars):
0560         # do the string interpolation
0561         value = rawval
0562         depth = MAX_INTERPOLATION_DEPTH
0563         while depth:                    # Loop through this until it's done
0564             depth -= 1
0565             if "%(" in value:
0566                 value = self._KEYCRE.sub(self._interpolation_replace, value)
0567                 try:
0568                     value = value % vars
0569                 except KeyError, e:
0570                     raise InterpolationMissingOptionError(
0571                         option, section, rawval, e[0])
0572             else:
0573                 break
0574         if "%(" in value:
0575             raise InterpolationDepthError(option, section, rawval)
0576         return value
0577 
0578     _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
0579 
0580     def _interpolation_replace(self, match):
0581         s = match.group(1)
0582         if s is None:
0583             return match.group()
0584         else:
0585             return "%%(%s)s" % self.optionxform(s)
0586 
0587 
0588 class SafeConfigParser(ConfigParser):
0589 
0590     def _interpolate(self, section, option, rawval, vars):
0591         # do the string interpolation
0592         L = []
0593         self._interpolate_some(option, L, rawval, section, vars, 1)
0594         return ''.join(L)
0595 
0596     _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
0597 
0598     def _interpolate_some(self, option, accum, rest, section, map, depth):
0599         if depth > MAX_INTERPOLATION_DEPTH:
0600             raise InterpolationDepthError(option, section, rest)
0601         while rest:
0602             p = rest.find("%")
0603             if p < 0:
0604                 accum.append(rest)
0605                 return
0606             if p > 0:
0607                 accum.append(rest[:p])
0608                 rest = rest[p:]
0609             # p is no longer used
0610             c = rest[1:2]
0611             if c == "%":
0612                 accum.append("%")
0613                 rest = rest[2:]
0614             elif c == "(":
0615                 m = self._interpvar_match(rest)
0616                 if m is None:
0617                     raise InterpolationSyntaxError(option, section,
0618                         "bad interpolation variable reference %r" % rest)
0619                 var = self.optionxform(m.group(1))
0620                 rest = rest[m.end():]
0621                 try:
0622                     v = map[var]
0623                 except KeyError:
0624                     raise InterpolationMissingOptionError(
0625                         option, section, rest, var)
0626                 if "%" in v:
0627                     self._interpolate_some(option, accum, v,
0628                                            section, map, depth + 1)
0629                 else:
0630                     accum.append(v)
0631             else:
0632                 raise InterpolationSyntaxError(
0633                     option, section,
0634                     "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
0635 
0636     def set(self, section, option, value):
0637         """Set an option.  Extend ConfigParser.set: check for string values."""
0638         if not isinstance(value, basestring):
0639             raise TypeError("option values must be strings")
0640         ConfigParser.set(self, section, option, value)
0641 

Generated by PyXR 0.9.4
SourceForge.net Logo