symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/ConfigParser.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 import re
       
    91 
       
    92 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
       
    93            "InterpolationError", "InterpolationDepthError",
       
    94            "InterpolationSyntaxError", "ParsingError",
       
    95            "MissingSectionHeaderError",
       
    96            "ConfigParser", "SafeConfigParser", "RawConfigParser",
       
    97            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
       
    98 
       
    99 DEFAULTSECT = "DEFAULT"
       
   100 
       
   101 MAX_INTERPOLATION_DEPTH = 10
       
   102 
       
   103 
       
   104 
       
   105 # exception classes
       
   106 class Error(Exception):
       
   107     """Base class for ConfigParser exceptions."""
       
   108 
       
   109     def _get_message(self):
       
   110         """Getter for 'message'; needed only to override deprecation in
       
   111         BaseException."""
       
   112         return self.__message
       
   113 
       
   114     def _set_message(self, value):
       
   115         """Setter for 'message'; needed only to override deprecation in
       
   116         BaseException."""
       
   117         self.__message = value
       
   118 
       
   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)
       
   123 
       
   124     def __init__(self, msg=''):
       
   125         self.message = msg
       
   126         Exception.__init__(self, msg)
       
   127 
       
   128     def __repr__(self):
       
   129         return self.message
       
   130 
       
   131     __str__ = __repr__
       
   132 
       
   133 class NoSectionError(Error):
       
   134     """Raised when no section matches a requested option."""
       
   135 
       
   136     def __init__(self, section):
       
   137         Error.__init__(self, 'No section: %r' % (section,))
       
   138         self.section = section
       
   139 
       
   140 class DuplicateSectionError(Error):
       
   141     """Raised when a section is multiply-created."""
       
   142 
       
   143     def __init__(self, section):
       
   144         Error.__init__(self, "Section %r already exists" % section)
       
   145         self.section = section
       
   146 
       
   147 class NoOptionError(Error):
       
   148     """A requested option was not found."""
       
   149 
       
   150     def __init__(self, option, section):
       
   151         Error.__init__(self, "No option %r in section: %r" %
       
   152                        (option, section))
       
   153         self.option = option
       
   154         self.section = section
       
   155 
       
   156 class InterpolationError(Error):
       
   157     """Base class for interpolation-related exceptions."""
       
   158 
       
   159     def __init__(self, option, section, msg):
       
   160         Error.__init__(self, msg)
       
   161         self.option = option
       
   162         self.section = section
       
   163 
       
   164 class InterpolationMissingOptionError(InterpolationError):
       
   165     """A string substitution required a setting which was not available."""
       
   166 
       
   167     def __init__(self, option, section, rawval, reference):
       
   168         msg = ("Bad value substitution:\n"
       
   169                "\tsection: [%s]\n"
       
   170                "\toption : %s\n"
       
   171                "\tkey    : %s\n"
       
   172                "\trawval : %s\n"
       
   173                % (section, option, reference, rawval))
       
   174         InterpolationError.__init__(self, option, section, msg)
       
   175         self.reference = reference
       
   176 
       
   177 class InterpolationSyntaxError(InterpolationError):
       
   178     """Raised when the source text into which substitutions are made
       
   179     does not conform to the required syntax."""
       
   180 
       
   181 class InterpolationDepthError(InterpolationError):
       
   182     """Raised when substitutions are nested too deeply."""
       
   183 
       
   184     def __init__(self, option, section, rawval):
       
   185         msg = ("Value interpolation too deeply recursive:\n"
       
   186                "\tsection: [%s]\n"
       
   187                "\toption : %s\n"
       
   188                "\trawval : %s\n"
       
   189                % (section, option, rawval))
       
   190         InterpolationError.__init__(self, option, section, msg)
       
   191 
       
   192 class ParsingError(Error):
       
   193     """Raised when a configuration file does not follow legal syntax."""
       
   194 
       
   195     def __init__(self, filename):
       
   196         Error.__init__(self, 'File contains parsing errors: %s' % filename)
       
   197         self.filename = filename
       
   198         self.errors = []
       
   199 
       
   200     def append(self, lineno, line):
       
   201         self.errors.append((lineno, line))
       
   202         self.message += '\n\t[line %2d]: %s' % (lineno, line)
       
   203 
       
   204 class MissingSectionHeaderError(ParsingError):
       
   205     """Raised when a key-value pair is found before any section header."""
       
   206 
       
   207     def __init__(self, filename, lineno, line):
       
   208         Error.__init__(
       
   209             self,
       
   210             'File contains no section headers.\nfile: %s, line: %d\n%r' %
       
   211             (filename, lineno, line))
       
   212         self.filename = filename
       
   213         self.lineno = lineno
       
   214         self.line = line
       
   215 
       
   216 
       
   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()
       
   222         if defaults:
       
   223             for key, value in defaults.items():
       
   224                 self._defaults[self.optionxform(key)] = value
       
   225 
       
   226     def defaults(self):
       
   227         return self._defaults
       
   228 
       
   229     def sections(self):
       
   230         """Return a list of section names, excluding [DEFAULT]"""
       
   231         # self._sections will never have [DEFAULT] in it
       
   232         return self._sections.keys()
       
   233 
       
   234     def add_section(self, section):
       
   235         """Create a new section in the configuration.
       
   236 
       
   237         Raise DuplicateSectionError if a section by the specified name
       
   238         already exists. Raise ValueError if name is DEFAULT or any of it's
       
   239         case-insensitive variants.
       
   240         """
       
   241         if section.lower() == "default":
       
   242             raise ValueError, 'Invalid section name: %s' % section
       
   243 
       
   244         if section in self._sections:
       
   245             raise DuplicateSectionError(section)
       
   246         self._sections[section] = self._dict()
       
   247 
       
   248     def has_section(self, section):
       
   249         """Indicate whether the named section is present in the configuration.
       
   250 
       
   251         The DEFAULT section is not acknowledged.
       
   252         """
       
   253         return section in self._sections
       
   254 
       
   255     def options(self, section):
       
   256         """Return a list of option names for the given section name."""
       
   257         try:
       
   258             opts = self._sections[section].copy()
       
   259         except KeyError:
       
   260             raise NoSectionError(section)
       
   261         opts.update(self._defaults)
       
   262         if '__name__' in opts:
       
   263             del opts['__name__']
       
   264         return opts.keys()
       
   265 
       
   266     def read(self, filenames):
       
   267         """Read and parse a filename or a list of filenames.
       
   268 
       
   269         Files that cannot be opened are silently ignored; this is
       
   270         designed so that you can specify a list of potential
       
   271         configuration file locations (e.g. current directory, user's
       
   272         home directory, systemwide directory), and all existing
       
   273         configuration files in the list will be read.  A single
       
   274         filename may also be given.
       
   275 
       
   276         Return list of successfully read files.
       
   277         """
       
   278         if isinstance(filenames, basestring):
       
   279             filenames = [filenames]
       
   280         read_ok = []
       
   281         for filename in filenames:
       
   282             try:
       
   283                 fp = open(filename)
       
   284             except IOError:
       
   285                 continue
       
   286             self._read(fp, filename)
       
   287             fp.close()
       
   288             read_ok.append(filename)
       
   289         return read_ok
       
   290 
       
   291     def readfp(self, fp, filename=None):
       
   292         """Like read() but the argument must be a file-like object.
       
   293 
       
   294         The `fp' argument must have a `readline' method.  Optional
       
   295         second argument is the `filename', which if not given, is
       
   296         taken from fp.name.  If fp has no `name' attribute, `<???>' is
       
   297         used.
       
   298 
       
   299         """
       
   300         if filename is None:
       
   301             try:
       
   302                 filename = fp.name
       
   303             except AttributeError:
       
   304                 filename = '<???>'
       
   305         self._read(fp, filename)
       
   306 
       
   307     def get(self, section, option):
       
   308         opt = self.optionxform(option)
       
   309         if section not in self._sections:
       
   310             if section != DEFAULTSECT:
       
   311                 raise NoSectionError(section)
       
   312             if opt in self._defaults:
       
   313                 return self._defaults[opt]
       
   314             else:
       
   315                 raise NoOptionError(option, section)
       
   316         elif opt in self._sections[section]:
       
   317             return self._sections[section][opt]
       
   318         elif opt in self._defaults:
       
   319             return self._defaults[opt]
       
   320         else:
       
   321             raise NoOptionError(option, section)
       
   322 
       
   323     def items(self, section):
       
   324         try:
       
   325             d2 = self._sections[section]
       
   326         except KeyError:
       
   327             if section != DEFAULTSECT:
       
   328                 raise NoSectionError(section)
       
   329             d2 = self._dict()
       
   330         d = self._defaults.copy()
       
   331         d.update(d2)
       
   332         if "__name__" in d:
       
   333             del d["__name__"]
       
   334         return d.items()
       
   335 
       
   336     def _get(self, section, conv, option):
       
   337         return conv(self.get(section, option))
       
   338 
       
   339     def getint(self, section, option):
       
   340         return self._get(section, int, option)
       
   341 
       
   342     def getfloat(self, section, option):
       
   343         return self._get(section, float, option)
       
   344 
       
   345     _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
       
   346                        '0': False, 'no': False, 'false': False, 'off': False}
       
   347 
       
   348     def getboolean(self, section, option):
       
   349         v = self.get(section, option)
       
   350         if v.lower() not in self._boolean_states:
       
   351             raise ValueError, 'Not a boolean: %s' % v
       
   352         return self._boolean_states[v.lower()]
       
   353 
       
   354     def optionxform(self, optionstr):
       
   355         return optionstr.lower()
       
   356 
       
   357     def has_option(self, section, option):
       
   358         """Check for the existence of a given option in a given section."""
       
   359         if not section or section == DEFAULTSECT:
       
   360             option = self.optionxform(option)
       
   361             return option in self._defaults
       
   362         elif section not in self._sections:
       
   363             return False
       
   364         else:
       
   365             option = self.optionxform(option)
       
   366             return (option in self._sections[section]
       
   367                     or option in self._defaults)
       
   368 
       
   369     def set(self, section, option, value):
       
   370         """Set an option."""
       
   371         if not section or section == DEFAULTSECT:
       
   372             sectdict = self._defaults
       
   373         else:
       
   374             try:
       
   375                 sectdict = self._sections[section]
       
   376             except KeyError:
       
   377                 raise NoSectionError(section)
       
   378         sectdict[self.optionxform(option)] = value
       
   379 
       
   380     def write(self, fp):
       
   381         """Write an .ini-format representation of the configuration state."""
       
   382         if self._defaults:
       
   383             fp.write("[%s]\n" % DEFAULTSECT)
       
   384             for (key, value) in self._defaults.items():
       
   385                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
       
   386             fp.write("\n")
       
   387         for section in self._sections:
       
   388             fp.write("[%s]\n" % section)
       
   389             for (key, value) in self._sections[section].items():
       
   390                 if key != "__name__":
       
   391                     fp.write("%s = %s\n" %
       
   392                              (key, str(value).replace('\n', '\n\t')))
       
   393             fp.write("\n")
       
   394 
       
   395     def remove_option(self, section, option):
       
   396         """Remove an option."""
       
   397         if not section or section == DEFAULTSECT:
       
   398             sectdict = self._defaults
       
   399         else:
       
   400             try:
       
   401                 sectdict = self._sections[section]
       
   402             except KeyError:
       
   403                 raise NoSectionError(section)
       
   404         option = self.optionxform(option)
       
   405         existed = option in sectdict
       
   406         if existed:
       
   407             del sectdict[option]
       
   408         return existed
       
   409 
       
   410     def remove_section(self, section):
       
   411         """Remove a file section."""
       
   412         existed = section in self._sections
       
   413         if existed:
       
   414             del self._sections[section]
       
   415         return existed
       
   416 
       
   417     #
       
   418     # Regular expressions for parsing section headers and options.
       
   419     #
       
   420     SECTCRE = re.compile(
       
   421         r'\['                                 # [
       
   422         r'(?P<header>[^]]+)'                  # very permissive!
       
   423         r'\]'                                 # ]
       
   424         )
       
   425     OPTCRE = re.compile(
       
   426         r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
       
   427         r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
       
   428                                               # followed by separator
       
   429                                               # (either : or =), followed
       
   430                                               # by any # space/tab
       
   431         r'(?P<value>.*)$'                     # everything up to eol
       
   432         )
       
   433 
       
   434     def _read(self, fp, fpname):
       
   435         """Parse a sectioned setup file.
       
   436 
       
   437         The sections in setup file contains a title line at the top,
       
   438         indicated by a name in square brackets (`[]'), plus key/value
       
   439         options lines, indicated by `name: value' format lines.
       
   440         Continuations are represented by an embedded newline then
       
   441         leading whitespace.  Blank lines, lines beginning with a '#',
       
   442         and just about everything else are ignored.
       
   443         """
       
   444         cursect = None                            # None, or a dictionary
       
   445         optname = None
       
   446         lineno = 0
       
   447         e = None                                  # None, or an exception
       
   448         while True:
       
   449             line = fp.readline()
       
   450             if not line:
       
   451                 break
       
   452             lineno = lineno + 1
       
   453             # comment or blank line?
       
   454             if line.strip() == '' or line[0] in '#;':
       
   455                 continue
       
   456             if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
       
   457                 # no leading whitespace
       
   458                 continue
       
   459             # continuation line?
       
   460             if line[0].isspace() and cursect is not None and optname:
       
   461                 value = line.strip()
       
   462                 if value:
       
   463                     cursect[optname] = "%s\n%s" % (cursect[optname], value)
       
   464             # a section header or option header?
       
   465             else:
       
   466                 # is it a section header?
       
   467                 mo = self.SECTCRE.match(line)
       
   468                 if mo:
       
   469                     sectname = mo.group('header')
       
   470                     if sectname in self._sections:
       
   471                         cursect = self._sections[sectname]
       
   472                     elif sectname == DEFAULTSECT:
       
   473                         cursect = self._defaults
       
   474                     else:
       
   475                         cursect = self._dict()
       
   476                         cursect['__name__'] = sectname
       
   477                         self._sections[sectname] = cursect
       
   478                     # So sections can't start with a continuation line
       
   479                     optname = None
       
   480                 # no section header in the file?
       
   481                 elif cursect is None:
       
   482                     raise MissingSectionHeaderError(fpname, lineno, line)
       
   483                 # an option line?
       
   484                 else:
       
   485                     mo = self.OPTCRE.match(line)
       
   486                     if mo:
       
   487                         optname, vi, optval = mo.group('option', 'vi', 'value')
       
   488                         if vi in ('=', ':') and ';' in optval:
       
   489                             # ';' is a comment delimiter only if it follows
       
   490                             # a spacing character
       
   491                             pos = optval.find(';')
       
   492                             if pos != -1 and optval[pos-1].isspace():
       
   493                                 optval = optval[:pos]
       
   494                         optval = optval.strip()
       
   495                         # allow empty values
       
   496                         if optval == '""':
       
   497                             optval = ''
       
   498                         optname = self.optionxform(optname.rstrip())
       
   499                         cursect[optname] = optval
       
   500                     else:
       
   501                         # a non-fatal parsing error occurred.  set up the
       
   502                         # exception but keep going. the exception will be
       
   503                         # raised at the end of the file and will contain a
       
   504                         # list of all bogus lines
       
   505                         if not e:
       
   506                             e = ParsingError(fpname)
       
   507                         e.append(lineno, repr(line))
       
   508         # if any parsing errors occurred, raise an exception
       
   509         if e:
       
   510             raise e
       
   511 
       
   512 
       
   513 class ConfigParser(RawConfigParser):
       
   514 
       
   515     def get(self, section, option, raw=False, vars=None):
       
   516         """Get an option value for a given section.
       
   517 
       
   518         All % interpolations are expanded in the return values, based on the
       
   519         defaults passed into the constructor, unless the optional argument
       
   520         `raw' is true.  Additional substitutions may be provided using the
       
   521         `vars' argument, which must be a dictionary whose contents overrides
       
   522         any pre-existing defaults.
       
   523 
       
   524         The section DEFAULT is special.
       
   525         """
       
   526         d = self._defaults.copy()
       
   527         try:
       
   528             d.update(self._sections[section])
       
   529         except KeyError:
       
   530             if section != DEFAULTSECT:
       
   531                 raise NoSectionError(section)
       
   532         # Update with the entry specific variables
       
   533         if vars:
       
   534             for key, value in vars.items():
       
   535                 d[self.optionxform(key)] = value
       
   536         option = self.optionxform(option)
       
   537         try:
       
   538             value = d[option]
       
   539         except KeyError:
       
   540             raise NoOptionError(option, section)
       
   541 
       
   542         if raw:
       
   543             return value
       
   544         else:
       
   545             return self._interpolate(section, option, value, d)
       
   546 
       
   547     def items(self, section, raw=False, vars=None):
       
   548         """Return a list of tuples with (name, value) for each option
       
   549         in the section.
       
   550 
       
   551         All % interpolations are expanded in the return values, based on the
       
   552         defaults passed into the constructor, unless the optional argument
       
   553         `raw' is true.  Additional substitutions may be provided using the
       
   554         `vars' argument, which must be a dictionary whose contents overrides
       
   555         any pre-existing defaults.
       
   556 
       
   557         The section DEFAULT is special.
       
   558         """
       
   559         d = self._defaults.copy()
       
   560         try:
       
   561             d.update(self._sections[section])
       
   562         except KeyError:
       
   563             if section != DEFAULTSECT:
       
   564                 raise NoSectionError(section)
       
   565         # Update with the entry specific variables
       
   566         if vars:
       
   567             for key, value in vars.items():
       
   568                 d[self.optionxform(key)] = value
       
   569         options = d.keys()
       
   570         if "__name__" in options:
       
   571             options.remove("__name__")
       
   572         if raw:
       
   573             return [(option, d[option])
       
   574                     for option in options]
       
   575         else:
       
   576             return [(option, self._interpolate(section, option, d[option], d))
       
   577                     for option in options]
       
   578 
       
   579     def _interpolate(self, section, option, rawval, vars):
       
   580         # do the string interpolation
       
   581         value = rawval
       
   582         depth = MAX_INTERPOLATION_DEPTH
       
   583         while depth:                    # Loop through this until it's done
       
   584             depth -= 1
       
   585             if "%(" in value:
       
   586                 value = self._KEYCRE.sub(self._interpolation_replace, value)
       
   587                 try:
       
   588                     value = value % vars
       
   589                 except KeyError, e:
       
   590                     raise InterpolationMissingOptionError(
       
   591                         option, section, rawval, e.args[0])
       
   592             else:
       
   593                 break
       
   594         if "%(" in value:
       
   595             raise InterpolationDepthError(option, section, rawval)
       
   596         return value
       
   597 
       
   598     _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
       
   599 
       
   600     def _interpolation_replace(self, match):
       
   601         s = match.group(1)
       
   602         if s is None:
       
   603             return match.group()
       
   604         else:
       
   605             return "%%(%s)s" % self.optionxform(s)
       
   606 
       
   607 
       
   608 class SafeConfigParser(ConfigParser):
       
   609 
       
   610     def _interpolate(self, section, option, rawval, vars):
       
   611         # do the string interpolation
       
   612         L = []
       
   613         self._interpolate_some(option, L, rawval, section, vars, 1)
       
   614         return ''.join(L)
       
   615 
       
   616     _interpvar_re = re.compile(r"%\(([^)]+)\)s")
       
   617     _badpercent_re = re.compile(r"%[^%]|%$")
       
   618 
       
   619     def _interpolate_some(self, option, accum, rest, section, map, depth):
       
   620         if depth > MAX_INTERPOLATION_DEPTH:
       
   621             raise InterpolationDepthError(option, section, rest)
       
   622         while rest:
       
   623             p = rest.find("%")
       
   624             if p < 0:
       
   625                 accum.append(rest)
       
   626                 return
       
   627             if p > 0:
       
   628                 accum.append(rest[:p])
       
   629                 rest = rest[p:]
       
   630             # p is no longer used
       
   631             c = rest[1:2]
       
   632             if c == "%":
       
   633                 accum.append("%")
       
   634                 rest = rest[2:]
       
   635             elif c == "(":
       
   636                 m = self._interpvar_re.match(rest)
       
   637                 if m is None:
       
   638                     raise InterpolationSyntaxError(option, section,
       
   639                         "bad interpolation variable reference %r" % rest)
       
   640                 var = self.optionxform(m.group(1))
       
   641                 rest = rest[m.end():]
       
   642                 try:
       
   643                     v = map[var]
       
   644                 except KeyError:
       
   645                     raise InterpolationMissingOptionError(
       
   646                         option, section, rest, var)
       
   647                 if "%" in v:
       
   648                     self._interpolate_some(option, accum, v,
       
   649                                            section, map, depth + 1)
       
   650                 else:
       
   651                     accum.append(v)
       
   652             else:
       
   653                 raise InterpolationSyntaxError(
       
   654                     option, section,
       
   655                     "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
       
   656 
       
   657     def set(self, section, option, value):
       
   658         """Set an option.  Extend ConfigParser.set: check for string values."""
       
   659         if not isinstance(value, basestring):
       
   660             raise TypeError("option values must be strings")
       
   661         # check for bad percent signs:
       
   662         # first, replace all "good" interpolations
       
   663         tmp_value = self._interpvar_re.sub('', value)
       
   664         # then, check if there's a lone percent sign left
       
   665         m = self._badpercent_re.search(tmp_value)
       
   666         if m:
       
   667             raise ValueError("invalid interpolation syntax in %r at "
       
   668                              "position %d" % (value, m.start()))
       
   669         ConfigParser.set(self, section, option, value)