[Python-checkins] python/dist/src/Lib ConfigParser.py,1.56,1.57

esr@users.sourceforge.net esr@users.sourceforge.net
Tue, 31 Dec 2002 07:26:23 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv9903/Lib

Modified Files:
	ConfigParser.py 
Log Message:
Fixed a bug in writing of continuations that broke the reversibilty of
the write() operation by readfp().  Sections and options are now
guaranteed to be written out in the order they were read in.  The
write method is now factored so that a _str_ method is supported.
Added optional capability to handle array values and multiline string
literals.  Updated unit test and documentation appropriately.


Index: ConfigParser.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v
retrieving revision 1.56
retrieving revision 1.57
diff -C2 -d -r1.56 -r1.57
*** ConfigParser.py	31 Dec 2002 06:55:41 -0000	1.56
--- ConfigParser.py	31 Dec 2002 15:26:19 -0000	1.57
***************
*** 203,206 ****
--- 203,210 ----
          else:
              self._defaults = defaults
+         self._sectkeys = []
+         self._optkeys = {}
+         self.listbrackets = None
+         self.stringquotes = None
  
      def defaults(self):
***************
*** 317,320 ****
--- 321,332 ----
                         '0': False, 'no': False, 'false': False, 'off': False}
  
+     def getstring(self, section, option):
+         v = self.get(section, option)
+         for c in self.stringquotes:
+             if v[0] == c and v[-1] == c:
+                 return v[1:-1]
+         else:
+             return v
+ 
      def getboolean(self, section, option):
          v = self.get(section, option)
***************
*** 349,366 ****
          sectdict[self.optionxform(option)] = value
  
!     def write(self, fp):
!         """Write an .ini-format representation of the configuration state."""
          if self._defaults:
!             fp.write("[%s]\n" % DEFAULTSECT)
!             for (key, value) in self._defaults.items():
!                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
!             fp.write("\n")
!         for section in self._sections:
!             fp.write("[%s]\n" % section)
!             for (key, value) in self._sections[section].items():
                  if key != "__name__":
!                     fp.write("%s = %s\n" %
!                              (key, str(value).replace('\n', '\n\t')))
!             fp.write("\n")
  
      def remove_option(self, section, option):
--- 361,396 ----
          sectdict[self.optionxform(option)] = value
  
!     def dump_value(self, section, key, value):
!         """Dump a value in a canonical form.
!         Section and key arguments are in case a subclass needs to do
!         special handling.
!         """
!         if self.listbrackets and type(value) == type([]):
!             return self.listbrackets[0] + ", ".join(map(lambda x: self.dump_value(section, key, x), value)) + self.listbrackets[1]
!         elif self.stringquotes and value[0] in self.stringquotes:
!             return str(value)
!         else:
!             return str(value).replace('\n', '\n\t')
! 
!     def __str__(self):
!         rep = ""
          if self._defaults:
!             rep += "[%s]\n" % DEFAULTSECT
!             for key in self._optkeys[DEFAULTSECT]:
!                 value = self._defaults[key]
!                 rep += "%s = %s\n" % (key, self.dump_value(DEFAULTSECT, key, value))
!             rep += "\n"
!         for section in self._sectkeys:
!             rep += "[%s]\n" % section
!             for key in self._optkeys[section]:
!                 value = self.get(section, key)
                  if key != "__name__":
!                     rep += "%s = %s\n" % (key, self.dump_value(section, key, value))
!             rep += "\n"
!         return rep
! 
!     def write(self, fp):
!         """Write an .ini-format representation of the configuration state."""
!         fp.write(str(self))
  
      def remove_option(self, section, option):
***************
*** 443,449 ****
--- 473,482 ----
                      elif sectname == DEFAULTSECT:
                          cursect = self._defaults
+                         self._optkeys[DEFAULTSECT] = []
                      else:
                          cursect = {'__name__': sectname}
                          self._sections[sectname] = cursect
+                         self._sectkeys.append(sectname)
+                         self._optkeys[sectname] = []
                      # So sections can't start with a continuation line
                      optname = None
***************
*** 467,471 ****
                              optval = ''
                          optname = self.optionxform(optname.rstrip())
!                         cursect[optname] = optval
                      else:
                          # a non-fatal parsing error occurred.  set up the
--- 500,545 ----
                              optval = ''
                          optname = self.optionxform(optname.rstrip())
!                         self._optkeys[sectname].append(optname)
!                         if self.listbrackets and optval[0] == self.listbrackets[0]:
!                             # we see a list delimiter
!                             import cStringIO, shlex
!                             valuelist = []
!                             restofline = cStringIO.StringIO(optval)
!                             tokenizer = shlex.shlex(restofline)
!                             tokenizer.whitespace += ","
!                             tokenizer.commenters += "#;"
!                             tokenizer.get_token()
!                             while 1:
!                                 tok = tokenizer.get_token()
!                                 if tok == '':
!                                     break
!                                 else:
!                                     valuelist.append(tok)
!                             if valuelist[-1] == self.listbrackets[1]:
!                                 valuelist.pop()
!                             else:
!                                 tokenizer = shlex.shlex(fp)
!                                 tokenizer.whitespace += ","
!                                 tokenizer.commenters += "#;"
!                                 while 1:
!                                     tok = tokenizer.get_token()
!                                     if tok=='' or tok == self.listbrackets[1]:
!                                         break
!                                     else:
!                                         valuelist.append(tok)
!                             cursect[optname] = valuelist
!                         elif self.stringquotes and optval[0] in self.stringquotes:
!                             # string-quoted literal
!                             if len(optval) == 1 or optval[-1] != optval[0]:
!                                 optval += '\n'
!                                 while 1:
!                                     line = fp.readline()
!                                     optval += line
!                                     if line == '' or line.rstrip()[-1] == optval[0]:
!                                         break;
!                             cursect[optname] = optval.rstrip()
!                         else:
!                             # normal case -- single value
!                             cursect[optname] = optval
                      else:
                          # a non-fatal parsing error occurred.  set up the
***************
*** 548,551 ****
--- 622,627 ----
      def _interpolate(self, section, option, rawval, vars):
          # do the string interpolation
+         if type(rawval) == type([]):
+             return map(lambda v:self._interpolate(section, option, v, vars), rawval)
          value = rawval
          depth = MAX_INTERPOLATION_DEPTH
***************
*** 568,571 ****
--- 644,649 ----
      def _interpolate(self, section, option, rawval, vars):
          # do the string interpolation
+         if type(rawval) == type([]):
+             return map(lambda v:self._interpolate(section, option, v, vars), rawval)
          L = []
          self._interpolate_some(option, L, rawval, section, vars, 1)
***************
*** 609,610 ****
--- 687,689 ----
                  raise InterpolationSyntaxError(
                      "'%' must be followed by '%' or '('")
+