Browse Source

HUE-7675 [core] Warn on startup for any invalid configurations in hue.ini (Step#1)

Roohi 8 years ago
parent
commit
c3dcfb518f
52 changed files with 9800 additions and 3790 deletions
  1. 191 178
      desktop/core/ext-py/configobj-4.7.2/configobj.py
  2. 2671 0
      desktop/core/ext-py/configobj-4.7.2/docs/configobj.html
  3. 2992 0
      desktop/core/ext-py/configobj-4.7.2/docs/configobj.txt
  4. 45 30
      desktop/core/ext-py/configobj-4.7.2/docs/default.css
  5. 5 0
      desktop/core/ext-py/configobj-4.7.2/docs/docutils.conf
  6. 1 1
      desktop/core/ext-py/configobj-4.7.2/docs/docutils.css
  7. 61 0
      desktop/core/ext-py/configobj-4.7.2/docs/pygments.css
  8. 8 0
      desktop/core/ext-py/configobj-4.7.2/docs/template.tmp
  9. 639 0
      desktop/core/ext-py/configobj-4.7.2/docs/validate.html
  10. 686 0
      desktop/core/ext-py/configobj-4.7.2/docs/validate.txt
  11. 83 0
      desktop/core/ext-py/configobj-4.7.2/setup.py
  12. 0 0
      desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/__init__.py
  13. 10 0
      desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/conf.ini
  14. 13 0
      desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/conf.spec
  15. 101 0
      desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/test_configobj.py
  16. 66 0
      desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/test_validate_errors.py
  17. 2221 0
      desktop/core/ext-py/configobj-4.7.2/tests/test_configobj.py
  18. 7 22
      desktop/core/ext-py/configobj-4.7.2/validate.py
  19. 0 10
      desktop/core/ext-py/configobj/PKG-INFO
  20. 0 2473
      desktop/core/ext-py/configobj/docs/configobj.html
  21. BIN
      desktop/core/ext-py/configobj/docs/images/PythonPowered.png
  22. BIN
      desktop/core/ext-py/configobj/docs/images/new_python.gif
  23. BIN
      desktop/core/ext-py/configobj/docs/images/osi-certified-120x100.gif
  24. BIN
      desktop/core/ext-py/configobj/docs/images/powered_by_python.jpg
  25. BIN
      desktop/core/ext-py/configobj/docs/images/pythonbanner.gif
  26. BIN
      desktop/core/ext-py/configobj/docs/smilies/arrow.gif
  27. BIN
      desktop/core/ext-py/configobj/docs/smilies/badgrin.gif
  28. BIN
      desktop/core/ext-py/configobj/docs/smilies/biggrin.gif
  29. BIN
      desktop/core/ext-py/configobj/docs/smilies/confused.gif
  30. BIN
      desktop/core/ext-py/configobj/docs/smilies/cool.gif
  31. BIN
      desktop/core/ext-py/configobj/docs/smilies/cry.gif
  32. BIN
      desktop/core/ext-py/configobj/docs/smilies/doubt.gif
  33. BIN
      desktop/core/ext-py/configobj/docs/smilies/evil.gif
  34. BIN
      desktop/core/ext-py/configobj/docs/smilies/exclaim.gif
  35. BIN
      desktop/core/ext-py/configobj/docs/smilies/idea.gif
  36. BIN
      desktop/core/ext-py/configobj/docs/smilies/lol.gif
  37. BIN
      desktop/core/ext-py/configobj/docs/smilies/mad.gif
  38. BIN
      desktop/core/ext-py/configobj/docs/smilies/neutral.gif
  39. BIN
      desktop/core/ext-py/configobj/docs/smilies/question.gif
  40. BIN
      desktop/core/ext-py/configobj/docs/smilies/razz.gif
  41. BIN
      desktop/core/ext-py/configobj/docs/smilies/redface.gif
  42. BIN
      desktop/core/ext-py/configobj/docs/smilies/rolleyes.gif
  43. BIN
      desktop/core/ext-py/configobj/docs/smilies/sad.gif
  44. 0 43
      desktop/core/ext-py/configobj/docs/smilies/sc_smilies.pak
  45. BIN
      desktop/core/ext-py/configobj/docs/smilies/shock.gif
  46. BIN
      desktop/core/ext-py/configobj/docs/smilies/smile.gif
  47. BIN
      desktop/core/ext-py/configobj/docs/smilies/surprised.gif
  48. BIN
      desktop/core/ext-py/configobj/docs/smilies/wink.gif
  49. 0 349
      desktop/core/ext-py/configobj/docs/stylesheets/pep.css
  50. 0 29
      desktop/core/ext-py/configobj/docs/stylesheets/pysrc.css
  51. 0 624
      desktop/core/ext-py/configobj/docs/validate.html
  52. 0 31
      desktop/core/ext-py/configobj/setup.py

+ 191 - 178
desktop/core/ext-py/configobj/configobj.py → desktop/core/ext-py/configobj-4.7.2/configobj.py

@@ -1,6 +1,6 @@
 # configobj.py
 # A config file reader/writer that supports nested sections in config files.
-# Copyright (C) 2005-2009 Michael Foord, Nicola Larosa
+# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa
 # E-mail: fuzzyman AT voidspace DOT org DOT uk
 #         nico AT tekNico DOT net
 
@@ -16,37 +16,17 @@
 # http://lists.sourceforge.net/lists/listinfo/configobj-develop
 # Comments, suggestions and bug reports welcome.
 
-
 from __future__ import generators
 
-import sys
 import os
 import re
+import sys
 
-compiler = None
-try:
-    import compiler
-except ImportError:
-    # for IronPython
-    pass
+from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
 
 
-try:
-    from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
-except ImportError:
-    # Python 2.2 does not have these
-    # UTF-8
-    BOM_UTF8 = '\xef\xbb\xbf'
-    # UTF-16, little endian
-    BOM_UTF16_LE = '\xff\xfe'
-    # UTF-16, big endian
-    BOM_UTF16_BE = '\xfe\xff'
-    if sys.byteorder == 'little':
-        # UTF-16, native endianness
-        BOM_UTF16 = BOM_UTF16_LE
-    else:
-        # UTF-16, native endianness
-        BOM_UTF16 = BOM_UTF16_BE
+# imported lazily to avoid startup performance hit if it isn't used
+compiler = None
 
 # A dictionary mapping BOM to
 # the encoding to decode with, and what to set the
@@ -100,24 +80,20 @@ wspace_plus = ' \r\n\v\t\'"'
 tsquot = '"""%s"""'
 tdquot = "'''%s'''"
 
-try:
-    enumerate
-except NameError:
-    def enumerate(obj):
-        """enumerate for Python 2.2."""
-        i = -1
-        for item in obj:
-            i += 1
-            yield i, item
-
 # Sentinel for use in getattr calls to replace hasattr
 MISSING = object()
 
-__version__ = '4.6.0'
+__version__ = '4.7.2'
 
-__revision__ = '$Id: configobj.py 156 2006-01-31 14:57:08Z fuzzyman $'
+try:
+    any
+except NameError:
+    def any(iterable):
+        for entry in iterable:
+            if entry:
+                return True
+        return False
 
-__docformat__ = "restructuredtext en" 
 
 __all__ = (
     '__version__',
@@ -137,8 +113,8 @@ __all__ = (
     'ReloadError',
     'UnreprError',
     'UnknownType',
-    '__docformat__',
     'flatten_errors',
+    'get_extra_values'
 )
 
 DEFAULT_INTERPOLATION = 'configparser'
@@ -164,9 +140,10 @@ OPTION_DEFAULTS = {
 
 
 def getObj(s):
-    s = "a=" + s
+    global compiler
     if compiler is None:
-        raise ImportError('compiler module not available')
+        import compiler
+    s = "a=" + s
     p = compiler.parse(s)
     return p.getChildren()[1].getChildren()[0].getChildren()[1]
 
@@ -309,11 +286,9 @@ class RepeatSectionError(ConfigObjError):
 
 class MissingInterpolationOption(InterpolationError):
     """A value specified for interpolation was missing."""
-
     def __init__(self, option):
-        InterpolationError.__init__(
-            self,
-            'missing option "%s" in interpolation.' % option)
+        msg = 'missing option "%s" in interpolation.' % option
+        InterpolationError.__init__(self, msg)
 
 
 class UnreprError(ConfigObjError):
@@ -331,6 +306,7 @@ class InterpolationEngine(object):
 
     # compiled regexp to use in self.interpolate()
     _KEYCRE = re.compile(r"%\(([^)]*)\)s")
+    _cookie = '%'
 
     def __init__(self, section):
         # the Section instance that "owns" this engine
@@ -338,6 +314,10 @@ class InterpolationEngine(object):
 
 
     def interpolate(self, key, value):
+        # short-cut
+        if not self._cookie in value:
+            return value
+        
         def recursive_interpolate(key, value, section, backtrail):
             """The function that does the actual work.
 
@@ -349,7 +329,7 @@ class InterpolationEngine(object):
             This is similar to a depth-first-search algorithm.
             """
             # Have we been here already?
-            if backtrail.has_key((key, section.name)):
+            if (key, section.name) in backtrail:
                 # Yes - infinite loop detected
                 raise InterpolationLoopError(key)
             # Place a marker on our backtrail so we won't come back here again
@@ -400,11 +380,11 @@ class InterpolationEngine(object):
         while True:
             # try the current section first
             val = current_section.get(key)
-            if val is not None:
+            if val is not None and not isinstance(val, Section):
                 break
             # try "DEFAULT" next
             val = current_section.get('DEFAULT', {}).get(key)
-            if val is not None:
+            if val is not None and not isinstance(val, Section):
                 break
             # move up to parent and try again
             # top-level's parent is itself
@@ -442,6 +422,7 @@ class InterpolationEngine(object):
 
 class ConfigParserInterpolation(InterpolationEngine):
     """Behaves like ConfigParser."""
+    _cookie = '%'
     _KEYCRE = re.compile(r"%\(([^)]*)\)s")
 
     def _parse_match(self, match):
@@ -453,6 +434,7 @@ class ConfigParserInterpolation(InterpolationEngine):
 
 class TemplateInterpolation(InterpolationEngine):
     """Behaves like string.Template."""
+    _cookie = '$'
     _delimiter = '$'
     _KEYCRE = re.compile(r"""
         \$(?:
@@ -553,6 +535,8 @@ class Section(dict):
         # for defaults
         self.defaults = []
         self.default_values = {}
+        self.extra_values = []
+        self._created = False
 
 
     def _interpolate(self, key, value):
@@ -581,8 +565,17 @@ class Section(dict):
     def __getitem__(self, key):
         """Fetch the item and do string interpolation."""
         val = dict.__getitem__(self, key)
-        if self.main.interpolation and isinstance(val, basestring):
-            return self._interpolate(key, val)
+        if self.main.interpolation: 
+            if isinstance(val, basestring):
+                return self._interpolate(key, val)
+            if isinstance(val, list):
+                def _check(entry):
+                    if isinstance(entry, basestring):
+                        return self._interpolate(key, entry)
+                    return entry
+                new = [_check(entry) for entry in val]
+                if new != val:
+                    return new
         return val
 
 
@@ -604,7 +597,7 @@ class Section(dict):
             raise ValueError('The key "%s" is not a string.' % key)
         
         # add the comment
-        if not self.comments.has_key(key):
+        if key not in self.comments:
             self.comments[key] = []
             self.inline_comments[key] = ''
         # remove the entry from defaults
@@ -612,13 +605,13 @@ class Section(dict):
             self.defaults.remove(key)
         #
         if isinstance(value, Section):
-            if not self.has_key(key):
+            if key not in self:
                 self.sections.append(key)
             dict.__setitem__(self, key, value)
         elif isinstance(value, dict) and not unrepr:
             # First create the new depth level,
             # then create the section
-            if not self.has_key(key):
+            if key not in self:
                 self.sections.append(key)
             new_depth = self.depth + 1
             dict.__setitem__(
@@ -631,7 +624,7 @@ class Section(dict):
                     indict=value,
                     name=key))
         else:
-            if not self.has_key(key):
+            if key not in self:
                 self.scalars.append(key)
             if not self.main.stringify:
                 if isinstance(value, basestring):
@@ -672,22 +665,19 @@ class Section(dict):
             self[entry] = indict[entry]
 
 
-    def pop(self, key, *args):
+    def pop(self, key, default=MISSING):
         """
         'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
         If key is not found, d is returned if given, otherwise KeyError is raised'
         """
-        val = dict.pop(self, key, *args)
-        if key in self.scalars:
-            del self.comments[key]
-            del self.inline_comments[key]
-            self.scalars.remove(key)
-        elif key in self.sections:
-            del self.comments[key]
-            del self.inline_comments[key]
-            self.sections.remove(key)
-        if self.main.interpolation and isinstance(val, basestring):
-            return self._interpolate(key, val)
+        try:
+            val = self[key]
+        except KeyError:
+            if default is MISSING:
+                raise
+            val = default
+        else:
+            del self[key]
         return val
 
 
@@ -716,6 +706,8 @@ class Section(dict):
         self.comments = {}
         self.inline_comments = {}
         self.configspec = None
+        self.defaults = []
+        self.extra_values = []
 
 
     def setdefault(self, key, default=None):
@@ -761,7 +753,12 @@ class Section(dict):
 
     def __repr__(self):
         """x.__repr__() <==> repr(x)"""
-        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(self[key])))
+        def _getval(key):
+            try:
+                return self[key]
+            except MissingInterpolationOption:
+                return dict.__getitem__(self, key)
+        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key))))
             for key in (self.scalars + self.sections)])
 
     __str__ = __repr__
@@ -1148,7 +1145,7 @@ class ConfigObj(Section):
         (
             (?:".*?")|          # double quotes
             (?:'.*?')|          # single quotes
-            (?:[^'",\#].*?)       # unquoted
+            (?:[^'",\#]?.*?)       # unquoted
         )
         \s*,\s*                 # comma
         ''',
@@ -1187,34 +1184,60 @@ class ConfigObj(Section):
         }
 
 
-    def __init__(self, infile=None, options=None, _inspec=False, **kwargs):
+    def __init__(self, infile=None, options=None, configspec=None, encoding=None,
+                 interpolation=True, raise_errors=False, list_values=True,
+                 create_empty=False, file_error=False, stringify=True,
+                 indent_type=None, default_encoding=None, unrepr=False,
+                 write_empty_values=False, _inspec=False):
         """
         Parse a config file or create a config file object.
         
-        ``ConfigObj(infile=None, options=None, **kwargs)``
+        ``ConfigObj(infile=None, configspec=None, encoding=None,
+                    interpolation=True, raise_errors=False, list_values=True,
+                    create_empty=False, file_error=False, stringify=True,
+                    indent_type=None, default_encoding=None, unrepr=False,
+                    write_empty_values=False, _inspec=False)``
         """
         self._inspec = _inspec
         # init the superclass
         Section.__init__(self, self, 0, self)
         
         infile = infile or []
-        options = dict(options or {})
+        
+        _options = {'configspec': configspec,
+                    'encoding': encoding, 'interpolation': interpolation,
+                    'raise_errors': raise_errors, 'list_values': list_values,
+                    'create_empty': create_empty, 'file_error': file_error,
+                    'stringify': stringify, 'indent_type': indent_type,
+                    'default_encoding': default_encoding, 'unrepr': unrepr,
+                    'write_empty_values': write_empty_values}
+
+        if options is None:
+            options = _options
+        else:
+            import warnings
+            warnings.warn('Passing in an options dictionary to ConfigObj() is '
+                          'deprecated. Use **options instead.',
+                          DeprecationWarning, stacklevel=2)
             
-        # keyword arguments take precedence over an options dictionary
-        options.update(kwargs)
+            # TODO: check the values too.
+            for entry in options:
+                if entry not in OPTION_DEFAULTS:
+                    raise TypeError('Unrecognised option "%s".' % entry)
+            for entry, value in OPTION_DEFAULTS.items():
+                if entry not in options:
+                    options[entry] = value
+                keyword_value = _options[entry]
+                if value != keyword_value:
+                    options[entry] = keyword_value
+        
+        # XXXX this ignores an explicit list_values = True in combination
+        # with _inspec. The user should *never* do that anyway, but still...
         if _inspec:
             options['list_values'] = False
         
-        defaults = OPTION_DEFAULTS.copy()
-        # TODO: check the values too.
-        for entry in options:
-            if entry not in defaults:
-                raise TypeError('Unrecognised option "%s".' % entry)
-        
-        # Add any explicit options to the defaults
-        defaults.update(options)
-        self._initialise(defaults)
-        configspec = defaults['configspec']
+        self._initialise(options)
+        configspec = options['configspec']
         self._original_configspec = configspec
         self._load(infile, configspec)
         
@@ -1247,10 +1270,17 @@ class ConfigObj(Section):
             # the Section class handles creating subsections
             if isinstance(infile, ConfigObj):
                 # get a copy of our ConfigObj
-                infile = infile.dict()
+                def set_section(in_section, this_section):
+                    for entry in in_section.scalars:
+                        this_section[entry] = in_section[entry]
+                    for section in in_section.sections:
+                        this_section[section] = {}
+                        set_section(in_section[section], this_section[section])
+                set_section(infile, self)
                 
-            for entry in infile:
-                self[entry] = infile[entry]
+            else:
+                for entry in infile:
+                    self[entry] = infile[entry]
             del self._errors
             
             if configspec is not None:
@@ -1342,8 +1372,13 @@ class ConfigObj(Section):
         
         
     def __repr__(self):
+        def _getval(key):
+            try:
+                return self[key]
+            except MissingInterpolationOption:
+                return dict.__getitem__(self, key)
         return ('ConfigObj({%s})' % 
-                ', '.join([('%s: %s' % (repr(key), repr(self[key]))) 
+                ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) 
                 for key in (self.scalars + self.sections)]))
     
     
@@ -1560,7 +1595,7 @@ class ConfigObj(Section):
                                        NestingError, infile, cur_index)
                     
                 sect_name = self._unquote(sect_name)
-                if parent.has_key(sect_name):
+                if sect_name in parent:
                     self._handle_error('Duplicate section name at line %s.',
                                        DuplicateError, infile, cur_index)
                     continue
@@ -1594,7 +1629,7 @@ class ConfigObj(Section):
                 # check for a multiline value
                 if value[:3] in ['"""', "'''"]:
                     try:
-                        (value, comment, cur_index) = self._multiline(
+                        value, comment, cur_index = self._multiline(
                             value, infile, cur_index, maxline)
                     except SyntaxError:
                         self._handle_error(
@@ -1638,7 +1673,7 @@ class ConfigObj(Section):
                             continue
                 #
                 key = self._unquote(key)
-                if this_section.has_key(key):
+                if key in this_section:
                     self._handle_error(
                         'Duplicate keyword name at line %s.',
                         DuplicateError, infile, cur_index)
@@ -1703,6 +1738,9 @@ class ConfigObj(Section):
 
     def _unquote(self, value):
         """Return an unquoted version of a value"""
+        if not value:
+            # should only happen during parsing of lists
+            raise SyntaxError
         if (value[0] == value[-1]) and (value[0] in ('"', "'")):
             value = value[1:-1]
         return value
@@ -1919,6 +1957,7 @@ class ConfigObj(Section):
                 continue
             if entry not in section:
                 section[entry] = {}
+                section[entry]._created = True
                 if copy:
                     # copy comments
                     section.comments[entry] = configspec.comments.get(entry, [])
@@ -1976,6 +2015,8 @@ class ConfigObj(Section):
         >>> a.filename = filename
         >>> a == ConfigObj('test.ini', raise_errors=True)
         1
+        >>> import os
+        >>> os.remove('test.ini')
         """
         if self.indent_type is None:
             # this can be true if initialised from a dictionary
@@ -2051,6 +2092,10 @@ class ConfigObj(Section):
         
         # Turn the list to a string, joined with correct newlines
         newline = self.newlines or os.linesep
+        if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w'
+            and sys.platform == 'win32' and newline == '\r\n'):
+            # Windows specific hack to avoid writing '\r\r\n'
+            newline = '\n'
         output = self._a_to_u(newline).join(out)
         if self.encoding:
             output = output.encode(self.encoding)
@@ -2124,10 +2169,21 @@ class ConfigObj(Section):
                 section.indent_type = section.configspec.indent_type
             
         #
+        # section.default_values.clear() #??
         configspec = section.configspec
         self._set_configspec(section, copy)
+
         
         def validate_entry(entry, spec, val, missing, ret_true, ret_false):
+            section.default_values.pop(entry, None)
+                
+            try:
+                section.default_values[entry] = validator.get_default_value(configspec[entry])
+            except (KeyError, AttributeError, validator.baseErrorClass):
+                # No default, bad default or validator has no 'get_default_value'
+                # (e.g. SimpleVal)
+                pass
+            
             try:
                 check = validator.check(spec,
                                         val,
@@ -2142,21 +2198,6 @@ class ConfigObj(Section):
                     ret_false = False
                 ret_true = False
             else:
-                try: 
-                    section.default_values.pop(entry, None)
-                except AttributeError: 
-                    # For Python 2.2 compatibility
-                    try:
-                        del section.default_values[entry]
-                    except KeyError:
-                        pass
-                    
-                try: 
-                    section.default_values[entry] = validator.get_default_value(configspec[entry])
-                except (KeyError, AttributeError):
-                    # No default or validator has no 'get_default_value' (e.g. SimpleVal)
-                    pass
-                    
                 ret_false = False
                 out[entry] = True
                 if self.stringify or missing:
@@ -2190,13 +2231,12 @@ class ConfigObj(Section):
             if entry in ('__many__', '___many___'):
                 # reserved names
                 continue
-            
             if (not entry in section.scalars) or (entry in section.defaults):
                 # missing entries
                 # or entries from defaults
                 missing = True
                 val = None
-                if copy and not entry in section.scalars:
+                if copy and entry not in section.scalars:
                     # copy comments
                     section.comments[entry] = (
                         configspec.comments.get(entry, []))
@@ -2206,7 +2246,7 @@ class ConfigObj(Section):
             else:
                 missing = False
                 val = section[entry]
-                
+            
             ret_true, ret_false = validate_entry(entry, configspec[entry], val, 
                                                  missing, ret_true, ret_false)
         
@@ -2221,6 +2261,7 @@ class ConfigObj(Section):
                 val = section[entry]
                 ret_true, ret_false = validate_entry(entry, many, val, False,
                                                      ret_true, ret_false)
+            unvalidated = []
 
         for entry in incorrect_scalars:
             ret_true = False
@@ -2246,6 +2287,7 @@ class ConfigObj(Section):
             if section is self and entry == 'DEFAULT':
                 continue
             if section[entry].configspec is None:
+                unvalidated.append(entry)
                 continue
             if copy:
                 section.comments[entry] = configspec.comments.get(entry, [])
@@ -2258,8 +2300,19 @@ class ConfigObj(Section):
                 ret_false = False
             else:
                 ret_true = False
-                ret_false = False
+        
+        section.extra_values = unvalidated
+        if preserve_errors and not section._created:
+            # If the section wasn't created (i.e. it wasn't missing)
+            # then we can't return False, we need to preserve errors
+            ret_false = False
         #
+        if ret_false and preserve_errors and out:
+            # If we are preserving errors, but all
+            # the failures are from missing sections / values
+            # then we can return False. Otherwise there is a
+            # real failure that we need to preserve.
+            ret_false = not any(out.values())
         if ret_true:
             return True
         elif ret_false:
@@ -2326,7 +2379,6 @@ class SimpleVal(object):
         return member
 
 
-# Check / processing functions for options
 def flatten_errors(cfg, res, levels=None, results=None):
     """
     An example function that will turn a nested dictionary of results
@@ -2338,9 +2390,7 @@ def flatten_errors(cfg, res, levels=None, results=None):
     (This is a recursive function, so you shouldn't use the ``levels`` or
     ``results`` arguments - they are used by the function.)
     
-    Returns a list of keys that failed. Each member of the list is a tuple :
-    
-    ::
+    Returns a list of keys that failed. Each member of the list is a tuple::
     
         ([list of sections...], key, result)
     
@@ -2360,77 +2410,14 @@ def flatten_errors(cfg, res, levels=None, results=None):
     object returned. You can use this as a string that describes the failure.
     
     For example *The value "3" is of the wrong type*.
-    
-    >>> import validate
-    >>> vtor = validate.Validator()
-    >>> my_ini = '''
-    ...     option1 = True
-    ...     [section1]
-    ...     option1 = True
-    ...     [section2]
-    ...     another_option = Probably
-    ...     [section3]
-    ...     another_option = True
-    ...     [[section3b]]
-    ...     value = 3
-    ...     value2 = a
-    ...     value3 = 11
-    ...     '''
-    >>> my_cfg = '''
-    ...     option1 = boolean()
-    ...     option2 = boolean()
-    ...     option3 = boolean(default=Bad_value)
-    ...     [section1]
-    ...     option1 = boolean()
-    ...     option2 = boolean()
-    ...     option3 = boolean(default=Bad_value)
-    ...     [section2]
-    ...     another_option = boolean()
-    ...     [section3]
-    ...     another_option = boolean()
-    ...     [[section3b]]
-    ...     value = integer
-    ...     value2 = integer
-    ...     value3 = integer(0, 10)
-    ...         [[[section3b-sub]]]
-    ...         value = string
-    ...     [section4]
-    ...     another_option = boolean()
-    ...     '''
-    >>> cs = my_cfg.split('\\n')
-    >>> ini = my_ini.split('\\n')
-    >>> cfg = ConfigObj(ini, configspec=cs)
-    >>> res = cfg.validate(vtor, preserve_errors=True)
-    >>> errors = []
-    >>> for entry in flatten_errors(cfg, res):
-    ...     section_list, key, error = entry
-    ...     section_list.insert(0, '[root]')
-    ...     if key is not None:
-    ...        section_list.append(key)
-    ...     else:
-    ...         section_list.append('[missing]')
-    ...     section_string = ', '.join(section_list)
-    ...     errors.append((section_string, ' = ', error))
-    >>> errors.sort()
-    >>> for entry in errors:
-    ...     print entry[0], entry[1], (entry[2] or 0)
-    [root], option2  =  0
-    [root], option3  =  the value "Bad_value" is of the wrong type.
-    [root], section1, option2  =  0
-    [root], section1, option3  =  the value "Bad_value" is of the wrong type.
-    [root], section2, another_option  =  the value "Probably" is of the wrong type.
-    [root], section3, section3b, section3b-sub, [missing]  =  0
-    [root], section3, section3b, value2  =  the value "a" is of the wrong type.
-    [root], section3, section3b, value3  =  the value "11" is too big.
-    [root], section4, [missing]  =  0
     """
     if levels is None:
         # first time called
         levels = []
         results = []
-    if res is True:
+    if res == True:
         return results
-    if res is False or isinstance(res, Exception):
+    if res == False or isinstance(res, Exception):
         results.append((levels[:], None, res))
         if levels:
             levels.pop()
@@ -2452,4 +2439,30 @@ def flatten_errors(cfg, res, levels=None, results=None):
     return results
 
 
+def get_extra_values(conf, _prepend=()):
+    """
+    Find all the values and sections not in the configspec from a validated
+    ConfigObj.
+    
+    ``get_extra_values`` returns a list of tuples where each tuple represents
+    either an extra section, or an extra value.
+    
+    The tuples contain two values, a tuple representing the section the value 
+    is in and the name of the extra values. For extra values in the top level
+    section the first member will be an empty tuple. For values in the 'foo'
+    section the first member will be ``('foo',)``. For members in the 'bar'
+    subsection of the 'foo' section the first member will be ``('foo', 'bar')``.
+    
+    NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't
+    been validated it will return an empty list.
+    """
+    out = []
+    
+    out.extend([(_prepend, name) for name in conf.extra_values])
+    for name in conf.sections:
+        if name not in conf.extra_values:
+            out.extend(get_extra_values(conf[name], _prepend + (name,)))
+    return out
+
+
 """*A programming language is a medium of expression.* - Paul Graham"""

+ 2671 - 0
desktop/core/ext-py/configobj-4.7.2/docs/configobj.html

@@ -0,0 +1,2671 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
+<title>Reading and Writing Config Files</title>
+<meta name="authors" content="Michael Foord  Nicola Larosa" />
+<meta name="date" content="2010/02/27" />
+<meta content="ConfigObj - a Python module for easy reading and writing of config files." name="description" />
+<meta content="python, script, module, config, configuration, data, persistence, developer, configparser" name="keywords" />
+<link rel="stylesheet" href="docutils.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="reading-and-writing-config-files">
+<h1 class="title">Reading and Writing Config Files</h1>
+<h2 class="subtitle" id="configobj-4-introduction-and-reference">ConfigObj 4 Introduction and Reference</h2>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr><th class="docinfo-name">Authors:</th>
+<td>Michael Foord
+<br />Nicola Larosa</td></tr>
+<tr><th class="docinfo-name">Version:</th>
+<td>ConfigObj 4.7.2</td></tr>
+<tr><th class="docinfo-name">Date:</th>
+<td>2010/02/27</td></tr>
+<tr class="field"><th class="docinfo-name">Homepage:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj Homepage</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">PyPI Entry:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/configobj/">ConfigObj on PyPI</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">Development:</th><td class="field-body"><a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">License:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">Support:</th><td class="field-body"><a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a></td>
+</tr>
+</tbody>
+</table>
+<div class="contents topic" id="configobj-manual">
+<p class="topic-title first">ConfigObj Manual</p>
+<ul class="auto-toc simple">
+<li><a class="reference internal" href="#introduction" id="id27">1&nbsp;&nbsp;&nbsp;Introduction</a></li>
+<li><a class="reference internal" href="#downloading" id="id28">2&nbsp;&nbsp;&nbsp;Downloading</a><ul class="auto-toc">
+<li><a class="reference internal" href="#installing" id="id29">2.1&nbsp;&nbsp;&nbsp;Installing</a></li>
+<li><a class="reference internal" href="#documentation" id="id30">2.2&nbsp;&nbsp;&nbsp;Documentation</a></li>
+<li><a class="reference internal" href="#development-version" id="id31">2.3&nbsp;&nbsp;&nbsp;Development Version</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#configobj-in-the-real-world" id="id32">3&nbsp;&nbsp;&nbsp;ConfigObj in the Real World</a></li>
+<li><a class="reference internal" href="#getting-started" id="id33">4&nbsp;&nbsp;&nbsp;Getting Started</a><ul class="auto-toc">
+<li><a class="reference internal" href="#reading-a-config-file" id="id34">4.1&nbsp;&nbsp;&nbsp;Reading a Config File</a></li>
+<li><a class="reference internal" href="#writing-a-config-file" id="id35">4.2&nbsp;&nbsp;&nbsp;Writing a Config File</a></li>
+<li><a class="reference internal" href="#config-files" id="id36">4.3&nbsp;&nbsp;&nbsp;Config Files</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#configobj-specifications" id="id37">5&nbsp;&nbsp;&nbsp;ConfigObj specifications</a><ul class="auto-toc">
+<li><a class="reference internal" href="#methods" id="id38">5.1&nbsp;&nbsp;&nbsp;Methods</a><ul class="auto-toc">
+<li><a class="reference internal" href="#write" id="id39">5.1.1&nbsp;&nbsp;&nbsp;write</a></li>
+<li><a class="reference internal" href="#validate" id="id40">5.1.2&nbsp;&nbsp;&nbsp;validate</a><ul class="auto-toc">
+<li><a class="reference internal" href="#return-value" id="id41">5.1.2.1&nbsp;&nbsp;&nbsp;Return Value</a></li>
+<li><a class="reference internal" href="#mentioning-default-values" id="id42">5.1.2.2&nbsp;&nbsp;&nbsp;Mentioning Default Values</a></li>
+<li><a class="reference internal" href="#mentioning-repeated-sections-and-values" id="id43">5.1.2.3&nbsp;&nbsp;&nbsp;Mentioning Repeated Sections and Values</a></li>
+<li><a class="reference internal" href="#mentioning-simpleval" id="id44">5.1.2.4&nbsp;&nbsp;&nbsp;Mentioning SimpleVal</a></li>
+<li><a class="reference internal" href="#mentioning-copy-mode" id="id45">5.1.2.5&nbsp;&nbsp;&nbsp;Mentioning copy Mode</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#reload" id="id46">5.1.3&nbsp;&nbsp;&nbsp;reload</a></li>
+<li><a class="reference internal" href="#reset" id="id47">5.1.4&nbsp;&nbsp;&nbsp;reset</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#attributes" id="id48">5.2&nbsp;&nbsp;&nbsp;Attributes</a><ul class="auto-toc">
+<li><a class="reference internal" href="#interpolation" id="id49">5.2.1&nbsp;&nbsp;&nbsp;interpolation</a></li>
+<li><a class="reference internal" href="#stringify" id="id50">5.2.2&nbsp;&nbsp;&nbsp;stringify</a></li>
+<li><a class="reference internal" href="#bom" id="id51">5.2.3&nbsp;&nbsp;&nbsp;BOM</a></li>
+<li><a class="reference internal" href="#initial-comment" id="id52">5.2.4&nbsp;&nbsp;&nbsp;initial_comment</a></li>
+<li><a class="reference internal" href="#final-comment" id="id53">5.2.5&nbsp;&nbsp;&nbsp;final_comment</a></li>
+<li><a class="reference internal" href="#list-values" id="id54">5.2.6&nbsp;&nbsp;&nbsp;list_values</a></li>
+<li><a class="reference internal" href="#encoding" id="id55">5.2.7&nbsp;&nbsp;&nbsp;encoding</a></li>
+<li><a class="reference internal" href="#default-encoding" id="id56">5.2.8&nbsp;&nbsp;&nbsp;default_encoding</a></li>
+<li><a class="reference internal" href="#unrepr" id="id57">5.2.9&nbsp;&nbsp;&nbsp;unrepr</a></li>
+<li><a class="reference internal" href="#write-empty-values" id="id58">5.2.10&nbsp;&nbsp;&nbsp;write_empty_values</a></li>
+<li><a class="reference internal" href="#newlines" id="id59">5.2.11&nbsp;&nbsp;&nbsp;newlines</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#the-config-file-format" id="id60">6&nbsp;&nbsp;&nbsp;The Config File Format</a></li>
+<li><a class="reference internal" href="#sections" id="id61">7&nbsp;&nbsp;&nbsp;Sections</a><ul class="auto-toc">
+<li><a class="reference internal" href="#section-attributes" id="id62">7.1&nbsp;&nbsp;&nbsp;Section Attributes</a></li>
+<li><a class="reference internal" href="#section-methods" id="id63">7.2&nbsp;&nbsp;&nbsp;Section Methods</a></li>
+<li><a class="reference internal" href="#walking-a-section" id="id64">7.3&nbsp;&nbsp;&nbsp;Walking a Section</a></li>
+<li><a class="reference internal" href="#examples" id="id65">7.4&nbsp;&nbsp;&nbsp;Examples</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#exceptions" id="id66">8&nbsp;&nbsp;&nbsp;Exceptions</a></li>
+<li><a class="reference internal" href="#validation" id="id67">9&nbsp;&nbsp;&nbsp;Validation</a><ul class="auto-toc">
+<li><a class="reference internal" href="#configspec" id="id68">9.1&nbsp;&nbsp;&nbsp;configspec</a></li>
+<li><a class="reference internal" href="#type-conversion" id="id69">9.2&nbsp;&nbsp;&nbsp;Type Conversion</a></li>
+<li><a class="reference internal" href="#default-values" id="id70">9.3&nbsp;&nbsp;&nbsp;Default Values</a><ul class="auto-toc">
+<li><a class="reference internal" href="#id13" id="id71">9.3.1&nbsp;&nbsp;&nbsp;List Values</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#repeated-sections" id="id72">9.4&nbsp;&nbsp;&nbsp;Repeated Sections</a></li>
+<li><a class="reference internal" href="#repeated-values" id="id73">9.5&nbsp;&nbsp;&nbsp;Repeated Values</a></li>
+<li><a class="reference internal" href="#copy-mode" id="id74">9.6&nbsp;&nbsp;&nbsp;Copy Mode</a></li>
+<li><a class="reference internal" href="#validation-and-interpolation" id="id75">9.7&nbsp;&nbsp;&nbsp;Validation and Interpolation</a></li>
+<li><a class="reference internal" href="#extra-values" id="id76">9.8&nbsp;&nbsp;&nbsp;Extra Values</a></li>
+<li><a class="reference internal" href="#simpleval" id="id77">9.9&nbsp;&nbsp;&nbsp;SimpleVal</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#empty-values" id="id78">10&nbsp;&nbsp;&nbsp;Empty values</a></li>
+<li><a class="reference internal" href="#unrepr-mode" id="id79">11&nbsp;&nbsp;&nbsp;unrepr mode</a></li>
+<li><a class="reference internal" href="#string-interpolation" id="id80">12&nbsp;&nbsp;&nbsp;String Interpolation</a><ul class="auto-toc">
+<li><a class="reference internal" href="#string-interpolation-and-list-values" id="id81">12.1&nbsp;&nbsp;&nbsp;String Interpolation and List Values</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#comments" id="id82">13&nbsp;&nbsp;&nbsp;Comments</a></li>
+<li><a class="reference internal" href="#flatten-errors" id="id83">14&nbsp;&nbsp;&nbsp;flatten_errors</a><ul class="auto-toc">
+<li><a class="reference internal" href="#example-usage" id="id84">14.1&nbsp;&nbsp;&nbsp;Example Usage</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#get-extra-values" id="id85">15&nbsp;&nbsp;&nbsp;get_extra_values</a><ul class="auto-toc">
+<li><a class="reference internal" href="#id14" id="id86">15.1&nbsp;&nbsp;&nbsp;Example Usage</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#credits" id="id87">16&nbsp;&nbsp;&nbsp;CREDITS</a></li>
+<li><a class="reference internal" href="#license" id="id88">17&nbsp;&nbsp;&nbsp;LICENSE</a></li>
+<li><a class="reference internal" href="#todo" id="id89">18&nbsp;&nbsp;&nbsp;TODO</a></li>
+<li><a class="reference internal" href="#issues" id="id90">19&nbsp;&nbsp;&nbsp;ISSUES</a></li>
+<li><a class="reference internal" href="#changelog" id="id91">20&nbsp;&nbsp;&nbsp;CHANGELOG</a><ul class="auto-toc">
+<li><a class="reference internal" href="#version-4-7-2" id="id92">20.1&nbsp;&nbsp;&nbsp;2010/02/27 - Version 4.7.2</a></li>
+<li><a class="reference internal" href="#version-4-7-1" id="id93">20.2&nbsp;&nbsp;&nbsp;2010/02/06 - Version 4.7.1</a></li>
+<li><a class="reference internal" href="#version-4-7-0" id="id94">20.3&nbsp;&nbsp;&nbsp;2010/01/09 - Version 4.7.0</a></li>
+<li><a class="reference internal" href="#version-4-6-0" id="id95">20.4&nbsp;&nbsp;&nbsp;2009/04/13 - Version 4.6.0</a></li>
+<li><a class="reference internal" href="#version-4-5-3" id="id96">20.5&nbsp;&nbsp;&nbsp;2008/06/27 - Version 4.5.3</a></li>
+<li><a class="reference internal" href="#version-4-5-2" id="id97">20.6&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.2</a></li>
+<li><a class="reference internal" href="#version-4-5-1" id="id98">20.7&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.1</a></li>
+<li><a class="reference internal" href="#version-4-5-0" id="id99">20.8&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.0</a></li>
+<li><a class="reference internal" href="#version-4-4-0" id="id100">20.9&nbsp;&nbsp;&nbsp;2007/02/04 - Version 4.4.0</a></li>
+<li><a class="reference internal" href="#version-4-3-3-alpha4" id="id101">20.10&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha4</a></li>
+<li><a class="reference internal" href="#version-4-3-3-alpha3" id="id102">20.11&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha3</a></li>
+<li><a class="reference internal" href="#version-4-3-3-alpha2" id="id103">20.12&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha2</a></li>
+<li><a class="reference internal" href="#version-4-3-3-alpha1" id="id104">20.13&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha1</a></li>
+<li><a class="reference internal" href="#version-4-3-2" id="id105">20.14&nbsp;&nbsp;&nbsp;2006/06/04 - Version 4.3.2</a></li>
+<li><a class="reference internal" href="#version-4-3-1" id="id106">20.15&nbsp;&nbsp;&nbsp;2006/04/29 - Version 4.3.1</a></li>
+<li><a class="reference internal" href="#version-4-3-0" id="id107">20.16&nbsp;&nbsp;&nbsp;2006/03/24 - Version 4.3.0</a></li>
+<li><a class="reference internal" href="#version-4-2-0" id="id108">20.17&nbsp;&nbsp;&nbsp;2006/02/16 - Version 4.2.0</a></li>
+<li><a class="reference internal" href="#version-4-1-0" id="id109">20.18&nbsp;&nbsp;&nbsp;2005/12/14 - Version 4.1.0</a></li>
+<li><a class="reference internal" href="#version-4-0-2" id="id110">20.19&nbsp;&nbsp;&nbsp;2005/12/02 - Version 4.0.2</a></li>
+<li><a class="reference internal" href="#version-4-0-1" id="id111">20.20&nbsp;&nbsp;&nbsp;2005/11/05 - Version 4.0.1</a></li>
+<li><a class="reference internal" href="#version-4-0-0" id="id112">20.21&nbsp;&nbsp;&nbsp;2005/10/17 - Version 4.0.0</a></li>
+<li><a class="reference internal" href="#version-4-0-0-beta-5" id="id113">20.22&nbsp;&nbsp;&nbsp;2005/09/09 - Version 4.0.0 beta 5</a></li>
+<li><a class="reference internal" href="#version-4-0-0-beta-4" id="id114">20.23&nbsp;&nbsp;&nbsp;2005/09/07 - Version 4.0.0 beta 4</a></li>
+<li><a class="reference internal" href="#version-4-0-0-beta-3" id="id115">20.24&nbsp;&nbsp;&nbsp;2005/08/28 - Version 4.0.0 beta 3</a></li>
+<li><a class="reference internal" href="#version-4-0-0-beta-2" id="id116">20.25&nbsp;&nbsp;&nbsp;2005/08/25 - Version 4.0.0 beta 2</a></li>
+<li><a class="reference internal" href="#version-4-0-0-beta-1" id="id117">20.26&nbsp;&nbsp;&nbsp;2005/08/21 - Version 4.0.0 beta 1</a></li>
+<li><a class="reference internal" href="#version-3-0-0" id="id118">20.27&nbsp;&nbsp;&nbsp;2004/05/24 - Version 3.0.0</a></li>
+<li><a class="reference internal" href="#version-2-0-0-beta" id="id119">20.28&nbsp;&nbsp;&nbsp;2004/03/14 - Version 2.0.0 beta</a></li>
+<li><a class="reference internal" href="#version-1-0-5" id="id120">20.29&nbsp;&nbsp;&nbsp;2004/01/29 - Version 1.0.5</a></li>
+<li><a class="reference internal" href="#origins" id="id121">20.30&nbsp;&nbsp;&nbsp;Origins</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#footnotes" id="id122">21&nbsp;&nbsp;&nbsp;Footnotes</a></li>
+</ul>
+</div>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>The best introduction to working with ConfigObj, including the powerful configuration validation system,
+is the article:</p>
+<ul class="last simple">
+<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id27">1&nbsp;&nbsp;&nbsp;Introduction</a></h1>
+<p><strong>ConfigObj</strong> is a simple but powerful config file reader and writer: an <em>ini
+file round tripper</em>. Its main feature is that it is very easy to use, with a
+straightforward programmer's interface and a simple syntax for config files.
+It has lots of other features though :</p>
+<ul>
+<li><p class="first">Nested sections (subsections), to any level</p>
+</li>
+<li><p class="first">List values</p>
+</li>
+<li><p class="first">Multiple line values</p>
+</li>
+<li><p class="first">String interpolation (substitution)</p>
+</li>
+<li><p class="first">Integrated with a powerful validation system</p>
+<blockquote>
+<ul class="simple">
+<li>including automatic type checking/conversion</li>
+<li>repeated sections</li>
+<li>and allowing default values</li>
+</ul>
+</blockquote>
+</li>
+<li><p class="first">When writing out config files, ConfigObj preserves all comments and the order of members and sections</p>
+</li>
+<li><p class="first">Many useful methods and options for working with configuration files (like the 'reload' method)</p>
+</li>
+<li><p class="first">Full Unicode support</p>
+</li>
+</ul>
+<p>For support and bug reports please use the ConfigObj <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a> or the issue tracker on the
+<a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a>.</p>
+</div>
+<div class="section" id="downloading">
+<h1><a class="toc-backref" href="#id28">2&nbsp;&nbsp;&nbsp;Downloading</a></h1>
+<p>The current version is <strong>4.7.2</strong>, dated 27th February 2010. ConfigObj 4 is
+stable and mature. We still expect to pick up a few bugs along the way though <a class="footnote-reference" href="#id15" id="id1">[1]</a>.</p>
+<p>You can get ConfigObj in the following ways :</p>
+<ul>
+<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/configobj.py">configobj.py</a> from Voidspace</p>
+<blockquote>
+<p>ConfigObj has no external dependencies. This file is sufficient to access
+all the functionality except <a class="reference internal" href="#validation">Validation</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/configobj-4.7.2.zip">configobj.zip</a> from Voidspace</p>
+<blockquote>
+<p>This also contains <a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a>  and <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a> from Voidspace</p>
+</li>
+</ul>
+<div class="section" id="installing">
+<h2><a class="toc-backref" href="#id29">2.1&nbsp;&nbsp;&nbsp;Installing</a></h2>
+<p>ConfigObj has a source distribution <a class="reference external" href="http://pypi.python.org/pypi/configobj/">on PyPI</a>. If you unzip
+the archive you can install it with:</p>
+<pre class="literal-block">
+setup.py install
+</pre>
+<p>Alternatively, you can install with easy install or pip:</p>
+<pre class="literal-block">
+easy_install configobj
+</pre>
+</div>
+<div class="section" id="documentation">
+<h2><a class="toc-backref" href="#id30">2.2&nbsp;&nbsp;&nbsp;Documentation</a></h2>
+<p><em>configobj.zip</em> also contains <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a>.</p>
+<ul class="simple">
+<li>You can view <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a> online at the <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj Homepage</a>.</li>
+</ul>
+</div>
+<div class="section" id="development-version">
+<h2><a class="toc-backref" href="#id31">2.3&nbsp;&nbsp;&nbsp;Development Version</a></h2>
+<p>It is sometimes possible to get the latest <em>development version</em> of ConfigObj
+from the Subversion Repository maintained on the <a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a>.</p>
+</div>
+</div>
+<div class="section" id="configobj-in-the-real-world">
+<h1><a class="toc-backref" href="#id32">3&nbsp;&nbsp;&nbsp;ConfigObj in the Real World</a></h1>
+<p><strong>ConfigObj</strong> is widely used. Projects using it include:</p>
+<ul>
+<li><p class="first"><a class="reference external" href="http://bazaar-ng.org">Bazaar</a>.</p>
+<blockquote>
+<p>Bazaar is a Python distributed {acro;VCS;Version Control System}.
+ConfigObj is used to read <tt class="docutils literal">bazaar.conf</tt> and <tt class="docutils literal">branches.conf</tt>.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://chandler.osafoundation.org/">Chandler</a></p>
+<blockquote>
+<p>A Python and <a class="reference external" href="http://www.wxpython.org">wxPython</a>
+Personal Information Manager, being developed by the
+<a class="reference external" href="http://www.osafoundation.org/">OSAFoundation</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://matplotlib.sourceforge.net/">matplotlib</a></p>
+<blockquote>
+<p>A 2D plotting library.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://ipython.scipy.org/moin/">IPython</a></p>
+<blockquote>
+<p>IPython is an enhanced interactive Python shell. IPython uses ConfigObj in a module called 'TConfig' that combines it with enthought <a class="reference external" href="http://code.enthought.com/traits/">Traits</a>: <a class="reference external" href="http://ipython.scipy.org/ipython/ipython/browser/ipython/branches/saw/sandbox/tconfig">tconfig</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><a class="reference external" href="http://elisa.fluendo.com/">Elisa - the Fluendo Mediacenter</a></p>
+<blockquote>
+<p>Elisa is an open source cross-platform media center solution designed to be simple for people not particularly familiar with computers.</p>
+</blockquote>
+</li>
+</ul>
+</div>
+<div class="section" id="getting-started">
+<h1><a class="toc-backref" href="#id33">4&nbsp;&nbsp;&nbsp;Getting Started</a></h1>
+<p>The outstanding feature of using ConfigObj is simplicity. Most functions can be
+performed with single line commands.</p>
+<div class="section" id="reading-a-config-file">
+<h2><a class="toc-backref" href="#id34">4.1&nbsp;&nbsp;&nbsp;Reading a Config File</a></h2>
+<p>The normal way to read a config file, is to give ConfigObj the filename :</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+</pre></div>
+<p>You can also pass the config file in as a list of lines, or a <tt class="docutils literal">StringIO</tt>
+instance, so it doesn't matter where your config data comes from.</p>
+<p>You can then access members of your config file as a dictionary. Subsections
+will also be dictionaries.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="n">value1</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="s">&#39;keyword1&#39;</span><span class="p">]</span>
+<span class="n">value2</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="s">&#39;keyword2&#39;</span><span class="p">]</span>
+<span class="c">#</span>
+<span class="n">section1</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">]</span>
+<span class="n">value3</span> <span class="o">=</span> <span class="n">section1</span><span class="p">[</span><span class="s">&#39;keyword3&#39;</span><span class="p">]</span>
+<span class="n">value4</span> <span class="o">=</span> <span class="n">section1</span><span class="p">[</span><span class="s">&#39;keyword4&#39;</span><span class="p">]</span>
+<span class="c">#</span>
+<span class="c"># you could also write</span>
+<span class="n">value3</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">][</span><span class="s">&#39;keyword3&#39;</span><span class="p">]</span>
+<span class="n">value4</span> <span class="o">=</span> <span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">][</span><span class="s">&#39;keyword4&#39;</span><span class="p">]</span>
+</pre></div>
+</div>
+<div class="section" id="writing-a-config-file">
+<h2><a class="toc-backref" href="#id35">4.2&nbsp;&nbsp;&nbsp;Writing a Config File</a></h2>
+<p>Creating a new config file is just as easy as reading one. You can specify a
+filename when you create the ConfigObj, or do it later <a class="footnote-reference" href="#id16" id="id2">[2]</a>.</p>
+<p>If you <em>don't</em> set a filename, then the <tt class="docutils literal">write</tt> method will return a list of
+lines instead of writing to file. See the <a class="reference internal" href="#write">write</a> method for more details.</p>
+<p>Here we show creating an empty ConfigObj, setting a filename and some values,
+and then writing to file :</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">()</span>
+<span class="n">config</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span>
+<span class="c">#</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;keyword1&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value1</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;keyword2&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value2</span>
+<span class="c">#</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">][</span><span class="s">&#39;keyword3&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value3</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section1&#39;</span><span class="p">][</span><span class="s">&#39;keyword4&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value4</span>
+<span class="c">#</span>
+<span class="n">section2</span> <span class="o">=</span> <span class="p">{</span>
+    <span class="s">&#39;keyword5&#39;</span><span class="p">:</span> <span class="n">value5</span><span class="p">,</span>
+    <span class="s">&#39;keyword6&#39;</span><span class="p">:</span> <span class="n">value6</span><span class="p">,</span>
+    <span class="s">&#39;sub-section&#39;</span><span class="p">:</span> <span class="p">{</span>
+        <span class="s">&#39;keyword7&#39;</span><span class="p">:</span> <span class="n">value7</span>
+        <span class="p">}</span>
+<span class="p">}</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section2&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">section2</span>
+<span class="c">#</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section3&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section3&#39;</span><span class="p">][</span><span class="s">&#39;keyword 8&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">value8</span><span class="p">,</span> <span class="n">value9</span><span class="p">,</span> <span class="n">value10</span><span class="p">]</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;section3&#39;</span><span class="p">][</span><span class="s">&#39;keyword 9&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">value11</span><span class="p">,</span> <span class="n">value12</span><span class="p">,</span> <span class="n">value13</span><span class="p">]</span>
+<span class="c">#</span>
+<span class="n">config</span><span class="o">.</span><span class="n">write</span><span class="p">()</span>
+</pre></div>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p>Keywords and section names can only be strings <a class="footnote-reference" href="#id17" id="id3">[3]</a>. Attempting to set
+anything else will raise a <tt class="docutils literal">ValueError</tt>.</p>
+<p class="last">See <a class="reference internal" href="#string-interpolation-and-list-values">String Interpolation and List Values</a> for an important note on
+using lists in combination with <a class="reference internal" href="#string-interpolation">String Interpolation</a>.</p>
+</div>
+</div>
+<div class="section" id="config-files">
+<h2><a class="toc-backref" href="#id36">4.3&nbsp;&nbsp;&nbsp;Config Files</a></h2>
+<p>The config files that ConfigObj will read and write are based on the 'INI'
+format. This means it will read and write files created for <tt class="docutils literal">ConfigParser</tt>
+<a class="footnote-reference" href="#id18" id="id4">[4]</a>.</p>
+<p>Keywords and values are separated by an <tt class="docutils literal">'='</tt>, and section markers are
+between square brackets. Keywords, values, and section names can be surrounded
+by single or double quotes. Indentation is not significant, but can be
+preserved.</p>
+<p>Subsections are indicated by repeating the square brackets in the section
+marker. You nest levels by using more brackets.</p>
+<p>You can have list values by separating items with a comma, and values spanning
+multiple lines by using triple quotes (single or double).</p>
+<p>For full details on all these see <a class="reference internal" href="#the-config-file-format">the config file format</a>. Here's an example
+to illustrate:</p>
+<pre class="literal-block">
+# This is the 'initial_comment'
+# Which may be several lines
+keyword1 = value1
+'keyword 2' = 'value 2'
+
+[ &quot;section 1&quot; ]
+# This comment goes with keyword 3
+keyword 3 = value 3
+'keyword 4' = value4, value 5, 'value 6'
+
+    [[ sub-section ]]    # an inline comment
+    # sub-section is inside &quot;section 1&quot;
+    'keyword 5' = 'value 7'
+    'keyword 6' = '''A multiline value,
+that spans more than one line :-)
+The line breaks are included in the value.'''
+
+        [[[ sub-sub-section ]]]
+        # sub-sub-section is *in* 'sub-section'
+        # which is in 'section 1'
+        'keyword 7' = 'value 8'
+
+[section 2]    # an inline comment
+keyword8 = &quot;value 9&quot;
+keyword9 = value10     # an inline comment
+# The 'final_comment'
+# Which also may be several lines
+</pre>
+</div>
+</div>
+<div class="section" id="configobj-specifications">
+<h1><a class="toc-backref" href="#id37">5&nbsp;&nbsp;&nbsp;ConfigObj specifications</a></h1>
+<div class="highlight"><pre><span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">infile</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
+                   <span class="n">interpolation</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">list_values</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
+                   <span class="n">create_empty</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">file_error</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">stringify</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
+                   <span class="n">indent_type</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">default_encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">unrepr</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
+                   <span class="n">write_empty_values</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">_inspec</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
+</pre></div>
+<p>Many of the keyword arguments are available as attributes after the config file has been
+parsed.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>New in ConfigObj 4.7.0: Instantiating ConfigObj with
+an <tt class="docutils literal">options</tt> dictionary is now deprecated. To modify code that used to
+do this simply unpack the dictionary in the constructor call:</p>
+<div class="last"><div class="highlight"><pre><span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="o">**</span><span class="n">options</span><span class="p">)</span>
+</pre></div>
+</div></div>
+<p>ConfigObj takes the following arguments (with the default values shown) :</p>
+<ul>
+<li><p class="first">infile: <tt class="docutils literal">None</tt></p>
+<blockquote>
+<p>You don't need to specify an infile. If you omit it, an empty ConfigObj will be
+created. <tt class="docutils literal">infile</tt> <em>can</em> be :</p>
+<ul class="simple">
+<li>Nothing. In which case the <tt class="docutils literal">filename</tt> attribute of your ConfigObj will be
+<tt class="docutils literal">None</tt>. You can set a filename at any time.</li>
+<li>A filename. What happens if the file doesn't already exist is determined by
+the options <tt class="docutils literal">file_error</tt> and <tt class="docutils literal">create_empty</tt>. The filename will be
+preserved as the <tt class="docutils literal">filename</tt> attribute. This can be changed at any time.</li>
+<li>A list of lines. Any trailing newlines will be removed from the lines. The
+<tt class="docutils literal">filename</tt> attribute of your ConfigObj will be <tt class="docutils literal">None</tt>.</li>
+<li>A <tt class="docutils literal">StringIO</tt> instance or file object, or any object with a <tt class="docutils literal">read</tt> method.
+The <tt class="docutils literal">filename</tt> attribute of your ConfigObj will be <tt class="docutils literal">None</tt> <a class="footnote-reference" href="#id19" id="id5">[5]</a>.</li>
+<li>A dictionary. You can initialise a ConfigObj from a dictionary <a class="footnote-reference" href="#id20" id="id6">[6]</a>. The
+<tt class="docutils literal">filename</tt> attribute of your ConfigObj will be <tt class="docutils literal">None</tt>. All keys must be
+strings. In this case, the order of values and sections is arbitrary.</li>
+</ul>
+</blockquote>
+</li>
+<li><p class="first">'raise_errors': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>When parsing, it is possible that the config file will be badly formed. The
+default is to parse the whole file and raise a single error at the end. You
+can set <tt class="docutils literal">raise_errors = True</tt> to have errors raised immediately. See the
+<a class="reference internal" href="#exceptions">exceptions</a> section for more details.</p>
+<p>Altering this value after initial parsing has no effect.</p>
+</blockquote>
+</li>
+<li><p class="first">'list_values': <tt class="docutils literal">True</tt></p>
+<blockquote>
+<p>If <tt class="docutils literal">True</tt> (the default) then list values are possible. If <tt class="docutils literal">False</tt>, the
+values are not parsed for lists.</p>
+<p>If <tt class="docutils literal">list_values = False</tt> then single line values are not quoted or
+unquoted when reading and writing.</p>
+<p>Changing this value affects whether single line values will be quoted or
+not when writing.</p>
+</blockquote>
+</li>
+<li><p class="first">'create_empty': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>If this value is <tt class="docutils literal">True</tt> and the file specified by <tt class="docutils literal">infile</tt> doesn't
+exist, ConfigObj will create an empty file. This can be a useful test that
+the filename makes sense: an impossible filename will cause an error.</p>
+<p>Altering this value after initial parsing has no effect.</p>
+</blockquote>
+</li>
+<li><p class="first">'file_error': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>If this value is <tt class="docutils literal">True</tt> and the file specified by <tt class="docutils literal">infile</tt> doesn't
+exist, ConfigObj will raise an <tt class="docutils literal">IOError</tt>.</p>
+<p>Altering this value after initial parsing has no effect.</p>
+</blockquote>
+</li>
+<li><p class="first">'interpolation': <tt class="docutils literal">True</tt></p>
+<blockquote>
+<p>Whether string interpolation is switched on or not. It is on (<tt class="docutils literal">True</tt>) by
+default.</p>
+<p>You can set this attribute to change whether string interpolation is done
+when values are fetched. See the <a class="reference internal" href="#string-interpolation">String Interpolation</a> section for more details.</p>
+<p>New in ConfigObj 4.7.0: Interpolation will also be done in list values.</p>
+</blockquote>
+</li>
+<li><p class="first">'configspec': <tt class="docutils literal">None</tt></p>
+<blockquote>
+<p>If you want to use the validation system, you supply a configspec. This is
+effectively a type of config file that specifies a check for each member.
+This check can be used to do type conversion as well as check that the
+value is within your required parameters.</p>
+<p>You provide a configspec in the same way as you do the initial file: a
+filename, or list of lines, etc. See the <a class="reference internal" href="#validation">validation</a> section for full
+details on how to use the system.</p>
+<p>When parsed, every section has a <tt class="docutils literal">configspec</tt> with a dictionary of
+configspec checks for <em>that section</em>.</p>
+</blockquote>
+</li>
+<li><p class="first">'stringify': <tt class="docutils literal">True</tt></p>
+<blockquote>
+<p>If you use the validation scheme, it can do type checking <em>and</em> conversion
+for you. This means you may want to set members to integers, or other
+non-string values.</p>
+<p>If 'stringify' is set to <tt class="docutils literal">True</tt> (default) then non-string values will
+be converted to strings when you write the config file. The <a class="reference internal" href="#validation">validation</a>
+process converts values from strings to the required type.</p>
+<p>If 'stringify' is set to <tt class="docutils literal">False</tt>, attempting to set a member to a
+non-string value <a class="footnote-reference" href="#id21" id="id7">[7]</a> will raise a <tt class="docutils literal">TypeError</tt> (no type conversion is
+done by validation).</p>
+</blockquote>
+</li>
+<li><p class="first">'indent_type': <tt class="docutils literal">'&nbsp;&nbsp;&nbsp; '</tt></p>
+<blockquote>
+<p>Indentation is not significant; it can however be present in the input and
+output config. Any combination of tabs and spaces may be used: the string
+will be repeated for each level of indentation. Typical values are: <tt class="docutils literal">''</tt>
+(no indentation), <tt class="docutils literal">'&nbsp;&nbsp;&nbsp; '</tt> (indentation with four spaces, the default),
+<tt class="docutils literal">'\t'</tt> (indentation with one tab).</p>
+<p>If this option is not specified, and the ConfigObj is initialised with a
+dictionary, the indentation used in the output is the default one, that is,
+four spaces.</p>
+<p>If this option is not specified, and the ConfigObj is initialised with a
+list of lines or a file, the indentation used in the first indented line is
+selected and used in all output lines. If no input line is indented, no
+output line will be either.</p>
+<p>If this option <em>is</em> specified, the option value is used in the output
+config, overriding the type of indentation in the input config (if any).</p>
+</blockquote>
+</li>
+<li><p class="first">'encoding': <tt class="docutils literal">None</tt></p>
+<blockquote>
+<p>By default <strong>ConfigObj</strong> does not decode the file/strings you pass it into
+Unicode <a class="footnote-reference" href="#id22" id="id8">[8]</a>. If you want your config file as Unicode (keys and members)
+you need to provide an encoding to decode the file with. This encoding will
+also be used to encode the config file when writing.</p>
+<p>You can change the encoding attribute at any time.</p>
+<p>Any characters in your strings that can't be encoded with the specified
+encoding will raise a <tt class="docutils literal">UnicodeEncodeError</tt>.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p><tt class="docutils literal">UTF16</tt> encoded files will automatically be detected and decoded,
+even if <tt class="docutils literal">encoding</tt> is <tt class="docutils literal">None</tt>.</p>
+<p class="last">This is because it is a 16-bit encoding, and ConfigObj will mangle it
+(split characters on byte boundaries) if it parses it without decoding.</p>
+</div>
+</blockquote>
+</li>
+<li><p class="first">'default_encoding': <tt class="docutils literal">None</tt></p>
+<blockquote>
+<p>When using the <tt class="docutils literal">write</tt> method, <strong>ConfigObj</strong> uses the <tt class="docutils literal">encoding</tt>
+attribute to encode the Unicode strings. If any members (or keys) have
+been set as byte strings instead of Unicode, these must first be decoded
+to Unicode before outputting in the specified encoding.</p>
+<p><tt class="docutils literal">default_encoding</tt>, if specified, is the encoding used to decode byte
+strings in the <strong>ConfigObj</strong> before writing. If this is <tt class="docutils literal">None</tt>, then
+the Python default encoding (<tt class="docutils literal">sys.defaultencoding</tt> - usually ASCII) is
+used.</p>
+<p>For most Western European users, a value of <tt class="docutils literal"><span class="pre">latin-1</span></tt> is sensible.</p>
+<p><tt class="docutils literal">default_encoding</tt> is <em>only</em> used if an <tt class="docutils literal">encoding</tt> is specified.</p>
+<p>Any characters in byte-strings that can't be decoded using the
+<tt class="docutils literal">default_encoding</tt> will raise a <tt class="docutils literal">UnicodeDecodeError</tt>.</p>
+</blockquote>
+</li>
+<li><p class="first">'unrepr': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>The <tt class="docutils literal">unrepr</tt> option reads and writes files in a different mode. This
+allows you to store and retrieve the basic Python data-types using config
+files.</p>
+<p>This uses Python syntax for lists and quoting. See <a class="reference internal" href="#unrepr-mode">unrepr mode</a> for the
+full details.</p>
+</blockquote>
+</li>
+<li><p class="first">'write_empty_values': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>If <tt class="docutils literal">write_empty_values</tt> is <tt class="docutils literal">True</tt>, empty strings are written as
+empty values. See <a class="reference internal" href="#empty-values">Empty Values</a> for more details.</p>
+</blockquote>
+</li>
+<li><p class="first">'_inspec': <tt class="docutils literal">False</tt></p>
+<blockquote>
+<p>Used internally by ConfigObj when parsing configspec files. If you are
+creating a ConfigObj instance from a configspec file you must pass True
+for this argument as well as <tt class="docutils literal">list_values=False</tt>.</p>
+</blockquote>
+</li>
+</ul>
+<div class="section" id="methods">
+<h2><a class="toc-backref" href="#id38">5.1&nbsp;&nbsp;&nbsp;Methods</a></h2>
+<p>The ConfigObj is a subclass of an object called <tt class="docutils literal">Section</tt>, which is itself a
+subclass of <tt class="docutils literal">dict</tt>, the builtin dictionary type. This means it also has
+<strong>all</strong> the normal dictionary methods.</p>
+<p>In addition, the following <a class="reference internal" href="#section-methods">Section Methods</a> may be useful :</p>
+<ul class="simple">
+<li>'restore_default'</li>
+<li>'restore_defaults'</li>
+<li>'walk'</li>
+<li>'merge'</li>
+<li>'dict'</li>
+<li>'as_bool'</li>
+<li>'as_float'</li>
+<li>'as_int'</li>
+<li>'as_list'</li>
+</ul>
+<p>Read about <a class="reference internal" href="#sections">Sections</a> for details of all the methods.</p>
+<div class="hint">
+<p class="first admonition-title">Hint</p>
+<p>The <em>merge</em> method of sections is a recursive update.</p>
+<p>You can use this to merge sections, or even whole ConfigObjs, into each
+other.</p>
+<p class="last">You would typically use this to create a default ConfigObj and then merge
+in user settings. This way users only need to specify values that are
+different from the default. You can use configspecs and validation to
+achieve the same thing of course.</p>
+</div>
+<p>The public methods available on ConfigObj are :</p>
+<ul class="simple">
+<li>'write'</li>
+<li>'validate'</li>
+<li>'reset'</li>
+<li>'reload'</li>
+</ul>
+<div class="section" id="write">
+<h3><a class="toc-backref" href="#id39">5.1.1&nbsp;&nbsp;&nbsp;write</a></h3>
+<div class="highlight"><pre><span class="n">write</span><span class="p">(</span><span class="n">file_object</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
+</pre></div>
+<p>This method writes the current ConfigObj and takes a single, optional argument
+<a class="footnote-reference" href="#id23" id="id9">[9]</a>.</p>
+<p>If you pass in a file like object to the <tt class="docutils literal">write</tt> method, the config file will
+be written to this. (The only method of this object that is used is its
+<tt class="docutils literal">write</tt> method, so a <tt class="docutils literal">StringIO</tt> instance, or any other file like object
+will work.)</p>
+<p>Otherwise, the behaviour of this method depends on the <tt class="docutils literal">filename</tt> attribute
+of the ConfigObj.</p>
+<dl class="docutils">
+<dt><tt class="docutils literal">filename</tt></dt>
+<dd>ConfigObj will write the configuration to the file specified.</dd>
+<dt><tt class="docutils literal">None</tt></dt>
+<dd><tt class="docutils literal">write</tt> returns a list of lines. (Not <tt class="docutils literal">'\n'</tt> terminated)</dd>
+</dl>
+<p>First the 'initial_comment' is written, then the config file, followed by the
+'final_comment'. Comment lines and inline comments are written with each
+key/value.</p>
+</div>
+<div class="section" id="validate">
+<h3><a class="toc-backref" href="#id40">5.1.2&nbsp;&nbsp;&nbsp;validate</a></h3>
+<div class="highlight"><pre><span class="n">validate</span><span class="p">(</span><span class="n">validator</span><span class="p">,</span> <span class="n">preserve_errors</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
+</pre></div>
+<div class="highlight"><pre><span class="c"># filename is the config file</span>
+<span class="c"># filename2 is the configspec</span>
+<span class="c"># (which could also be hardcoded into your program)</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">filename2</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="n">val</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+<span class="n">test</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">test</span> <span class="o">==</span> <span class="bp">True</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;Succeeded.&#39;</span>
+</pre></div>
+<p>The validate method uses the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">validate</a> module to do the
+validation.</p>
+<p>This method validates the ConfigObj against the configspec. By doing type
+conversion as well it can abstract away the config file altogether and present
+the config <em>data</em> to your application (in the types it expects it to be).</p>
+<p>If the <tt class="docutils literal">configspec</tt> attribute of the ConfigObj is <tt class="docutils literal">None</tt>, it raises a
+<tt class="docutils literal">ValueError</tt>.</p>
+<p>If the <a class="reference internal" href="#stringify">stringify</a> attribute is set, this process will convert values to the
+type defined in the configspec.</p>
+<p>The validate method uses checks specified in the configspec and defined in the
+<tt class="docutils literal">Validator</tt> object. It is very easy to extend.</p>
+<p>The configspec looks like the config file, but instead of the value, you
+specify the check (and any default value). See the <a class="reference internal" href="#validation">validation</a> section for
+details.</p>
+<div class="hint">
+<p class="first admonition-title">Hint</p>
+<p>The system of configspecs can seem confusing at first, but is actually
+quite simple and powerful. The best guide to them is this article on
+ConfigObj:</p>
+<ul class="last simple">
+<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
+</ul>
+</div>
+<p>The <tt class="docutils literal">copy</tt> parameter fills in missing values from the configspec (default
+values), <em>without</em> marking the values as defaults. It also causes comments to
+be copied from the configspec into the config file. This allows you to use a
+configspec to create default config files. (Normally default values aren't
+written out by the <tt class="docutils literal">write</tt> method.)</p>
+<p>As of ConfigObj 4.3.0 you can also pass in a ConfigObj instance as your
+configspec. This is especially useful if you need to specify the encoding of
+your configspec file. When you read your configspec file, you <em>must</em> specify
+<tt class="docutils literal">list_values=False</tt>. If you need to support hashes inside the configspec
+values then you must also pass in <tt class="docutils literal">_inspec=True</tt>. This is because configspec
+files actually use a different syntax to config files and inline comment support
+must be switched off to correctly read configspec files with hashes in the values.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">configspec</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">configspecfilename</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">&#39;UTF8&#39;</span><span class="p">,</span>
+                       <span class="n">list_values</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">_inspec</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">configspec</span><span class="p">)</span>
+</pre></div>
+<div class="section" id="return-value">
+<h4><a class="toc-backref" href="#id41">5.1.2.1&nbsp;&nbsp;&nbsp;Return Value</a></h4>
+<p>By default, the validate method either returns <tt class="docutils literal">True</tt> (everything passed)
+or a dictionary of <tt class="docutils literal">True</tt> / <tt class="docutils literal">False</tt> representing pass/fail. The dictionary
+follows the structure of the ConfigObj.</p>
+<p>If a whole section passes then it is replaced with the value <tt class="docutils literal">True</tt>. If a
+whole section fails, then it is replaced with the value <tt class="docutils literal">False</tt>.</p>
+<p>If a value is missing, and there is no default in the check, then the check
+automatically fails.</p>
+<p>The <tt class="docutils literal">validate</tt> method takes an optional keyword argument <tt class="docutils literal">preserve_errors</tt>.
+If you set this to <tt class="docutils literal">True</tt>, instead of getting <tt class="docutils literal">False</tt> for failed checks you
+get the actual error object from the <strong>validate</strong> module. This usually contains
+useful information about why the check failed.</p>
+<p>See the <a class="reference internal" href="#flatten-errors">flatten_errors</a> function for how to turn your results dictionary into
+a useful list of error messages.</p>
+<p>Even if <tt class="docutils literal">preserve_errors</tt> is <tt class="docutils literal">True</tt>, missing keys or sections will still be
+represented by a <tt class="docutils literal">False</tt> in the results dictionary.</p>
+</div>
+<div class="section" id="mentioning-default-values">
+<h4><a class="toc-backref" href="#id42">5.1.2.2&nbsp;&nbsp;&nbsp;Mentioning Default Values</a></h4>
+<p>In the check in your configspec, you can specify a default to be used - by
+using the <tt class="docutils literal">default</tt> keyword. E.g.</p>
+<pre class="literal-block">
+key1 = integer(0, 30, default=15)
+key2 = integer(default=15)
+key3 = boolean(default=True)
+key4 = option('Hello', 'Goodbye', 'Not Today', default='Not Today')
+</pre>
+<p>If the configspec check supplies a default and the value is missing in the
+config, then the default will be set in your ConfigObj. (It is still passed to
+the <tt class="docutils literal">Validator</tt> so that type conversion can be done: this means the default
+value must still pass the check.)</p>
+<p>ConfigObj keeps a record of which values come from defaults, using the
+<tt class="docutils literal">defaults</tt> attribute of <a class="reference internal" href="#sections">sections</a>. Any key in this list isn't written out by
+the <tt class="docutils literal">write</tt> method. If a key is set from outside (even to the same value)
+then it is removed from the <tt class="docutils literal">defaults</tt> list.</p>
+<!-- note:
+
+Even if all the keys in a section are in the defaults list, the section
+marker is still written out. -->
+<p>There is additionally a special case default value of <tt class="docutils literal">None</tt>. If you set the
+default value to <tt class="docutils literal">None</tt> and the value is missing, the value will always be
+set to <tt class="docutils literal">None</tt>. As the other checks don't return <tt class="docutils literal">None</tt> (unless you
+implement your own that do), you can tell that this value came from a default
+value (and was missing from the config file). It allows an easy way of
+implementing optional values. Simply check (and ignore) members that are set
+to <tt class="docutils literal">None</tt>.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">If <a class="reference internal" href="#stringify">stringify</a> is <tt class="docutils literal">False</tt> then <tt class="docutils literal">default=None</tt> returns <tt class="docutils literal">''</tt> instead of
+<tt class="docutils literal">None</tt>. This is because setting a value to a non-string raises an error
+if stringify is unset.</p>
+</div>
+<p>The default value can be a list. See <a class="reference internal" href="#id13">List Values</a> for the way to do this.</p>
+<p>Writing invalid default values is a <em>guaranteed</em> way of confusing your users.
+Default values <strong>must</strong> pass the check.</p>
+</div>
+<div class="section" id="mentioning-repeated-sections-and-values">
+<h4><a class="toc-backref" href="#id43">5.1.2.3&nbsp;&nbsp;&nbsp;Mentioning Repeated Sections and Values</a></h4>
+<p>In the configspec it is possible to cause <em>every</em> sub-section in a section to
+be validated using the same configspec. You do this with a section in the
+configspec  called <tt class="docutils literal">__many__</tt>. Every sub-section in that section has the
+<tt class="docutils literal">__many__</tt> configspec applied to it (without you having to explicitly name
+them in advance).</p>
+<p>Your <tt class="docutils literal">__many__</tt> section can have nested subsections, which can also include
+<tt class="docutils literal">__many__</tt> type sections.</p>
+<p>You can also specify that all values should be validated using the same configspec,
+by having a member with the name <tt class="docutils literal">__many__</tt>. If you want to use repeated values
+along with repeated sections then you can call one of them <tt class="docutils literal">___many___</tt> (triple
+underscores).</p>
+<p>Sections with repeated sections or values can also have specifically named sub-sections
+or values. The <tt class="docutils literal">__many__</tt> configspec will only be used to validate entries that don't
+have an explicit configspec.</p>
+<p>See <a class="reference internal" href="#repeated-sections">Repeated Sections</a> for examples.</p>
+</div>
+<div class="section" id="mentioning-simpleval">
+<h4><a class="toc-backref" href="#id44">5.1.2.4&nbsp;&nbsp;&nbsp;Mentioning SimpleVal</a></h4>
+<p>If you just want to check if all members are present, then you can use the
+<tt class="docutils literal">SimpleVal</tt> object that comes with ConfigObj. It only fails members if they
+are missing.</p>
+<p>Write a configspec that has all the members you want to check for, but set
+every section to <tt class="docutils literal">''</tt>.</p>
+<div class="highlight"><pre><span class="n">val</span> <span class="o">=</span> <span class="n">SimpleVal</span><span class="p">()</span>
+<span class="n">test</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">test</span> <span class="ow">is</span> <span class="bp">True</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;Succeeded.&#39;</span>
+</pre></div>
+</div>
+<div class="section" id="mentioning-copy-mode">
+<h4><a class="toc-backref" href="#id45">5.1.2.5&nbsp;&nbsp;&nbsp;Mentioning copy Mode</a></h4>
+<p>As discussed in <a class="reference internal" href="#mentioning-default-values">Mentioning Default Values</a>, you can use a configspec to
+supply default values. These are marked in the ConfigObj instance as defaults,
+and <em>not</em> written out by the <tt class="docutils literal">write</tt> mode. This means that your users only
+need to supply values that are different from the defaults.</p>
+<p>This can be inconvenient if you <em>do</em> want to write out the default values,
+for example to write out a default config file.</p>
+<p>If you set <tt class="docutils literal">copy=True</tt> when you call validate, then no values are marked as
+defaults. In addition, all comments from the configspec are copied into
+your ConfigObj instance. You can then call <tt class="docutils literal">write</tt> to create your config
+file.</p>
+<p>There is a limitation with this. In order to allow <a class="reference internal" href="#string-interpolation">String Interpolation</a> to work
+within configspecs, <tt class="docutils literal">DEFAULT</tt> sections are not processed by
+validation; even in copy mode.</p>
+</div>
+</div>
+<div class="section" id="reload">
+<h3><a class="toc-backref" href="#id46">5.1.3&nbsp;&nbsp;&nbsp;reload</a></h3>
+<p>If a ConfigObj instance was loaded from the filesystem, then this method will reload it. It
+will also reuse any configspec you supplied at instantiation (including reloading it from
+the filesystem if you passed it in as a filename).</p>
+<p>If the ConfigObj does not have a filename attribute pointing to a file, then a <tt class="docutils literal">ReloadError</tt>
+will be raised.</p>
+</div>
+<div class="section" id="reset">
+<h3><a class="toc-backref" href="#id47">5.1.4&nbsp;&nbsp;&nbsp;reset</a></h3>
+<p>This method takes no arguments and doesn't return anything. It restores a ConfigObj
+instance to a freshly created state.</p>
+</div>
+</div>
+<div class="section" id="attributes">
+<h2><a class="toc-backref" href="#id48">5.2&nbsp;&nbsp;&nbsp;Attributes</a></h2>
+<p>A ConfigObj has the following attributes :</p>
+<ul class="simple">
+<li>indent_type</li>
+<li>interpolation</li>
+<li>stringify</li>
+<li>BOM</li>
+<li>initial_comment</li>
+<li>final_comment</li>
+<li>list_values</li>
+<li>encoding</li>
+<li>default_encoding</li>
+<li>unrepr</li>
+<li>write_empty_values</li>
+<li>newlines</li>
+</ul>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">This doesn't include <em>comments</em>, <em>inline_comments</em>, <em>defaults</em>, or
+<em>configspec</em>. These are actually attributes of <a class="reference internal" href="#sections">Sections</a>.</p>
+</div>
+<p>It also has the following attributes as a result of parsing. They correspond to
+options when the ConfigObj was created, but changing them has no effect.</p>
+<ul class="simple">
+<li>raise_errors</li>
+<li>create_empty</li>
+<li>file_error</li>
+</ul>
+<div class="section" id="interpolation">
+<h3><a class="toc-backref" href="#id49">5.2.1&nbsp;&nbsp;&nbsp;interpolation</a></h3>
+<p>ConfigObj can perform string interpolation in a <em>similar</em> way to
+<tt class="docutils literal">ConfigParser</tt>. See the <a class="reference internal" href="#string-interpolation">String Interpolation</a> section for full details.</p>
+<p>If <tt class="docutils literal">interpolation</tt> is set to <tt class="docutils literal">False</tt>, then interpolation is <em>not</em> done when
+you fetch values.</p>
+</div>
+<div class="section" id="stringify">
+<h3><a class="toc-backref" href="#id50">5.2.2&nbsp;&nbsp;&nbsp;stringify</a></h3>
+<p>If this attribute is set (<tt class="docutils literal">True</tt>) then the <a class="reference internal" href="#validate">validate</a> method changes the
+values in the ConfigObj. These are turned back into strings when <a class="reference internal" href="#write">write</a> is
+called.</p>
+<p>If stringify is unset (<tt class="docutils literal">False</tt>) then attempting to set a value to a non
+string (or a list of strings) will raise a <tt class="docutils literal">TypeError</tt>.</p>
+</div>
+<div class="section" id="bom">
+<h3><a class="toc-backref" href="#id51">5.2.3&nbsp;&nbsp;&nbsp;BOM</a></h3>
+<p>If the initial config file <em>started</em> with the UTF8 Unicode signature (known
+slightly incorrectly as the BOM - Byte Order Mark), or the UTF16 BOM, then
+this attribute is set to <tt class="docutils literal">True</tt>. Otherwise it is <tt class="docutils literal">False</tt>.</p>
+<p>If it is set to <tt class="docutils literal">True</tt> when <tt class="docutils literal">write</tt> is called then, if <tt class="docutils literal">encoding</tt> is set
+to <tt class="docutils literal">None</tt> <em>or</em> to <tt class="docutils literal">utf_8</tt> (and variants) a UTF BOM will be written.</p>
+<p>For UTF16 encodings, a BOM is <em>always</em> written.</p>
+</div>
+<div class="section" id="initial-comment">
+<h3><a class="toc-backref" href="#id52">5.2.4&nbsp;&nbsp;&nbsp;initial_comment</a></h3>
+<p>This is a list of lines. If the ConfigObj is created from an existing file, it
+will contain any lines of comments before the start of the members.</p>
+<p>If you create a new ConfigObj, this will be an empty list.</p>
+<p>The write method puts these lines before it starts writing out the members.</p>
+</div>
+<div class="section" id="final-comment">
+<h3><a class="toc-backref" href="#id53">5.2.5&nbsp;&nbsp;&nbsp;final_comment</a></h3>
+<p>This is a list of lines. If the ConfigObj is created from an existing file, it
+will contain any lines of comments after the last member.</p>
+<p>If you create a new ConfigObj, this will be an empty list.</p>
+<p>The <tt class="docutils literal">write</tt> method puts these lines after it finishes writing out the
+members.</p>
+</div>
+<div class="section" id="list-values">
+<h3><a class="toc-backref" href="#id54">5.2.6&nbsp;&nbsp;&nbsp;list_values</a></h3>
+<p>This attribute is <tt class="docutils literal">True</tt> or <tt class="docutils literal">False</tt>. If set to <tt class="docutils literal">False</tt> then values are
+not parsed for list values. In addition single line values are not unquoted.</p>
+<p>This allows you to do your own parsing of values. It exists primarily to
+support the reading of the <a class="reference internal" href="#configspec">configspec</a> - but has other use cases.</p>
+<p>For example you could use the <tt class="docutils literal">LineParser</tt> from the
+<a class="reference external" href="http://www.voidspace.org.uk/python/listquote.html#lineparser">listquote module</a>
+to read values for nested lists.</p>
+<p>Single line values aren't quoted when writing - but multiline values are
+handled as normal.</p>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p class="last">Because values aren't quoted, leading or trailing whitespace can be lost. This behaviour was changed in version 4.0.1. Prior to this, single line values might have been quoted; even with <tt class="docutils literal">list_values=False</tt>. This means that files written by earlier versions of ConfigObj <em>could</em> now be incompatible and need the quotes removing by hand.</p>
+</div>
+</div>
+<div class="section" id="encoding">
+<h3><a class="toc-backref" href="#id55">5.2.7&nbsp;&nbsp;&nbsp;encoding</a></h3>
+<p>This is the encoding used to encode the output, when you call <tt class="docutils literal">write</tt>. It
+must be a valid encoding <a class="reference external" href="http://docs.python.org/lib/standard-encodings.html">recognised by Python</a>.</p>
+<p>If this value is <tt class="docutils literal">None</tt> then no encoding is done when <tt class="docutils literal">write</tt> is called.</p>
+</div>
+<div class="section" id="default-encoding">
+<h3><a class="toc-backref" href="#id56">5.2.8&nbsp;&nbsp;&nbsp;default_encoding</a></h3>
+<p>If encoding is set, any byte-strings in your ConfigObj instance (keys or
+members) will first be decoded to Unicode using the encoding specified by the
+<tt class="docutils literal">default_encoding</tt> attribute. This ensures that the output is in the encoding
+specified.</p>
+<p>If this value is <tt class="docutils literal">None</tt> then <tt class="docutils literal">sys.defaultencoding</tt> is used instead.</p>
+</div>
+<div class="section" id="unrepr">
+<h3><a class="toc-backref" href="#id57">5.2.9&nbsp;&nbsp;&nbsp;unrepr</a></h3>
+<p>Another boolean value. If this is set, then <tt class="docutils literal">repr(value)</tt> is used to write
+values. This writes values in a slightly different way to the normal ConfigObj
+file syntax.</p>
+<p>This preserves basic Python data-types when read back in. See <a class="reference internal" href="#unrepr-mode">unrepr mode</a>
+for more details.</p>
+</div>
+<div class="section" id="write-empty-values">
+<h3><a class="toc-backref" href="#id58">5.2.10&nbsp;&nbsp;&nbsp;write_empty_values</a></h3>
+<p>Also boolean. If set, values that are an empty string (<tt class="docutils literal">''</tt>) are written as
+empty values. See <a class="reference internal" href="#empty-values">Empty Values</a> for more details.</p>
+</div>
+<div class="section" id="newlines">
+<h3><a class="toc-backref" href="#id59">5.2.11&nbsp;&nbsp;&nbsp;newlines</a></h3>
+<p>When a config file is read, ConfigObj records the type of newline separators in the
+file and uses this separator when writing. It defaults to <tt class="docutils literal">None</tt>, and ConfigObj
+uses the system default (<tt class="docutils literal">os.sep</tt>) if write is called without newlines having
+been set.</p>
+</div>
+</div>
+</div>
+<div class="section" id="the-config-file-format">
+<h1><a class="toc-backref" href="#id60">6&nbsp;&nbsp;&nbsp;The Config File Format</a></h1>
+<p>You saw an example config file in the <a class="reference internal" href="#config-files">Config Files</a> section. Here is a fuller
+specification of the config files used and created by ConfigObj.</p>
+<p>The basic pattern for keywords is:</p>
+<pre class="literal-block">
+# comment line
+# comment line
+keyword = value # inline comment
+</pre>
+<p>Both keyword and value can optionally be surrounded in quotes. The equals sign
+is the only valid divider.</p>
+<p>Values can have comments on the lines above them, and an inline comment after
+them. This, of course, is optional. See the <a class="reference internal" href="#comments">comments</a> section for details.</p>
+<p>If a keyword or value starts or ends with whitespace, or contains a quote mark
+or comma, then it should be surrounded by quotes. Quotes are not necessary if
+whitespace is surrounded by non-whitespace.</p>
+<p>Values can also be lists. Lists are comma separated. You indicate a single
+member list by a trailing comma. An empty list is shown by a single comma:</p>
+<pre class="literal-block">
+keyword1 = value1, value2, value3
+keyword2 = value1, # a single member list
+keyword3 = , # an empty list
+</pre>
+<p>Values that contain line breaks (multi-line values) can be surrounded by triple
+quotes. These can also be used if a value contains both types of quotes. List
+members cannot be surrounded by triple quotes:</p>
+<pre class="literal-block">
+keyword1 = ''' A multi line value
+on several
+lines'''     # with a comment
+keyword2 = '''I won't be &quot;afraid&quot;.'''
+#
+keyword3 = &quot;&quot;&quot; A multi line value
+on several
+lines&quot;&quot;&quot;     # with a comment
+keyword4 = &quot;&quot;&quot;I won't be &quot;afraid&quot;.&quot;&quot;&quot;
+</pre>
+<div class="warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">There is no way of safely quoting values that contain both types of triple
+quotes.</p>
+</div>
+<p>A line that starts with a '#', possibly preceded by whitespace, is a comment.</p>
+<p>New sections are indicated by a section marker line. That is the section name
+in square brackets. Whitespace around the section name is ignored. The name can
+be quoted with single or double quotes. The marker can have comments before it
+and an inline comment after it:</p>
+<pre class="literal-block">
+# The First Section
+[ section name 1 ] # first section
+keyword1 = value1
+
+# The Second Section
+[ &quot;section name 2&quot; ] # second section
+keyword2 = value2
+</pre>
+<p>Any subsections (sections that are <em>inside</em> the current section) are
+designated by repeating the square brackets before and after the section name.
+The number of square brackets represents the nesting level of the sub-section.
+Square brackets may be separated by whitespace; such whitespace, however, will
+not be present in the output config written by the <tt class="docutils literal">write</tt> method.</p>
+<p>Indentation is not significant, but can be preserved. See the description of
+the <tt class="docutils literal">indent_type</tt> option, in the <a class="reference internal" href="#configobj-specifications">ConfigObj specifications</a> chapter, for the
+details.</p>
+<p>A <em>NestingError</em> will be raised if the number of the opening and the closing
+brackets in a section marker is not the same, or if a sub-section's nesting
+level is greater than the nesting level of it parent plus one.</p>
+<p>In the outer section, single values can only appear before any sub-section.
+Otherwise they will belong to the sub-section immediately before them:</p>
+<pre class="literal-block">
+# initial comment
+keyword1 = value1
+keyword2 = value2
+
+[section 1]
+keyword1 = value1
+keyword2 = value2
+
+    [[sub-section]]
+    # this is in section 1
+    keyword1 = value1
+    keyword2 = value2
+
+        [[[nested section]]]
+        # this is in sub section
+        keyword1 = value1
+        keyword2 = value2
+
+    [[sub-section2]]
+    # this is in section 1 again
+    keyword1 = value1
+    keyword2 = value2
+
+[[sub-section3]]
+# this is also in section 1, indentation is misleading here
+keyword1 = value1
+keyword2 = value2
+
+# final comment
+</pre>
+<p>When parsed, the above config file produces the following data structure:</p>
+<div class="highlight"><pre><span class="n">ConfigObj</span><span class="p">({</span>
+    <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+    <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+    <span class="s">&#39;section 1&#39;</span><span class="p">:</span> <span class="p">{</span>
+        <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+        <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+        <span class="s">&#39;sub-section&#39;</span><span class="p">:</span> <span class="p">{</span>
+            <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+            <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+            <span class="s">&#39;nested section&#39;</span><span class="p">:</span> <span class="p">{</span>
+                <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+                <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+            <span class="p">},</span>
+        <span class="p">},</span>
+        <span class="s">&#39;sub-section2&#39;</span><span class="p">:</span> <span class="p">{</span>
+            <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+            <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+        <span class="p">},</span>
+        <span class="s">&#39;sub-section3&#39;</span><span class="p">:</span> <span class="p">{</span>
+            <span class="s">&#39;keyword1&#39;</span><span class="p">:</span> <span class="s">&#39;value1&#39;</span><span class="p">,</span>
+            <span class="s">&#39;keyword2&#39;</span><span class="p">:</span> <span class="s">&#39;value2&#39;</span><span class="p">,</span>
+        <span class="p">},</span>
+    <span class="p">},</span>
+<span class="p">})</span>
+</pre></div>
+<p>Sections are ordered: note how the structure of the resulting ConfigObj is in
+the same order as the original file.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>In ConfigObj 4.3.0 <em>empty values</em> became valid syntax. They are read as the
+empty string. There is also an option/attribute (<tt class="docutils literal">write_empty_values</tt>) to
+allow the writing of these.</p>
+<p>This is mainly to support 'legacy' config files, written from other
+applications. This is documented under <a class="reference internal" href="#empty-values">Empty Values</a>.</p>
+<p class="last"><a class="reference internal" href="#unrepr-mode">unrepr mode</a> introduces <em>another</em> syntax variation, used for storing
+basic Python datatypes in config files.</p>
+</div>
+</div>
+<div class="section" id="sections">
+<h1><a class="toc-backref" href="#id61">7&nbsp;&nbsp;&nbsp;Sections</a></h1>
+<p>Every section in a ConfigObj has certain properties. The ConfigObj itself also
+has these properties, because it too is a section (sometimes called the <em>root
+section</em>).</p>
+<p><tt class="docutils literal">Section</tt> is a subclass of the standard new-class dictionary, therefore it
+has <strong>all</strong> the methods of a normal dictionary. This means you can <tt class="docutils literal">update</tt>
+and <tt class="docutils literal">clear</tt> sections.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>You create a new section by assigning a member to be a dictionary.</p>
+<p>The new <tt class="docutils literal">Section</tt> is created <em>from</em> the dictionary, but isn't the same
+thing as the dictionary. (So references to the dictionary you use to create
+the section <em>aren't</em> references to the new section).</p>
+<p>Note the following.</p>
+<div class="highlight"><pre><span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">()</span>
+<span class="n">vals</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;key1&#39;</span><span class="p">:</span> <span class="s">&#39;value 1&#39;</span><span class="p">,</span>
+        <span class="s">&#39;key2&#39;</span><span class="p">:</span> <span class="s">&#39;value 2&#39;</span>
+       <span class="p">}</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;vals&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">vals</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;vals&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="n">vals</span>
+<span class="bp">True</span>
+<span class="n">config</span><span class="p">[</span><span class="s">&#39;vals&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="n">vals</span>
+<span class="bp">False</span>
+</pre></div>
+<p class="last">If you now change <tt class="docutils literal">vals</tt>, the changes won't be reflected in <tt class="docutils literal"><span class="pre">config['vals']</span></tt>.</p>
+</div>
+<p>A section is ordered, following its <tt class="docutils literal">scalars</tt> and <tt class="docutils literal">sections</tt>
+attributes documented below. This means that the following dictionary
+attributes return their results in order.</p>
+<ul>
+<li><p class="first">'__iter__'</p>
+<blockquote>
+<p>More commonly known as <tt class="docutils literal">for member in section:</tt>.</p>
+</blockquote>
+</li>
+<li><p class="first">'__repr__' and '__str__'</p>
+<blockquote>
+<p>Any time you print or display the ConfigObj.</p>
+</blockquote>
+</li>
+<li><p class="first">'items'</p>
+</li>
+<li><p class="first">'iteritems'</p>
+</li>
+<li><p class="first">'iterkeys'</p>
+</li>
+<li><p class="first">'itervalues'</p>
+</li>
+<li><p class="first">'keys'</p>
+</li>
+<li><p class="first">'popitem'</p>
+</li>
+<li><p class="first">'values'</p>
+</li>
+</ul>
+<div class="section" id="section-attributes">
+<h2><a class="toc-backref" href="#id62">7.1&nbsp;&nbsp;&nbsp;Section Attributes</a></h2>
+<ul>
+<li><p class="first">main</p>
+<blockquote>
+<p>A reference to the main ConfigObj.</p>
+</blockquote>
+</li>
+<li><p class="first">parent</p>
+<blockquote>
+<p>A reference to the 'parent' section, the section that this section is a
+member of.</p>
+<p>On the ConfigObj this attribute is a reference to itself. You can use this
+to walk up the sections, stopping when <tt class="docutils literal">section.parent is section</tt>.</p>
+</blockquote>
+</li>
+<li><p class="first">depth</p>
+<blockquote>
+<p>The nesting level of the current section.</p>
+<p>If you create a new ConfigObj and add sections, 1 will be added to the
+depth level between sections.</p>
+</blockquote>
+</li>
+<li><p class="first">defaults</p>
+<blockquote>
+<p>This attribute is a list of scalars that came from default values. Values
+that came from defaults aren't written out by the <tt class="docutils literal">write</tt> method.
+Setting any of these values in the section removes them from the defaults
+list.</p>
+</blockquote>
+</li>
+<li><p class="first">default_values</p>
+<blockquote>
+<p>This attribute is a dictionary mapping keys to the default values for the
+keys. By default it is an empty dictionary and is populated when you
+validate the ConfigObj.</p>
+</blockquote>
+</li>
+<li><p class="first">scalars, sections</p>
+<blockquote>
+<p>These attributes are normal lists, representing the order that members,
+single values and subsections appear in the section. The order will either
+be the order of the original config file, <em>or</em> the order that you added
+members.</p>
+<p>The order of members in this lists is the order that <tt class="docutils literal">write</tt> creates in
+the config file. The <tt class="docutils literal">scalars</tt> list is output before the <tt class="docutils literal">sections</tt>
+list.</p>
+<p>Adding or removing members also alters these lists. You can manipulate the
+lists directly to alter the order of members.</p>
+<div class="warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">If you alter the <tt class="docutils literal">scalars</tt>, <tt class="docutils literal">sections</tt>, or <tt class="docutils literal">defaults</tt> attributes
+so that they no longer reflect the contents of the section, you will
+break your ConfigObj.</p>
+</div>
+<p>See also the <tt class="docutils literal">rename</tt> method.</p>
+</blockquote>
+</li>
+<li><p class="first">comments</p>
+<blockquote>
+<p>This is a dictionary of comments associated with each member. Each entry is
+a list of lines. These lines are written out before the member.</p>
+</blockquote>
+</li>
+<li><p class="first">inline_comments</p>
+<blockquote>
+<p>This is <em>another</em> dictionary of comments associated with each member. Each
+entry is a string that is put inline with the member.</p>
+</blockquote>
+</li>
+<li><p class="first">configspec</p>
+<blockquote>
+<p>The configspec attribute is a dictionary mapping scalars to <em>checks</em>. A
+check defines the expected type and possibly the allowed values for a
+member.</p>
+<p>The configspec has the same format as a config file, but instead of values
+it has a specification for the value (which may include a default value).
+The <a class="reference internal" href="#validate">validate</a> method uses it to check the config file makes sense. If a
+configspec is passed in when the ConfigObj is created, then it is parsed
+and broken up to become the <tt class="docutils literal">configspec</tt> attribute of each section.</p>
+<p>If you didn't pass in a configspec, this attribute will be <tt class="docutils literal">None</tt> on the
+root section (the main ConfigObj).</p>
+<p>You can set the configspec attribute directly on a section.</p>
+<p>See the <a class="reference internal" href="#validation">validation</a> section for full details of how to write configspecs.</p>
+</blockquote>
+</li>
+<li><p class="first">extra_values</p>
+<blockquote>
+<p>By default an empty list. After <a class="reference internal" href="#validation">validation</a> this is populated with any members
+of the section that don't appear in the configspec (i.e. they are additional
+values). Rather than accessing this directly it may be more convenient to get
+all the extra values in a config file using the <a class="reference internal" href="#get-extra-values">get_extra_values</a> function.</p>
+<p>New in ConfigObj 4.7.0.</p>
+</blockquote>
+</li>
+</ul>
+</div>
+<div class="section" id="section-methods">
+<h2><a class="toc-backref" href="#id63">7.2&nbsp;&nbsp;&nbsp;Section Methods</a></h2>
+<ul>
+<li><p class="first"><strong>dict</strong></p>
+<blockquote>
+<p>This method takes no arguments. It returns a deep copy of the section as a
+dictionary. All subsections will also be dictionaries, and list values will
+be copies, rather than references to the original <a class="footnote-reference" href="#id24" id="id10">[10]</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>rename</strong></p>
+<blockquote>
+<p><tt class="docutils literal">rename(oldkey, newkey)</tt></p>
+<p>This method renames a key, without affecting its position in the sequence.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>merge</strong></p>
+<blockquote>
+<p><tt class="docutils literal">merge(indict)</tt></p>
+<p>This method is a <em>recursive update</em> method. It allows you to merge two
+config files together.</p>
+<p>You would typically use this to create a default ConfigObj and then merge
+in user settings. This way users only need to specify values that are
+different from the default.</p>
+<p>For example :</p>
+<div class="highlight"><pre><span class="c"># def_cfg contains your default config settings</span>
+<span class="c"># user_cfg contains the user settings</span>
+<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">def_cfg</span><span class="p">)</span>
+<span class="n">usr</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">user_cfg</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="n">cfg</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">usr</span><span class="p">)</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">cfg now contains a combination of the default settings and the user</span>
+<span class="sd">settings.</span>
+
+<span class="sd">The user settings will have overwritten any of the default ones.</span>
+<span class="sd">&quot;&quot;&quot;</span>
+</pre></div>
+</blockquote>
+</li>
+<li><p class="first"><strong>walk</strong></p>
+<blockquote>
+<p>This method can be used to transform values and names. See <a class="reference internal" href="#walking-a-section">walking a
+section</a> for examples and explanation.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>as_bool</strong></p>
+<blockquote>
+<p><tt class="docutils literal">as_bool(key)</tt></p>
+<p>Returns <tt class="docutils literal">True</tt> if the key contains a string that represents <tt class="docutils literal">True</tt>, or
+is the <tt class="docutils literal">True</tt> object.</p>
+<p>Returns <tt class="docutils literal">False</tt> if the key contains a string that represents <tt class="docutils literal">False</tt>,
+or is the <tt class="docutils literal">False</tt> object.</p>
+<p>Raises a <tt class="docutils literal">ValueError</tt> if the key contains anything else.</p>
+<p>Strings that represent <tt class="docutils literal">True</tt> are (not case sensitive):</p>
+<pre class="literal-block">
+true, yes, on, 1
+</pre>
+<p>Strings that represent <tt class="docutils literal">False</tt> are:</p>
+<pre class="literal-block">
+false, no, off, 0
+</pre>
+</blockquote>
+</li>
+<li><p class="first"><strong>as_int</strong></p>
+<blockquote>
+<p><tt class="docutils literal">as_int(key)</tt></p>
+<p>This returns the value contained in the specified key as an integer.</p>
+<p>It raises a <tt class="docutils literal">ValueError</tt> if the conversion can't be done.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>as_float</strong></p>
+<blockquote>
+<p><tt class="docutils literal">as_float(key)</tt></p>
+<p>This returns the value contained in the specified key as a float.</p>
+<p>It raises a <tt class="docutils literal">ValueError</tt> if the conversion can't be done.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>as_list</strong></p>
+<blockquote>
+<p><tt class="docutils literal">as_list(key)</tt></p>
+<p>This returns the value contained in the specified key as a list.</p>
+<p>If it isn't a list it will be wrapped as a list so that you can
+guarantee the returned value will be a list.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>restore_default</strong></p>
+<blockquote>
+<p><tt class="docutils literal">restore_default(key)</tt></p>
+<p>Restore (and return) the default value for the specified key.</p>
+<p>This method will only work for a ConfigObj that was created
+with a configspec and has been validated.</p>
+<p>If there is no default value for this key, <tt class="docutils literal">KeyError</tt> is raised.</p>
+</blockquote>
+</li>
+<li><p class="first"><strong>restore_defaults</strong></p>
+<blockquote>
+<p><tt class="docutils literal">restore_defaults()</tt></p>
+<p>Recursively restore default values to all members
+that have them.</p>
+<p>This method will only work for a ConfigObj that was created
+with a configspec and has been validated.</p>
+<p>It doesn't delete or modify entries without default values.</p>
+</blockquote>
+</li>
+</ul>
+</div>
+<div class="section" id="walking-a-section">
+<h2><a class="toc-backref" href="#id64">7.3&nbsp;&nbsp;&nbsp;Walking a Section</a></h2>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">The walk method allows you to call a function on every member/name.</p>
+</div>
+<div class="highlight"><pre><span class="n">walk</span><span class="p">(</span><span class="n">function</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
+     <span class="n">call_on_sections</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="o">**</span><span class="n">keywargs</span><span class="p">)</span>
+</pre></div>
+<p><tt class="docutils literal">walk</tt> is a method of the <tt class="docutils literal">Section</tt> object. This means it is also a method
+of ConfigObj.</p>
+<p>It walks through every member and calls a function on the keyword and value. It
+walks recursively through subsections.</p>
+<p>It returns a dictionary of all the computed values.</p>
+<p>If the function raises an exception, the default is to propagate the error, and
+stop. If <tt class="docutils literal">raise_errors=False</tt> then it sets the return value for that keyword
+to <tt class="docutils literal">False</tt> instead, and continues. This is similar to the way <a class="reference internal" href="#validation">validation</a>
+works.</p>
+<p>Your function receives the arguments <tt class="docutils literal">(section, key)</tt>. The current value is
+then <tt class="docutils literal">section[key]</tt> <a class="footnote-reference" href="#id25" id="id11">[11]</a>. Any unrecognised keyword arguments you pass to
+walk, are passed on to the function.</p>
+<p>Normally <tt class="docutils literal">walk</tt> just recurses into subsections. If you are transforming (or
+checking) names as well as values, then you want to be able to change the names
+of sections. In this case set <tt class="docutils literal">call_on_sections</tt> to <tt class="docutils literal">True</tt>. Now, on
+encountering a sub-section, <em>first</em> the function is called for the <em>whole</em>
+sub-section, and <em>then</em> it recurses into it's members. This means your function
+must be able to handle receiving dictionaries as well as strings and lists.</p>
+<p>If you are using the return value from <tt class="docutils literal">walk</tt> <em>and</em> <tt class="docutils literal">call_on_sections</tt>,
+note that walk discards the return value when it calls your function.</p>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p class="last">You can use <tt class="docutils literal">walk</tt> to transform the names of members of a section
+but you mustn't add or delete members.</p>
+</div>
+</div>
+<div class="section" id="examples">
+<h2><a class="toc-backref" href="#id65">7.4&nbsp;&nbsp;&nbsp;Examples</a></h2>
+<p>You can use this for transforming all values in your ConfigObj. For example
+you might like the nested lists from ConfigObj 3. This was provided by the
+<a class="reference external" href="http://www.voidspace.org.uk/python/modules.shtml#listquote">listquote</a> module. You could switch off the parsing for list values
+(<tt class="docutils literal">list_values=False</tt>) and use listquote to parse every value.</p>
+<p>Another thing you might want to do is use the Python escape codes in your
+values. You might be <em>used</em> to using <tt class="docutils literal">\n</tt> for line feed and <tt class="docutils literal">\t</tt> for tab.
+Obviously we'd need to decode strings that come from the config file (using the
+escape codes). Before writing out we'll need to put the escape codes back in
+encode.</p>
+<p>As an example we'll write a function to use with walk, that encodes or decodes
+values using the <tt class="docutils literal"><span class="pre">string-escape</span></tt> codec.</p>
+<p>The function has to take each value and set the new value. As a bonus we'll
+create one function that will do decode <em>or</em> encode depending on a keyword
+argument.</p>
+<p>We don't want to work with section names, we're only transforming values, so
+we can leave <tt class="docutils literal">call_on_sections</tt> as <tt class="docutils literal">False</tt>. This means the two datatypes we
+have to handle are strings and lists, we can ignore everything else. (We'll
+treat tuples as lists as well).</p>
+<p>We're not using the return values, so it doesn't need to return anything, just
+change the values if appropriate.</p>
+<div class="highlight"><pre><span class="k">def</span> <span class="nf">string_escape</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">encode</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">    A function to encode or decode using the &#39;string-escape&#39; codec.</span>
+<span class="sd">    To be passed to the walk method of a ConfigObj.</span>
+<span class="sd">    By default it decodes.</span>
+<span class="sd">    To encode, pass in the keyword argument ``encode=True``.</span>
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="n">val</span> <span class="o">=</span> <span class="n">section</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+    <span class="c"># is it a type we can work with</span>
+    <span class="c"># NOTE: for platforms where Python &gt; 2.2</span>
+    <span class="c"># you can use basestring instead of (str, unicode)</span>
+    <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
+        <span class="c"># no !</span>
+        <span class="k">return</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">)):</span>
+        <span class="c"># it&#39;s a string !</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">encode</span><span class="p">:</span>
+            <span class="n">section</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&#39;string-escape&#39;</span><span class="p">)</span>
+        <span class="k">else</span><span class="p">:</span>
+            <span class="n">section</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;string-escape&#39;</span><span class="p">)</span>
+    <span class="k">else</span><span class="p">:</span>
+        <span class="c"># it must be a list or tuple!</span>
+        <span class="c"># we&#39;ll be lazy and create a new list</span>
+        <span class="n">newval</span> <span class="o">=</span> <span class="p">[]</span>
+        <span class="c"># we&#39;ll check every member of the list</span>
+        <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">val</span><span class="p">:</span>
+            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">)):</span>
+                <span class="k">if</span> <span class="ow">not</span> <span class="n">encode</span><span class="p">:</span>
+                    <span class="n">newval</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&#39;string-escape&#39;</span><span class="p">))</span>
+                <span class="k">else</span><span class="p">:</span>
+                   <span class="n">newval</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;string-escape&#39;</span><span class="p">))</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="n">newval</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
+        <span class="c"># done !</span>
+        <span class="n">section</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span>  <span class="n">newval</span>
+
+<span class="c"># assume we have a ConfigObj called ``config``</span>
+<span class="c">#</span>
+<span class="c"># To decode</span>
+<span class="n">config</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">string_escape</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="c"># To encode.</span>
+<span class="c"># Because ``walk`` doesn&#39;t recognise the ``encode`` argument</span>
+<span class="c"># it passes it to our function.</span>
+<span class="n">config</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">string_escape</span><span class="p">,</span> <span class="n">encode</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+</pre></div>
+<p>Here's a simple example of using <tt class="docutils literal">walk</tt> to transform names and values. One
+usecase of this would be to create a <em>standard</em> config file with placeholders
+for section and keynames. You can then use walk to create new config files
+and change values and member names :</p>
+<div class="highlight"><pre><span class="c"># We use &#39;XXXX&#39; as a placeholder</span>
+<span class="n">config</span> <span class="o">=</span> <span class="s">&#39;&#39;&#39;</span>
+<span class="s">XXXXkey1 = XXXXvalue1</span>
+<span class="s">XXXXkey2 = XXXXvalue2</span>
+<span class="s">XXXXkey3 = XXXXvalue3</span>
+<span class="s">[XXXXsection1]</span>
+<span class="s">XXXXkey1 = XXXXvalue1</span>
+<span class="s">XXXXkey2 = XXXXvalue2</span>
+<span class="s">XXXXkey3 = XXXXvalue3</span>
+<span class="s">[XXXXsection2]</span>
+<span class="s">XXXXkey1 = XXXXvalue1</span>
+<span class="s">XXXXkey2 = XXXXvalue2</span>
+<span class="s">XXXXkey3 = XXXXvalue3</span>
+<span class="s">    [[XXXXsection1]]</span>
+<span class="s">    XXXXkey1 = XXXXvalue1</span>
+<span class="s">    XXXXkey2 = XXXXvalue2</span>
+<span class="s">    XXXXkey3 = XXXXvalue3</span>
+<span class="s">&#39;&#39;&#39;</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
+<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">config</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="k">def</span> <span class="nf">transform</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+    <span class="n">val</span> <span class="o">=</span> <span class="n">section</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+    <span class="n">newkey</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;XXXX&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1&#39;</span><span class="p">)</span>
+    <span class="n">section</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">newkey</span><span class="p">)</span>
+    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="p">(</span><span class="nb">tuple</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)):</span>
+        <span class="k">pass</span>
+    <span class="k">else</span><span class="p">:</span>
+        <span class="n">val</span> <span class="o">=</span> <span class="n">val</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;XXXX&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1&#39;</span><span class="p">)</span>
+        <span class="n">section</span><span class="p">[</span><span class="n">newkey</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>
+<span class="c">#</span>
+<span class="n">cfg</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">transform</span><span class="p">,</span> <span class="n">call_on_sections</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">cfg</span>
+<span class="n">ConfigObj</span><span class="p">({</span><span class="s">&#39;CLIENT1key1&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value1&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1key2&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value2&#39;</span><span class="p">,</span>
+<span class="s">&#39;CLIENT1key3&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value3&#39;</span><span class="p">,</span>
+<span class="s">&#39;CLIENT1section1&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s">&#39;CLIENT1key1&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value1&#39;</span><span class="p">,</span>
+    <span class="s">&#39;CLIENT1key2&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value2&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1key3&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value3&#39;</span><span class="p">},</span>
+<span class="s">&#39;CLIENT1section2&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s">&#39;CLIENT1key1&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value1&#39;</span><span class="p">,</span>
+    <span class="s">&#39;CLIENT1key2&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value2&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1key3&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value3&#39;</span><span class="p">,</span>
+    <span class="s">&#39;CLIENT1section1&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s">&#39;CLIENT1key1&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value1&#39;</span><span class="p">,</span>
+        <span class="s">&#39;CLIENT1key2&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value2&#39;</span><span class="p">,</span> <span class="s">&#39;CLIENT1key3&#39;</span><span class="p">:</span> <span class="s">&#39;CLIENT1value3&#39;</span><span class="p">}}})</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="exceptions">
+<h1><a class="toc-backref" href="#id66">8&nbsp;&nbsp;&nbsp;Exceptions</a></h1>
+<p>There are several places where ConfigObj may raise exceptions (other than
+because of bugs).</p>
+<ol class="arabic">
+<li><dl class="first docutils">
+<dt>If a configspec filename you pass in doesn't exist, or a config file</dt>
+<dd><p class="first last">filename doesn't exist <em>and</em> <tt class="docutils literal">file_error=True</tt>, an <tt class="docutils literal">IOError</tt> will be
+raised.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt>If you try to set a non-string key, or a non string value when</dt>
+<dd><p class="first last"><tt class="docutils literal">stringify=False</tt>, a <tt class="docutils literal">TypeError</tt> will be raised.</p>
+</dd>
+</dl>
+</li>
+<li><p class="first">A badly built config file will cause parsing errors.</p>
+</li>
+<li><p class="first">A parsing error can also occur when reading a configspec.</p>
+</li>
+<li><dl class="first docutils">
+<dt>In string interpolation you can specify a value that doesn't exist, or</dt>
+<dd><p class="first last">create circular references (recursion).</p>
+</dd>
+</dl>
+</li>
+</ol>
+<p>Number 5 (which is actually two different types of exceptions) is documented
+in <a class="reference internal" href="#string-interpolation">String Interpolation</a>.</p>
+<p><em>This</em> section is about errors raised during parsing.</p>
+<p>The base error class is <tt class="docutils literal">ConfigObjError</tt>. This is a subclass of
+<tt class="docutils literal">SyntaxError</tt>, so you can trap for <tt class="docutils literal">SyntaxError</tt> without needing to
+directly import any of the ConfigObj exceptions.</p>
+<p>The following other exceptions are defined (all deriving from
+<tt class="docutils literal">ConfigObjError</tt>) :</p>
+<ul>
+<li><p class="first"><tt class="docutils literal">NestingError</tt></p>
+<blockquote>
+<p>This error indicates either a mismatch in the brackets in a section marker,
+or an excessive level of nesting.</p>
+</blockquote>
+</li>
+<li><p class="first"><tt class="docutils literal">ParseError</tt></p>
+<blockquote>
+<p>This error indicates that a line is badly written. It is neither a valid
+<tt class="docutils literal">key = value</tt> line, nor a valid section marker line, nor a comment line.</p>
+</blockquote>
+</li>
+<li><p class="first"><tt class="docutils literal">DuplicateError</tt></p>
+<blockquote>
+<p>The keyword or section specified already exists.</p>
+</blockquote>
+</li>
+<li><p class="first"><tt class="docutils literal">ConfigspecError</tt></p>
+<blockquote>
+<p>An error occurred whilst parsing a configspec.</p>
+</blockquote>
+</li>
+<li><p class="first"><tt class="docutils literal">UnreprError</tt></p>
+<blockquote>
+<p>An error occurred when parsing a value in <a class="reference internal" href="#unrepr-mode">unrepr mode</a>.</p>
+</blockquote>
+</li>
+<li><p class="first"><tt class="docutils literal">ReloadError</tt></p>
+<blockquote>
+<p><tt class="docutils literal">reload</tt> was called on a ConfigObj instance that doesn't have a valid
+filename attribute.</p>
+</blockquote>
+</li>
+</ul>
+<p>When parsing a configspec, ConfigObj will stop on the first error it
+encounters.  It will raise a <tt class="docutils literal">ConfigspecError</tt>. This will have an <tt class="docutils literal">error</tt>
+attribute, which is the actual error that was raised.</p>
+<p>Behaviour when parsing a config file depends on the option <tt class="docutils literal">raise_errors</tt>.
+If ConfigObj encounters an error while parsing a config file:</p>
+<blockquote>
+<p>If <tt class="docutils literal">raise_errors=True</tt> then ConfigObj will raise the appropriate error
+and parsing will stop.</p>
+<p>If <tt class="docutils literal">raise_errors=False</tt> (the default) then parsing will continue to the
+end and <em>all</em> errors will be collected.</p>
+</blockquote>
+<p>If <tt class="docutils literal">raise_errors</tt> is False and multiple errors are found a <tt class="docutils literal">ConfigObjError</tt>
+is raised. The error raised has a <tt class="docutils literal">config</tt> attribute, which is the parts of
+the ConfigObj that parsed successfully. It also has an attribute <tt class="docutils literal">errors</tt>,
+which is a list of <em>all</em> the errors raised. Each entry in the list is an
+instance of the appropriate error type. Each one has the following attributes
+(useful for delivering a sensible error message to your user) :</p>
+<ul class="simple">
+<li><tt class="docutils literal">line</tt>: the original line that caused the error.</li>
+<li><tt class="docutils literal">line_number</tt>: its number in the config file.</li>
+<li><tt class="docutils literal">message</tt>: the error message that accompanied the error.</li>
+</ul>
+<p>If only one error is found, then that error is re-raised. The error still has
+the <tt class="docutils literal">config</tt> and <tt class="docutils literal">errors</tt> attributes. This means that your error handling
+code can be the same whether one error is raised in parsing , or several.</p>
+<p>It also means that in the most common case (a single error) a useful error
+message will be raised.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">One wrongly written line could break the basic structure of your config
+file. This could cause every line after it to flag an error, so having a
+list of all the lines that caused errors may not be as useful as it sounds.</p>
+</div>
+</div>
+<div class="section" id="validation">
+<h1><a class="toc-backref" href="#id67">9&nbsp;&nbsp;&nbsp;Validation</a></h1>
+<div class="hint">
+<p class="first admonition-title">Hint</p>
+<p>The system of configspecs can seem confusing at first, but is actually
+quite simple and powerful. The best reference is my article on ConfigObj:</p>
+<ul class="last simple">
+<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
+</ul>
+</div>
+<p>Validation is done through a combination of the <a class="reference internal" href="#configspec">configspec</a> and a <tt class="docutils literal">Validator</tt>
+object. For this you need <em>validate.py</em> <a class="footnote-reference" href="#id26" id="id12">[12]</a>. See <a class="reference internal" href="#downloading">downloading</a> if you don't
+have a copy.</p>
+<p>Validation can perform two different operations :</p>
+<ol class="arabic">
+<li><dl class="first docutils">
+<dt>Check that a value meets a specification. For example, check that a value</dt>
+<dd><p class="first last">is an integer between one and six, or is a choice from a specific set of
+options.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt>It can convert the value into the type required. For example, if one of</dt>
+<dd><p class="first last">your values is a port number, validation will turn it into an integer for
+you.</p>
+</dd>
+</dl>
+</li>
+</ol>
+<p>So validation can act as a transparent layer between the datatypes of your
+application configuration (boolean, integers, floats, etc) and the text format
+of your config file.</p>
+<div class="section" id="configspec">
+<h2><a class="toc-backref" href="#id68">9.1&nbsp;&nbsp;&nbsp;configspec</a></h2>
+<p>The <tt class="docutils literal">validate</tt> method checks members against an entry in the configspec. Your
+configspec therefore resembles your config file, with a check for every member.</p>
+<p>In order to perform validation you need a <tt class="docutils literal">Validator</tt> object. This has
+several useful built-in check functions. You can also create your own custom
+functions and register them with your Validator object.</p>
+<p>Each check is the name of one of these functions, including any parameters and
+keyword arguments. The configspecs look like function calls, and they map to
+function calls.</p>
+<p>The basic datatypes that an un-extended Validator can test for are :</p>
+<ul class="simple">
+<li>boolean values (True and False)</li>
+<li>integers (including minimum and maximum values)</li>
+<li>floats (including min and max)</li>
+<li>strings (including min and max length)</li>
+<li>IP addresses (v4 only)</li>
+</ul>
+<p>It can also handle lists of these types and restrict a value to being one from
+a set of options.</p>
+<p>An example configspec is going to look something like:</p>
+<pre class="literal-block">
+port = integer(0, 100)
+user = string(max=25)
+mode = option('quiet', 'loud', 'silent')
+</pre>
+<p>You can specify default values, and also have the same configspec applied to
+several sections. This is called <a class="reference internal" href="#repeated-sections">repeated sections</a>.</p>
+<p>For full details on writing configspecs, please refer to the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">validate.py
+documentation</a>.</p>
+<div class="important">
+<p class="first admonition-title">Important</p>
+<p>Your configspec is read by ConfigObj in the same way as a config file.</p>
+<p>That means you can do interpolation <em>within</em> your configspec.</p>
+<p>In order to allow this, checks in the 'DEFAULT' section (of the root level
+of your configspec) are <em>not</em> used.</p>
+<p>If you want to use a configspec <em>without</em> interpolation being done in it
+you can create your configspec manually and switch off interpolation:</p>
+<div class="last"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+
+<span class="n">configspec</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">spec_filename</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">list_values</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
+                       <span class="n">_inspec</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="n">conf</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">config_filename</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">configspec</span><span class="p">)</span>
+</pre></div>
+</div></div>
+<p>If you need to specify the encoding of your configspec, then you can pass in a
+ConfigObj instance as your configspec. When you read your configspec file, you
+<em>must</em> specify <tt class="docutils literal">list_values=False</tt>. If you need to support hashes in
+configspec values then you must also pass in <tt class="docutils literal">_inspec=True</tt>.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">configspec</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">configspecfilename</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">&#39;UTF8&#39;</span><span class="p">,</span>
+                       <span class="n">list_values</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">_inspec</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">configspec</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="section" id="type-conversion">
+<h2><a class="toc-backref" href="#id69">9.2&nbsp;&nbsp;&nbsp;Type Conversion</a></h2>
+<p>By default, validation does type conversion. This means that if you specify
+<tt class="docutils literal">integer</tt> as the check, then calling <a class="reference internal" href="#validate">validate</a> will actually change the value
+to an integer (so long as the check succeeds).</p>
+<p>It also means that when you call the <a class="reference internal" href="#write">write</a> method, the value will be converted
+back into a string using the <tt class="docutils literal">str</tt> function.</p>
+<p>To switch this off, and leave values as strings after validation, you need to
+set the <a class="reference internal" href="#stringify">stringify</a> attribute to <tt class="docutils literal">False</tt>. If this is the case, attempting to
+set a value to a non-string will raise an error.</p>
+</div>
+<div class="section" id="default-values">
+<h2><a class="toc-backref" href="#id70">9.3&nbsp;&nbsp;&nbsp;Default Values</a></h2>
+<p>You can set a default value in your check. If the value is missing from the
+config file then this value will be used instead. This means that your user
+only has to supply values that differ from the defaults.</p>
+<p>If you <em>don't</em> supply a default then for a value to be missing is an error,
+and this will show in the <a class="reference internal" href="#return-value">return value</a> from validate.</p>
+<p>Additionally you can set the default to be <tt class="docutils literal">None</tt>. This means the value will
+be set to <tt class="docutils literal">None</tt> (the object) <em>whichever check is used</em>. (It will be set to
+<tt class="docutils literal">''</tt> rather than <tt class="docutils literal">None</tt> if <a class="reference internal" href="#stringify">stringify</a> is <tt class="docutils literal">False</tt>). You can use this
+to easily implement optional values in your config files.</p>
+<pre class="literal-block">
+port = integer(0, 100, default=80)
+user = string(max=25, default=0)
+mode = option('quiet', 'loud', 'silent', default='loud')
+nick = string(default=None)
+</pre>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>Because the default goes through type conversion, it also has to pass the
+check.</p>
+<p class="last">Note that <tt class="docutils literal">default=None</tt> is case sensitive.</p>
+</div>
+<div class="section" id="id13">
+<h3><a class="toc-backref" href="#id71">9.3.1&nbsp;&nbsp;&nbsp;List Values</a></h3>
+<p>It's possible that you will want to specify a list as a default value. To avoid
+confusing syntax with commas and quotes you use a list constructor to specify
+that keyword arguments are lists. This includes the <tt class="docutils literal">default</tt> value. This
+makes checks look something like:</p>
+<pre class="literal-block">
+checkname(default=list('val1', 'val2', 'val3'))
+</pre>
+<p>This works with all keyword arguments, but is most useful for default values.</p>
+</div>
+</div>
+<div class="section" id="repeated-sections">
+<h2><a class="toc-backref" href="#id72">9.4&nbsp;&nbsp;&nbsp;Repeated Sections</a></h2>
+<p>Repeated sections are a way of specifying a configspec for a section that
+should be applied to all unspecified subsections in the same section.</p>
+<p>The easiest way of explaining this is to give an example. Suppose you have a
+config file that describes a dog. That dog has various attributes, but it can
+also have many fleas. You don't know in advance how many fleas there will be,
+or what they will be called, but you want each flea validated against the same
+configspec.</p>
+<p>We can define a section called <em>fleas</em>. We want every flea in that section
+(every sub-section) to have the same configspec applied to it. We do this by
+defining a single section called <tt class="docutils literal">__many__</tt>.</p>
+<pre class="literal-block">
+[dog]
+name = string(default=Rover)
+age = float(0, 99, default=0)
+
+    [[fleas]]
+
+        [[[__many__]]]
+        bloodsucker = boolean(default=True)
+        children = integer(default=10000)
+        size = option(small, tiny, micro, default=tiny)
+</pre>
+<p>Every flea on our dog will now be validated using the <tt class="docutils literal">__many__</tt> configspec.</p>
+<p><tt class="docutils literal">__many__</tt> sections can have sub-sections, including their own <tt class="docutils literal">__many__</tt>
+sub-sections. Defaults work in the normal way in repeated sections.</p>
+</div>
+<div class="section" id="repeated-values">
+<h2><a class="toc-backref" href="#id73">9.5&nbsp;&nbsp;&nbsp;Repeated Values</a></h2>
+<p>As well as using <tt class="docutils literal">__many__</tt> to validate unspecified sections you can use it to validate values. For
+example, to specify that all values in a section should be integers:</p>
+<pre class="literal-block">
+[section]
+    __many__ = integer
+</pre>
+<p>If you want to use repeated values alongside repeated sections you can call one <tt class="docutils literal">__many__</tt> and the
+other <tt class="docutils literal">___many___</tt> (with three underscores).</p>
+</div>
+<div class="section" id="copy-mode">
+<h2><a class="toc-backref" href="#id74">9.6&nbsp;&nbsp;&nbsp;Copy Mode</a></h2>
+<p>Because you can specify default values in your configspec, you can use
+ConfigObj to write out default config files for your application.</p>
+<p>However, normally values supplied from a default in a configspec are <em>not</em>
+written out by the <tt class="docutils literal">write</tt> method.</p>
+<p>To do this, you need to specify <tt class="docutils literal">copy=True</tt> when you call validate. As well
+as not marking values as default, all the comments in the configspec file
+will be copied into your ConfigObj instance.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="n">vdt</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">configspec</span><span class="o">=</span><span class="s">&#39;default.ini&#39;</span><span class="p">)</span>
+<span class="n">config</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="s">&#39;new_default.ini&#39;</span>
+<span class="n">config</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">vdt</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="n">config</span><span class="o">.</span><span class="n">write</span><span class="p">()</span>
+</pre></div>
+<p>If you need to support hashes in the configspec values then you must create
+it with <tt class="docutils literal">_inspec=True</tt>. This has the side effect of switching off the parsing
+of inline comments, meaning that they won't be copied into the new config file.
+(ConfigObj syntax is slightly different from configspec syntax and the parser
+can't support both inline comments and hashes in configspec values.)</p>
+</div>
+<div class="section" id="validation-and-interpolation">
+<h2><a class="toc-backref" href="#id75">9.7&nbsp;&nbsp;&nbsp;Validation and Interpolation</a></h2>
+<p>String interpolation and validation don't play well together. When validation
+changes type it sets the value. If the value uses interpolation, then the
+interpolation reference would normally be overwritten. Calling <tt class="docutils literal">write</tt> would
+then use the absolute value and the interpolation reference would be lost.</p>
+<p>As a compromise - if the value is unchanged by validation then it is not reset.
+This means strings that pass through validation unmodified will not be
+overwritten. If validation changes type - the value has to be overwritten, and
+any interpolation references are lost.</p>
+</div>
+<div class="section" id="extra-values">
+<h2><a class="toc-backref" href="#id76">9.8&nbsp;&nbsp;&nbsp;Extra Values</a></h2>
+<p>After validation the <tt class="docutils literal">extra_values</tt> member of every section that is listed in
+the configspec will be populated with the names of members that are in the
+config file but not in the configspec.</p>
+<p>If you are reporting configuration errors to your user this information can be
+useful, for example some missing entries may be due to misspelt entries that
+appear as extra values.</p>
+<p>See the <a class="reference internal" href="#get-extra-values">get_extra_values</a> function</p>
+<p>New in ConfigObj 4.7.0.</p>
+</div>
+<div class="section" id="simpleval">
+<h2><a class="toc-backref" href="#id77">9.9&nbsp;&nbsp;&nbsp;SimpleVal</a></h2>
+<p>You may not need a full validation process, but still want to check if all the
+expected values are present.</p>
+<p>Provided as part of the ConfigObj module is the <tt class="docutils literal">SimpleVal</tt> object. This has
+a dummy <tt class="docutils literal">test</tt> method that always passes.</p>
+<p>The only reason a test will fail is if the value is missing. The return value
+from <tt class="docutils literal">validate</tt> will either be <tt class="docutils literal">True</tt>, meaning all present, or a dictionary
+with <tt class="docutils literal">False</tt> for all missing values/sections.</p>
+<p>To use it, you still need to pass in a valid configspec when you create the
+ConfigObj, but just set all the values to <tt class="docutils literal">''</tt>. Then create an instance of
+<tt class="docutils literal">SimpleVal</tt> and pass it to the <tt class="docutils literal">validate</tt> method.</p>
+<p>As a trivial example if you had the following config file:</p>
+<pre class="literal-block">
+# config file for an application
+port = 80
+protocol = http
+domain = voidspace
+top_level_domain = org.uk
+</pre>
+<p>You would write the following configspec:</p>
+<pre class="literal-block">
+port = ''
+protocol = ''
+domain = ''
+top_level_domain = ''
+</pre>
+<div class="highlight"><pre><span class="n">config</span> <span class="o">=</span> <span class="n">Configobj</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">configspec</span><span class="p">)</span>
+<span class="n">val</span> <span class="o">=</span> <span class="n">SimpleVal</span><span class="p">()</span>
+<span class="n">test</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">test</span> <span class="o">==</span> <span class="bp">True</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;All values present.&#39;</span>
+<span class="k">elif</span> <span class="n">test</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;No values present!&#39;</span>
+<span class="k">else</span><span class="p">:</span>
+    <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">test</span><span class="p">:</span>
+        <span class="k">if</span> <span class="n">test</span><span class="p">[</span><span class="n">entry</span><span class="p">]</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span>
+            <span class="k">print</span> <span class="s">&#39;&quot;</span><span class="si">%s</span><span class="s">&quot; missing.&#39;</span> <span class="o">%</span> <span class="n">entry</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="empty-values">
+<h1><a class="toc-backref" href="#id78">10&nbsp;&nbsp;&nbsp;Empty values</a></h1>
+<p>Many config files from other applications allow empty values. As of version
+4.3.0, ConfigObj will read these as an empty string.</p>
+<p>A new option/attribute has been added (<tt class="docutils literal">write_empty_values</tt>) to allow
+ConfigObj to write empty strings as empty values.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">configobj</span> <span class="kn">import</span> <span class="n">ConfigObj</span>
+<span class="n">cfg</span> <span class="o">=</span> <span class="s">&#39;&#39;&#39;</span>
+<span class="s">    key =</span>
+<span class="s">    key2 = # a comment</span>
+<span class="s">&#39;&#39;&#39;</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">cfg</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">config</span>
+<span class="n">ConfigObj</span><span class="p">({</span><span class="s">&#39;key&#39;</span><span class="p">:</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;key2&#39;</span><span class="p">:</span> <span class="s">&#39;&#39;</span><span class="p">})</span>
+
+<span class="n">config</span><span class="o">.</span><span class="n">write_empty_values</span> <span class="o">=</span> <span class="bp">True</span>
+<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">config</span><span class="o">.</span><span class="n">write</span><span class="p">():</span>
+    <span class="k">print</span> <span class="n">line</span>
+
+<span class="n">key</span> <span class="o">=</span>
+<span class="n">key2</span> <span class="o">=</span>     <span class="c"># a comment</span>
+</pre></div>
+</div>
+<div class="section" id="unrepr-mode">
+<h1><a class="toc-backref" href="#id79">11&nbsp;&nbsp;&nbsp;unrepr mode</a></h1>
+<p>The <tt class="docutils literal">unrepr</tt> option allows you to store and retrieve the basic Python
+data-types using config files. It has to use a slightly different syntax to
+normal ConfigObj files. Unsurprisingly it uses Python syntax.</p>
+<p>This means that lists are different (they are surrounded by square brackets),
+and strings <em>must</em> be quoted.</p>
+<p>The types that <tt class="docutils literal">unrepr</tt> can work with are :</p>
+<blockquote>
+<div class="line-block">
+<div class="line">strings, lists tuples</div>
+<div class="line">None, True, False</div>
+<div class="line">dictionaries, integers, floats</div>
+<div class="line">longs and complex numbers</div>
+</div>
+</blockquote>
+<p>You can't store classes, types or instances.</p>
+<p><tt class="docutils literal">unrepr</tt> uses <tt class="docutils literal">repr(object)</tt> to write out values, so it currently <em>doesn't</em>
+check that you are writing valid objects. If you attempt to read an unsupported
+value, ConfigObj will raise a <tt class="docutils literal">configobj.UnknownType</tt> exception.</p>
+<p>Values that are triple quoted cased. The triple quotes are removed <em>before</em>
+converting. This means that you can use triple quotes to write dictionaries
+over several lines in your config files. They won't be written like this
+though.</p>
+<p>If you are writing config files by hand, for use with <tt class="docutils literal">unrepr</tt>, you should
+be aware of the following differences from normal ConfigObj syntax :</p>
+<blockquote>
+<div class="line-block">
+<div class="line">List : <tt class="docutils literal">['A List', 'With', 'Strings']</tt></div>
+<div class="line">Strings : <tt class="docutils literal">&quot;Must be quoted.&quot;</tt></div>
+<div class="line">Backslash : <tt class="docutils literal">&quot;The backslash must be escaped \\&quot;</tt></div>
+</div>
+</blockquote>
+<p>These all follow normal Python syntax.</p>
+<p>In unrepr mode <em>inline comments</em> are not saved. This is because lines are
+parsed using the <a class="reference external" href="http://docs.python.org/lib/compiler.html">compiler package</a>
+which discards comments.</p>
+</div>
+<div class="section" id="string-interpolation">
+<h1><a class="toc-backref" href="#id80">12&nbsp;&nbsp;&nbsp;String Interpolation</a></h1>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">String interpolation can slow down (slightly) the fetching of values
+from your config object. If you aren't using interpolation and it
+is performance critical then create your instance with
+<tt class="docutils literal">interpolation=False</tt>.</p>
+</div>
+<p>ConfigObj allows string interpolation <em>similar</em> to the way <tt class="docutils literal">ConfigParser</tt>
+or <tt class="docutils literal">string.Template</tt> work. The value of the <tt class="docutils literal">interpolation</tt> attribute
+determines which style of interpolation you want to use. Valid values are
+&quot;ConfigParser&quot; or &quot;Template&quot; (case-insensitive, so &quot;configparser&quot; and
+&quot;template&quot; will also work). For backwards compatibility reasons, the value
+<tt class="docutils literal">True</tt> is also a valid value for the <tt class="docutils literal">interpolation</tt> attribute, and
+will select <tt class="docutils literal">ConfigParser</tt>-style interpolation. At some undetermined point
+in the future, that default <em>may</em> change to <tt class="docutils literal">Template</tt>-style interpolation.</p>
+<p>For <tt class="docutils literal">ConfigParser</tt>-style interpolation, you specify a value to be
+substituted by including <tt class="docutils literal">%(name)s</tt> in the value.</p>
+<p>For <tt class="docutils literal">Template</tt>-style interpolation, you specify a value to be substituted
+by including <tt class="docutils literal">${cl}name{cr}</tt> in the value. Alternately, if 'name' is a valid
+Python identifier (i.e., is composed of nothing but alphanumeric characters,
+plus the underscore character), then the braces are optional and the value
+can be written as <tt class="docutils literal">$name</tt>.</p>
+<p>Note that <tt class="docutils literal">ConfigParser</tt>-style interpolation and <tt class="docutils literal">Template</tt>-style
+interpolation are mutually exclusive; you cannot have a configuration file
+that's a mix of one or the other. Pick one and stick to it. <tt class="docutils literal">Template</tt>-style
+interpolation is simpler to read and write by hand, and is recommended if
+you don't have a particular reason to use <tt class="docutils literal">ConfigParser</tt>-style.</p>
+<p>Interpolation checks first the current section to see if <tt class="docutils literal">name</tt> is the key
+to a value. ('name' is case sensitive).</p>
+<p>If it doesn't find it, next it checks the 'DEFAULT' sub-section of the current
+section.</p>
+<p>If it still doesn't find it, it moves on to check the parent section and the
+parent section's 'DEFAULT' subsection, and so on all the way up to the main
+section.</p>
+<p>If the value specified isn't found in any of these locations, then a
+<tt class="docutils literal">MissingInterpolationOption</tt> error is raised (a subclass of
+<tt class="docutils literal">ConfigObjError</tt>).</p>
+<p>If it is found then the returned value is also checked for substitutions. This
+allows you to make up compound values (for example directory paths) that use
+more than one default value. It also means it's possible to create circular
+references. If there are any circular references which would cause an infinite
+interpolation loop, an <tt class="docutils literal">InterpolationLoopError</tt> is raised.</p>
+<p>Both of these errors are subclasses of <tt class="docutils literal">InterpolationError</tt>, which is a
+subclass of <tt class="docutils literal">ConfigObjError</tt>.</p>
+<p>String interpolation and validation don't play well together. This is because
+validation overwrites values - and so may erase the interpolation references.
+See <a class="reference internal" href="#validation-and-interpolation">Validation and Interpolation</a>. (This can only happen if validation
+has to <em>change</em> the value).</p>
+<p>New in ConfigObj 4.7.0: String interpolation is now done in members of list
+values.</p>
+<div class="section" id="string-interpolation-and-list-values">
+<h2><a class="toc-backref" href="#id81">12.1&nbsp;&nbsp;&nbsp;String Interpolation and List Values</a></h2>
+<p>Since version 4.7 string interpolation is done on string members of list values.
+If interpolation changes any members of the list then what you get back is a
+<em>copy</em> of the list rather than the original list.</p>
+<p>This makes fetching list values slightly slower when interpolation is on, it
+also means that if you mutate the list changes won't be reflected in the
+original list:</p>
+<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">c</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">()</span>
+<span class="o">&gt;&gt;&gt;</span> <span class="n">c</span><span class="p">[</span><span class="s">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;boo&#39;</span>
+<span class="o">&gt;&gt;&gt;</span> <span class="n">c</span><span class="p">[</span><span class="s">&#39;bar&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;</span><span class="si">%(foo)s</span><span class="s">&#39;</span><span class="p">]</span>
+<span class="o">&gt;&gt;&gt;</span> <span class="n">c</span><span class="p">[</span><span class="s">&#39;bar&#39;</span><span class="p">]</span>
+<span class="p">[</span><span class="s">&#39;boo&#39;</span><span class="p">]</span>
+<span class="o">&gt;&gt;&gt;</span> <span class="n">c</span><span class="p">[</span><span class="s">&#39;bar&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&#39;fish&#39;</span><span class="p">)</span>
+<span class="o">&gt;&gt;&gt;</span> <span class="n">c</span><span class="p">[</span><span class="s">&#39;bar&#39;</span><span class="p">]</span>
+<span class="p">[</span><span class="s">&#39;boo&#39;</span><span class="p">]</span>
+</pre></div>
+<p>Instead of mutating the list you must create a new list and reassign it.</p>
+</div>
+</div>
+<div class="section" id="comments">
+<h1><a class="toc-backref" href="#id82">13&nbsp;&nbsp;&nbsp;Comments</a></h1>
+<p>Any line that starts with a '#', possibly preceded by whitespace, is a comment.</p>
+<p>If a config file starts with comments then these are preserved as the
+<a class="reference internal" href="#initial-comment">initial_comment</a>.</p>
+<p>If a config file ends with comments then these are preserved as the
+<a class="reference internal" href="#final-comment">final_comment</a>.</p>
+<p>Every key or section marker may have lines of comments immediately above it.
+These are saved as the <tt class="docutils literal">comments</tt> attribute of the section. Each member is a
+list of lines.</p>
+<p>You can also have a comment inline with a value. These are saved as the
+<tt class="docutils literal">inline_comments</tt> attribute of the section, with one entry per member of the
+section.</p>
+<p>Subsections (section markers in the config file) can also have comments.</p>
+<p>See <a class="reference internal" href="#section-attributes">Section Attributes</a> for more on these attributes.</p>
+<p>These comments are all written back out by the <tt class="docutils literal">write</tt> method.</p>
+</div>
+<div class="section" id="flatten-errors">
+<h1><a class="toc-backref" href="#id83">14&nbsp;&nbsp;&nbsp;flatten_errors</a></h1>
+<div class="highlight"><pre><span class="n">flatten_errors</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">res</span><span class="p">)</span>
+</pre></div>
+<p><a class="reference internal" href="#validation">Validation</a> is a powerful way of checking that the values supplied by the user
+make sense.</p>
+<p>The <a class="reference internal" href="#validate">validate</a> method returns a results dictionary that represents pass or fail
+for each value. This doesn't give you any information about <em>why</em> the check
+failed.</p>
+<p><tt class="docutils literal">flatten_errors</tt> is an example function that turns a results dictionary into
+a flat list, that only contains values that <em>failed</em>.</p>
+<p><tt class="docutils literal">cfg</tt> is the ConfigObj instance being checked, <tt class="docutils literal">res</tt> is the results
+dictionary returned by <tt class="docutils literal">validate</tt>.</p>
+<p>It returns a list of keys that failed. Each member of the list is a tuple:</p>
+<pre class="literal-block">
+([list of sections...], key, result)
+</pre>
+<p>If <tt class="docutils literal">validate</tt> was called with <tt class="docutils literal">preserve_errors=False</tt> (the default)
+then <tt class="docutils literal">result</tt> will always be <tt class="docutils literal">False</tt>.</p>
+<p><em>list of sections</em> is a flattened list of sections that the key was found
+in.</p>
+<p>If the section was missing then key will be <tt class="docutils literal">None</tt>.</p>
+<p>If the value (or section) was missing then <tt class="docutils literal">result</tt> will be <tt class="docutils literal">False</tt>.</p>
+<p>If <tt class="docutils literal">validate</tt> was called with <tt class="docutils literal">preserve_errors=True</tt> and a value
+was present, but failed the check, then <tt class="docutils literal">result</tt> will be the exception
+object returned. You can use this as a string that describes the failure.</p>
+<p>For example :</p>
+<blockquote>
+<em>The value &quot;3&quot; is of the wrong type</em>.</blockquote>
+<div class="section" id="example-usage">
+<h2><a class="toc-backref" href="#id84">14.1&nbsp;&nbsp;&nbsp;Example Usage</a></h2>
+<p>The output from <tt class="docutils literal">flatten_errors</tt> is a list of tuples.</p>
+<p>Here is an example of how you could present this information to the user.</p>
+<div class="highlight"><pre><span class="n">vtor</span> <span class="o">=</span> <span class="n">validate</span><span class="o">.</span><span class="n">Validator</span><span class="p">()</span>
+<span class="c"># ini is your config file - cs is the configspec</span>
+<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">ini</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">cs</span><span class="p">)</span>
+<span class="n">res</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">vtor</span><span class="p">,</span> <span class="n">preserve_errors</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">flatten_errors</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">res</span><span class="p">):</span>
+    <span class="c"># each entry is a tuple</span>
+    <span class="n">section_list</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="n">entry</span>
+    <span class="k">if</span> <span class="n">key</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
+       <span class="n">section_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
+    <span class="k">else</span><span class="p">:</span>
+        <span class="n">section_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&#39;[missing section]&#39;</span><span class="p">)</span>
+    <span class="n">section_string</span> <span class="o">=</span> <span class="s">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">section_list</span><span class="p">)</span>
+    <span class="k">if</span> <span class="n">error</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span>
+        <span class="n">error</span> <span class="o">=</span> <span class="s">&#39;Missing value or section.&#39;</span>
+    <span class="k">print</span> <span class="n">section_string</span><span class="p">,</span> <span class="s">&#39; = &#39;</span><span class="p">,</span> <span class="n">error</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="get-extra-values">
+<h1><a class="toc-backref" href="#id85">15&nbsp;&nbsp;&nbsp;get_extra_values</a></h1>
+<div class="highlight"><pre><span class="n">get_extra_values</span><span class="p">(</span><span class="n">conf</span><span class="p">)</span>
+</pre></div>
+<p>New in ConfigObj 4.7.0.</p>
+<p>Find all the values and sections not in the configspec from a validated
+ConfigObj.</p>
+<p><tt class="docutils literal">get_extra_values</tt> returns a list of tuples where each tuple represents
+either an extra section, or an extra value.</p>
+<p>The tuples contain two values, a tuple representing the section the value
+is in and the name of the extra values. For extra values in the top level
+section the first member will be an empty tuple. For values in the 'foo'
+section the first member will be <tt class="docutils literal"><span class="pre">('foo',)</span></tt>. For members in the 'bar'
+subsection of the 'foo' section the first member will be <tt class="docutils literal">('foo', 'bar')</tt>.</p>
+<p>Extra sections will only have one entry. Values and subsections inside
+an extra section aren't listed separately.</p>
+<p>NOTE: If you call <tt class="docutils literal">get_extra_values</tt> on a ConfigObj instance that hasn't
+been validated it will return an empty list.</p>
+<div class="section" id="id14">
+<h2><a class="toc-backref" href="#id86">15.1&nbsp;&nbsp;&nbsp;Example Usage</a></h2>
+<p>The output from <tt class="docutils literal">get_extra_values</tt> is a list of tuples.</p>
+<p>Here is an example of how you could present this information to the user.</p>
+<div class="highlight"><pre><span class="n">vtor</span> <span class="o">=</span> <span class="n">validate</span><span class="o">.</span><span class="n">Validator</span><span class="p">()</span>
+<span class="c"># ini is your config file - cs is the configspec</span>
+<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">ini</span><span class="p">,</span> <span class="n">configspec</span><span class="o">=</span><span class="n">cs</span><span class="p">)</span>
+<span class="n">cfg</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">vtor</span><span class="p">,</span> <span class="n">preserve_errors</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+
+<span class="k">for</span> <span class="n">sections</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">get_extra_values</span><span class="p">(</span><span class="n">cfg</span><span class="p">):</span>
+
+    <span class="c"># this code gets the extra values themselves</span>
+    <span class="n">the_section</span> <span class="o">=</span> <span class="n">cfg</span>
+    <span class="k">for</span> <span class="n">section</span> <span class="ow">in</span> <span class="n">sections</span><span class="p">:</span>
+        <span class="n">the_section</span> <span class="o">=</span> <span class="n">cfg</span><span class="p">[</span><span class="n">section</span><span class="p">]</span>
+
+    <span class="c"># the_value may be a section or a value</span>
+    <span class="n">the_value</span> <span class="o">=</span> <span class="n">the_section</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
+
+    <span class="n">section_or_value</span> <span class="o">=</span> <span class="s">&#39;value</span>
+    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">the_value</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
+        <span class="c"># Sections are subclasses of dict</span>
+        <span class="n">section_or_value</span> <span class="o">=</span> <span class="s">&#39;section&#39;</span>
+
+    <span class="n">section_string</span> <span class="o">=</span> <span class="s">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sections</span><span class="p">)</span> <span class="ow">or</span> <span class="s">&quot;top level&quot;</span>
+    <span class="k">print</span> <span class="s">&#39;Extra entry in section: </span><span class="si">%s</span><span class="s">. Entry </span><span class="si">%r</span><span class="s"> is a </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">section_string</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">section_or_value</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="credits">
+<h1><a class="toc-backref" href="#id87">16&nbsp;&nbsp;&nbsp;CREDITS</a></h1>
+<p>ConfigObj 4 is written by (and copyright) <a class="reference external" href="http://www.voidspace.org.uk/python/weblog/index.shtml">Michael Foord</a> and
+<a class="reference external" href="http://www.teknico.net">Nicola Larosa</a>.</p>
+<p>Particularly thanks to Nicola Larosa for help on the config file spec, the
+validation system and the doctests.</p>
+<p><em>validate.py</em> was originally written by Michael Foord and Mark Andrews.</p>
+<p>Thanks to many others for input, patches and bugfixes.</p>
+</div>
+<div class="section" id="license">
+<h1><a class="toc-backref" href="#id88">17&nbsp;&nbsp;&nbsp;LICENSE</a></h1>
+<p>ConfigObj, and related files, are licensed under the BSD license. This is a
+very unrestrictive license, but it comes with the usual disclaimer. This is
+free software: test it, break it, just don't blame us if it eats your data !
+Of course if it does, let us know and we'll fix the problem so it doesn't
+happen to anyone else:</p>
+<pre class="literal-block">
+Copyright (c) 2004 - 2010, Michael Foord &amp; Nicola Larosa
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Michael Foord nor Nicola Larosa
+      may be used to endorse or promote products derived from this
+      software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+&quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+<p>You should also be able to find a copy of this license at : <a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></p>
+</div>
+<div class="section" id="todo">
+<h1><a class="toc-backref" href="#id89">18&nbsp;&nbsp;&nbsp;TODO</a></h1>
+<p>Better support for configuration from multiple files, including tracking
+<em>where</em> the original file came from and writing changes to the correct
+file.</p>
+<p>Make <tt class="docutils literal">newline</tt> a keyword argument (as well as an attribute) ?</p>
+<p><tt class="docutils literal">UTF16</tt> encoded files, when returned as a list of lines, will have the
+BOM at the start of every line. Should this be removed from all but the
+first line ?</p>
+<p>Option to set warning type for unicode decode ? (Defaults to strict).</p>
+<p>A method to optionally remove uniform indentation from multiline values.
+(do as an example of using <tt class="docutils literal">walk</tt> - along with string-escape)</p>
+<p>Should the results dictionary from validate be an ordered dictionary if
+<a class="reference external" href="http://www.voidspace.org.uk/python/odict.html">odict</a> is available ?</p>
+<p>Implement some of the sequence methods (which include slicing) from the
+newer <tt class="docutils literal">odict</tt> ?</p>
+<p>Preserve line numbers of values (and possibly the original text of each value).</p>
+</div>
+<div class="section" id="issues">
+<h1><a class="toc-backref" href="#id90">19&nbsp;&nbsp;&nbsp;ISSUES</a></h1>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Please file any bug reports to <a class="reference external" href="http://www.voidspace.org.uk/python/weblog/index.shtml">Michael Foord</a> or the <strong>ConfigObj</strong>
+<a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
+</div>
+<p>There is currently no way to specify the encoding of a configspec file.</p>
+<p>As a consequence of the changes to configspec handling in version 4.6.0, when
+you create a ConfigObj instance and provide a configspec, the configspec
+attribute is only set on the ConfigObj instance - it isn't set on the sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't documented but did work previously.</p>
+<p>In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments in configspecs. This will only affect you if you are using <tt class="docutils literal">copy=True</tt> when validating and expecting inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be copied as usual).</p>
+<p>If you <em>create</em> the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or list of lines) then you should pass in <tt class="docutils literal">_inspec=True</tt> to the constructor to allow hashes in values. This is the magic that switches off inline comment parsing.</p>
+<p>When using <tt class="docutils literal">copy</tt> mode for validation, it won't copy <tt class="docutils literal">DEFAULT</tt>
+sections. This is so that you <em>can</em> use interpolation in configspec
+files. This is probably true even if interpolation is off in the
+configspec.</p>
+<p>You can't have a keyword with the same name as a section (in the same
+section). They are both dictionary keys - so they would overlap.</p>
+<p>ConfigObj doesn't quote and unquote values if <tt class="docutils literal">list_values=False</tt>.
+This means that leading or trailing whitespace in values will be lost when
+writing. (Unless you manually quote).</p>
+<p>Interpolation checks first the current section, then the 'DEFAULT' subsection
+of the current section, before moving on to the current section's parent and
+so on up the tree.</p>
+<p>Does it matter that we don't support the ':' divider, which is supported
+by <tt class="docutils literal">ConfigParser</tt> ?</p>
+<p>String interpolation and validation don't play well together. When
+validation changes type it sets the value. This will correctly fetch the
+value using interpolation - but then overwrite the interpolation reference.
+If the value is unchanged by validation (it's a string) - but other types
+will be.</p>
+</div>
+<div class="section" id="changelog">
+<h1><a class="toc-backref" href="#id91">20&nbsp;&nbsp;&nbsp;CHANGELOG</a></h1>
+<p>This is an abbreviated changelog showing the major releases up to version 4.
+From version 4 it lists all releases and changes.</p>
+<div class="section" id="version-4-7-2">
+<h2><a class="toc-backref" href="#id92">20.1&nbsp;&nbsp;&nbsp;2010/02/27 - Version 4.7.2</a></h2>
+<ul class="simple">
+<li>BUGFIX: Restore Python 2.3 compatibility</li>
+<li>BUGFIX: Members that were lists were being returned as copies due to interpolation
+introduced in 4.7. Lists are now only copies if interpolation changes a list
+member.</li>
+<li>BUGFIX: <tt class="docutils literal">pop</tt> now does interpolation in list values as well.</li>
+<li>BUGFIX: where interpolation matches a section name rather than a value it is
+ignored instead of raising an exception on fetching the item.</li>
+<li>BUGFIX: values that use interpolation to reference members that don't exist can
+now be repr'd.</li>
+<li>BUGFIX: Fix to avoid writing '\r\r\n' on Windows when given a file opened in
+text write mode ('w').</li>
+</ul>
+<p>See <a class="reference internal" href="#string-interpolation-and-list-values">String Interpolation and List Values</a> for information about the problem with lists and interpolation.</p>
+</div>
+<div class="section" id="version-4-7-1">
+<h2><a class="toc-backref" href="#id93">20.2&nbsp;&nbsp;&nbsp;2010/02/06 - Version 4.7.1</a></h2>
+<ul class="simple">
+<li>Fix bug in options deprecation warning added in 4.7.0</li>
+</ul>
+</div>
+<div class="section" id="version-4-7-0">
+<h2><a class="toc-backref" href="#id94">20.3&nbsp;&nbsp;&nbsp;2010/01/09 - Version 4.7.0</a></h2>
+<ul class="simple">
+<li>Minimum supported version of Python is now 2.3</li>
+<li>~25% performance improvement thanks to Christian Heimes</li>
+<li>String interpolation now works in list value members</li>
+<li>After validation any additional entries not in the configspec are listed in
+the <tt class="docutils literal">extra_values</tt> section member</li>
+<li>Addition of the <tt class="docutils literal">get_extra_values</tt> function for finding all extra values
+in a validated ConfigObj instance</li>
+<li>Deprecated the use of the <tt class="docutils literal">options</tt> dictionary in the ConfigObj constructor
+and added explicit keyword arguments instead. Use **options if you want
+to initialise a ConfigObj instance from a dictionary</li>
+<li>Constructing a ConfigObj from an existing ConfigObj instance now preserves
+the order of values and sections from the original instance in the new one</li>
+<li>BUGFIX: Checks that failed validation would not populate <tt class="docutils literal">default_values</tt> and
+<tt class="docutils literal">restore_default_value()</tt> wouldn't work for those entries</li>
+<li>BUGFIX: clear() now clears 'defaults'</li>
+<li>BUGFIX: empty values in list values were accidentally valid syntax. They now
+raise a <tt class="docutils literal">ParseError</tt>. e.g. &quot;value = 1, , 2&quot;</li>
+<li>BUGFIX: Change to the result of a call to <tt class="docutils literal">validate</tt> when <tt class="docutils literal">preserve_errors</tt>
+is True. Previously sections where <em>all</em> values failed validation would
+return False for the section rather than preserving the errors. False will
+now only be returned for a section if it is missing</li>
+<li>Distribution includes version 1.0.1 of validate.py</li>
+<li>Removed __revision__ and __docformat__</li>
+</ul>
+</div>
+<div class="section" id="version-4-6-0">
+<h2><a class="toc-backref" href="#id95">20.4&nbsp;&nbsp;&nbsp;2009/04/13 - Version 4.6.0</a></h2>
+<ul class="simple">
+<li>Pickling of ConfigObj instances now supported (thanks to Christian Heimes)</li>
+<li>Hashes in confgspecs are now allowed (see note below)</li>
+<li>Replaced use of hasattr (which can swallow exceptions) with getattr</li>
+<li>__many__ in configspecs can refer to scalars (ordinary values) as well as sections</li>
+<li>You can use ___many___ (three underscores!) where you want to use __many__ as well</li>
+<li>You can now have normal sections inside configspec sections that use __many__</li>
+<li>You can now create an empty ConfigObj with a configspec, programmatically set values and then validate</li>
+<li>A section that was supplied as a value (or vice-versa) in the actual config file would cause an exception during validation (the config file is still broken of course, but it is now handled gracefully)</li>
+<li>Added <tt class="docutils literal">as_list</tt> method</li>
+<li>Removed the deprecated <tt class="docutils literal">istrue</tt>, <tt class="docutils literal">encode</tt> and <tt class="docutils literal">decode</tt> methods</li>
+<li>Running test_configobj.py now also runs the doctests in the configobj module</li>
+</ul>
+<p>As a consequence of the changes to configspec handling, when you create a ConfigObj instance and provide
+a configspec, the configspec attribute is only set on the ConfigObj instance - it isn't set on the
+sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't
+documented but did work previously.</p>
+<p>In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments
+in configspecs. This will only affect you if you are using <tt class="docutils literal">copy=True</tt> when validating and expecting
+inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be
+copied as usual).</p>
+<p>If you <em>create</em> the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or
+list of lines) then you should pass in <tt class="docutils literal">_inspec=True</tt> to the constructor to allow hashes in values.
+This is the magic that switches off inline comment parsing.</p>
+</div>
+<div class="section" id="version-4-5-3">
+<h2><a class="toc-backref" href="#id96">20.5&nbsp;&nbsp;&nbsp;2008/06/27 - Version 4.5.3</a></h2>
+<p>BUGFIX: fixed a problem with <tt class="docutils literal">copy=True</tt> when validating with configspecs that use
+<tt class="docutils literal">__many__</tt> sections.</p>
+</div>
+<div class="section" id="version-4-5-2">
+<h2><a class="toc-backref" href="#id97">20.6&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.2</a></h2>
+<p>Distribution updated to include version 0.3.2 of <a class="reference internal" href="#validate">validate</a>. This means that
+<tt class="docutils literal">None</tt> as a default value in configspecs works.</p>
+</div>
+<div class="section" id="version-4-5-1">
+<h2><a class="toc-backref" href="#id98">20.7&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.1</a></h2>
+<p>Distribution updated to include version 0.3.1 of <a class="reference internal" href="#validate">validate</a>. This means that
+Unicode configspecs now work.</p>
+</div>
+<div class="section" id="version-4-5-0">
+<h2><a class="toc-backref" href="#id99">20.8&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.0</a></h2>
+<p>ConfigObj will now guarantee that files will be written terminated with a
+newline.</p>
+<p>ConfigObj will no longer attempt to import the <tt class="docutils literal">validate</tt> module, until/unless
+you call <tt class="docutils literal">ConfigObj.validate</tt> with <tt class="docutils literal">preserve_errors=True</tt>. This makes it
+faster to import.</p>
+<p>New methods <tt class="docutils literal">restore_default</tt> and <tt class="docutils literal">restore_defaults</tt>. <tt class="docutils literal">restore_default</tt>
+resets an entry to its default value (and returns that value). <tt class="docutils literal">restore_defaults</tt>
+resets all entries to their default value. It doesn't modify entries without a
+default value. You must have validated a ConfigObj (which populates the
+<tt class="docutils literal">default_values</tt> dictionary) before calling these methods.</p>
+<p>BUGFIX: Proper quoting of keys, values and list values that contain hashes
+(when writing).  When <tt class="docutils literal">list_values=False</tt>, values containing hashes are
+triple quoted.</p>
+<p>Added the <tt class="docutils literal">reload</tt> method. This reloads a ConfigObj from file. If the filename
+attribute is not set then a <tt class="docutils literal">ReloadError</tt> (a new exception inheriting from
+<tt class="docutils literal">IOError</tt>) is raised.</p>
+<p>BUGFIX: Files are read in with 'rb' mode, so that native/non-native line endings work!</p>
+<p>Minor efficiency improvement in <tt class="docutils literal">unrepr</tt> mode.</p>
+<p>Added missing docstrings for some overidden dictionary methods.</p>
+<p>Added the <tt class="docutils literal">reset</tt> method. This restores a ConfigObj to a freshly created state.</p>
+<p>Removed old CHANGELOG file.</p>
+</div>
+<div class="section" id="version-4-4-0">
+<h2><a class="toc-backref" href="#id100">20.9&nbsp;&nbsp;&nbsp;2007/02/04 - Version 4.4.0</a></h2>
+<p>Official release of 4.4.0</p>
+</div>
+<div class="section" id="version-4-3-3-alpha4">
+<h2><a class="toc-backref" href="#id101">20.10&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha4</a></h2>
+<p>By Nicola Larosa</p>
+<p>Allowed arbitrary indentation in the <tt class="docutils literal">indent_type</tt> parameter, removed the
+<tt class="docutils literal">NUM_INDENT_SPACES</tt> and <tt class="docutils literal">MAX_INTERPOL_DEPTH</tt> (a leftover) constants,
+added indentation tests (including another docutils workaround, sigh), updated
+the documentation.</p>
+<p>By Michael Foord</p>
+<p>Made the import of <tt class="docutils literal">compiler</tt> conditional so that <tt class="docutils literal">ConfigObj</tt> can be used
+with <a class="reference external" href="http://www.codeplex.com/IronPython">IronPython</a>.</p>
+</div>
+<div class="section" id="version-4-3-3-alpha3">
+<h2><a class="toc-backref" href="#id102">20.11&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha3</a></h2>
+<p>By Nicola Larosa</p>
+<p>Added a missing <tt class="docutils literal">self.</tt> in the _handle_comment method and a related test,
+per Sourceforge bug #1523975.</p>
+</div>
+<div class="section" id="version-4-3-3-alpha2">
+<h2><a class="toc-backref" href="#id103">20.12&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha2</a></h2>
+<p>By Nicola Larosa</p>
+<p>Changed interpolation search strategy, based on this patch by Robin Munn:
+<a class="reference external" href="http://sourceforge.net/mailarchive/message.php?msg_id=17125993">http://sourceforge.net/mailarchive/message.php?msg_id=17125993</a></p>
+</div>
+<div class="section" id="version-4-3-3-alpha1">
+<h2><a class="toc-backref" href="#id104">20.13&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha1</a></h2>
+<p>By Nicola Larosa</p>
+<p>Added Template-style interpolation, with tests, based on this patch by
+Robin Munn: <a class="reference external" href="http://sourceforge.net/mailarchive/message.php?msg_id=17125991">http://sourceforge.net/mailarchive/message.php?msg_id=17125991</a>
+(awful archives, bad Sourceforge, bad).</p>
+</div>
+<div class="section" id="version-4-3-2">
+<h2><a class="toc-backref" href="#id105">20.14&nbsp;&nbsp;&nbsp;2006/06/04 - Version 4.3.2</a></h2>
+<p>Changed error handling, if parsing finds a single error then that error will
+be re-raised. That error will still have an <tt class="docutils literal">errors</tt> and a <tt class="docutils literal">config</tt>
+attribute.</p>
+<p>Fixed bug where '\n' terminated files could be truncated.</p>
+<p>Bugfix in <tt class="docutils literal">unrepr</tt> mode, it couldn't handle '#' in values. (Thanks to
+Philippe Normand for the report.)</p>
+<p>As a consequence of this fix, ConfigObj doesn't now keep inline comments in
+<tt class="docutils literal">unrepr</tt> mode. This is because the parser in the <a class="reference external" href="http://docs.python.org/lib/compiler.html">compiler package</a>
+doesn't keep comments.</p>
+<p>Error messages are now more useful. They tell you the number of parsing errors
+and the line number of the first error. (In the case of multiple errors.)</p>
+<p>Line numbers in exceptions now start at 1, not 0.</p>
+<p>Errors in <tt class="docutils literal">unrepr</tt> mode are now handled the same way as in the normal mode.
+The errors stored will be an <tt class="docutils literal">UnreprError</tt>.</p>
+</div>
+<div class="section" id="version-4-3-1">
+<h2><a class="toc-backref" href="#id106">20.15&nbsp;&nbsp;&nbsp;2006/04/29 - Version 4.3.1</a></h2>
+<p>Added <tt class="docutils literal">validate.py</tt> back into <tt class="docutils literal">configobj.zip</tt>. (Thanks to Stewart
+Midwinter)</p>
+<p>Updated to <a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a> 0.2.2.</p>
+<p>Preserve tuples when calling the <tt class="docutils literal">dict</tt> method. (Thanks to Gustavo Niemeyer.)</p>
+<p>Changed <tt class="docutils literal">__repr__</tt> to return a string that contains <tt class="docutils literal">ConfigObj({ ... })</tt>.</p>
+<p>Change so that an options dictionary isn't modified by passing it to ConfigObj.
+(Thanks to Artarious.)</p>
+<p>Added ability to handle negative integers in <tt class="docutils literal">unrepr</tt>. (Thanks to Kevin
+Dangoor.)</p>
+</div>
+<div class="section" id="version-4-3-0">
+<h2><a class="toc-backref" href="#id107">20.16&nbsp;&nbsp;&nbsp;2006/03/24 - Version 4.3.0</a></h2>
+<p>Moved the tests and the CHANGELOG (etc) into a separate file. This has reduced
+the size of <tt class="docutils literal">configobj.py</tt> by about 40%.</p>
+<p>Added the <tt class="docutils literal">unrepr</tt> mode to reading and writing config files. Thanks to Kevin
+Dangoor for this suggestion.</p>
+<p>Empty values are now valid syntax. They are read as an empty string <tt class="docutils literal">''</tt>.
+(<tt class="docutils literal">key =</tt>, or <tt class="docutils literal">key = # comment</tt>.)</p>
+<p><tt class="docutils literal">validate</tt> now honours the order of the configspec.</p>
+<p>Added the <tt class="docutils literal">copy</tt> mode to validate. Thanks to Louis Cordier for this
+suggestion.</p>
+<p>Fixed bug where files written on windows could be given <tt class="docutils literal">'\r\r\n'</tt> line
+terminators.</p>
+<p>Fixed bug where last occurring comment line could be interpreted as the
+final comment if the last line isn't terminated.</p>
+<p>Fixed bug where nested list values would be flattened when <tt class="docutils literal">write</tt> is
+called. Now sub-lists have a string representation written instead.</p>
+<p>Deprecated <tt class="docutils literal">encode</tt> and <tt class="docutils literal">decode</tt> methods instead.</p>
+<p>You can now pass in a ConfigObj instance as a configspec (remember to read
+the configspec file using <tt class="docutils literal">list_values=False</tt>).</p>
+<p>Sorted footnotes in the docs.</p>
+</div>
+<div class="section" id="version-4-2-0">
+<h2><a class="toc-backref" href="#id108">20.17&nbsp;&nbsp;&nbsp;2006/02/16 - Version 4.2.0</a></h2>
+<p>Removed <tt class="docutils literal">BOM_UTF8</tt> from <tt class="docutils literal">__all__</tt>.</p>
+<p>The <tt class="docutils literal">BOM</tt> attribute has become a boolean. (Defaults to <tt class="docutils literal">False</tt>.) It is
+<em>only</em> <tt class="docutils literal">True</tt> for the <tt class="docutils literal">UTF16/UTF8</tt> encodings.</p>
+<p>File like objects no longer need a <tt class="docutils literal">seek</tt> attribute.</p>
+<p>Full unicode support added. New options/attributes <tt class="docutils literal">encoding</tt>,
+<tt class="docutils literal">default_encoding</tt>.</p>
+<p>ConfigObj no longer keeps a reference to file like objects. Instead the
+<tt class="docutils literal">write</tt> method takes a file like object as an optional argument. (Which
+will be used in preference of the <tt class="docutils literal">filename</tt> attribute if that exists as
+well.)</p>
+<p>utf16 files decoded to unicode.</p>
+<p>If <tt class="docutils literal">BOM</tt> is <tt class="docutils literal">True</tt>, but no encoding specified, then the utf8 BOM is
+written out at the start of the file. (It will normally only be <tt class="docutils literal">True</tt> if
+the utf8 BOM was found when the file was read.)</p>
+<p>Thanks to Aaron Bentley for help and testing on the unicode issues.</p>
+<p>File paths are <em>not</em> converted to absolute paths, relative paths will
+remain relative as the <tt class="docutils literal">filename</tt> attribute.</p>
+<p>Fixed bug where <tt class="docutils literal">final_comment</tt> wasn't returned if <tt class="docutils literal">write</tt> is returning
+a list of lines.</p>
+<p>Deprecated <tt class="docutils literal">istrue</tt>, replaced it with <tt class="docutils literal">as_bool</tt>.</p>
+<p>Added <tt class="docutils literal">as_int</tt> and <tt class="docutils literal">as_float</tt>.</p>
+</div>
+<div class="section" id="version-4-1-0">
+<h2><a class="toc-backref" href="#id109">20.18&nbsp;&nbsp;&nbsp;2005/12/14 - Version 4.1.0</a></h2>
+<p>Added <tt class="docutils literal">merge</tt>, a recursive update.</p>
+<p>Added <tt class="docutils literal">preserve_errors</tt> to <tt class="docutils literal">validate</tt> and the <tt class="docutils literal">flatten_errors</tt>
+example function.</p>
+<p>Thanks to Matthew Brett for suggestions and helping me iron out bugs.</p>
+<p>Fixed bug where a config file is <em>all</em> comment, the comment will now be
+<tt class="docutils literal">initial_comment</tt> rather than <tt class="docutils literal">final_comment</tt>.</p>
+<p>Validation no longer done on the 'DEFAULT' section (only in the root level).
+This allows interpolation in configspecs.</p>
+<p>Also use the new list syntax in <a class="reference internal" href="#validate">validate</a> 0.2.1. (For configspecs).</p>
+</div>
+<div class="section" id="version-4-0-2">
+<h2><a class="toc-backref" href="#id110">20.19&nbsp;&nbsp;&nbsp;2005/12/02 - Version 4.0.2</a></h2>
+<p>Fixed bug in <tt class="docutils literal">create_empty</tt>. Thanks to Paul Jimenez for the report.</p>
+</div>
+<div class="section" id="version-4-0-1">
+<h2><a class="toc-backref" href="#id111">20.20&nbsp;&nbsp;&nbsp;2005/11/05 - Version 4.0.1</a></h2>
+<p>Fixed bug in <tt class="docutils literal">Section.walk</tt> when transforming names as well as values.</p>
+<p>Added the <tt class="docutils literal">istrue</tt> method. (Fetches the boolean equivalent of a string
+value).</p>
+<p>Fixed <tt class="docutils literal">list_values=False</tt> - they are now only quoted/unquoted if they
+are multiline values.</p>
+<p>List values are written as <tt class="docutils literal">item, item</tt> rather than <tt class="docutils literal">item,item</tt>.</p>
+</div>
+<div class="section" id="version-4-0-0">
+<h2><a class="toc-backref" href="#id112">20.21&nbsp;&nbsp;&nbsp;2005/10/17 - Version 4.0.0</a></h2>
+<p><strong>ConfigObj 4.0.0 Final</strong></p>
+<p>Fixed bug in <tt class="docutils literal">setdefault</tt>. When creating a new section with setdefault the
+reference returned would be to the dictionary passed in <em>not</em> to the new
+section. Bug fixed and behaviour documented.</p>
+<p>Obscure typo/bug fixed in <tt class="docutils literal">write</tt>. Wouldn't have affected anyone though.</p>
+</div>
+<div class="section" id="version-4-0-0-beta-5">
+<h2><a class="toc-backref" href="#id113">20.22&nbsp;&nbsp;&nbsp;2005/09/09 - Version 4.0.0 beta 5</a></h2>
+<p>Removed <tt class="docutils literal">PositionError</tt>.</p>
+<p>Allowed quotes around keys as documented.</p>
+<p>Fixed bug with commas in comments. (matched as a list value)</p>
+</div>
+<div class="section" id="version-4-0-0-beta-4">
+<h2><a class="toc-backref" href="#id114">20.23&nbsp;&nbsp;&nbsp;2005/09/07 - Version 4.0.0 beta 4</a></h2>
+<p>Fixed bug in <tt class="docutils literal">__delitem__</tt>. Deleting an item no longer deletes the
+<tt class="docutils literal">inline_comments</tt> attribute.</p>
+<p>Fixed bug in initialising ConfigObj from a ConfigObj.</p>
+<p>Changed the mailing list address.</p>
+</div>
+<div class="section" id="version-4-0-0-beta-3">
+<h2><a class="toc-backref" href="#id115">20.24&nbsp;&nbsp;&nbsp;2005/08/28 - Version 4.0.0 beta 3</a></h2>
+<p>Interpolation is switched off before writing out files.</p>
+<p>Fixed bug in handling <tt class="docutils literal">StringIO</tt> instances. (Thanks to report from
+Gustavo Niemeyer.)</p>
+<p>Moved the doctests from the <tt class="docutils literal">__init__</tt> method to a separate function.
+(For the sake of IDE calltips).</p>
+</div>
+<div class="section" id="version-4-0-0-beta-2">
+<h2><a class="toc-backref" href="#id116">20.25&nbsp;&nbsp;&nbsp;2005/08/25 - Version 4.0.0 beta 2</a></h2>
+<p>Amendments to <em>validate.py</em>.</p>
+<p>First public release.</p>
+</div>
+<div class="section" id="version-4-0-0-beta-1">
+<h2><a class="toc-backref" href="#id117">20.26&nbsp;&nbsp;&nbsp;2005/08/21 - Version 4.0.0 beta 1</a></h2>
+<p>Reads nested subsections to any depth.</p>
+<p>Multiline values.</p>
+<p>Simplified options and methods.</p>
+<p>New list syntax.</p>
+<p>Faster, smaller, and better parser.</p>
+<p>Validation greatly improved. Includes:</p>
+<blockquote>
+<ul class="simple">
+<li>type conversion</li>
+<li>default values</li>
+<li>repeated sections</li>
+</ul>
+</blockquote>
+<p>Improved error handling.</p>
+<p>Plus lots of other improvements.</p>
+</div>
+<div class="section" id="version-3-0-0">
+<h2><a class="toc-backref" href="#id118">20.27&nbsp;&nbsp;&nbsp;2004/05/24 - Version 3.0.0</a></h2>
+<p>Several incompatible changes: another major overhaul and change. (Lots of
+improvements though).</p>
+<p>Added support for standard config files with sections. This has an entirely
+new interface: each section is a dictionary of values.</p>
+<p>Changed the update method to be called writein: update clashes with a dict
+method.</p>
+<p>Made various attributes keyword arguments, added several.</p>
+<p>Configspecs and orderlists have changed a great deal.</p>
+<p>Removed support for adding dictionaries: use update instead.</p>
+<p>Now subclasses a new class called caselessDict. This should add various
+dictionary methods that could have caused errors before.</p>
+<p>It also preserves the original casing of keywords when writing them back out.</p>
+<p>Comments are also saved using a <tt class="docutils literal">caselessDict</tt>.</p>
+<p>Using a non-string key will now raise a <tt class="docutils literal">TypeError</tt> rather than converting
+the key.</p>
+<p>Added an exceptions keyword for <em>much</em> better handling of errors.</p>
+<p>Made <tt class="docutils literal">creatempty=False</tt> the default.</p>
+<p>Now checks indict <em>and</em> any keyword args. Keyword args take precedence over
+indict.</p>
+<p><tt class="docutils literal">' ', <span class="pre">':',</span> <span class="pre">'=',</span> ','</tt> and <tt class="docutils literal">'\t'</tt> are now all valid dividers where the
+keyword is unquoted.</p>
+<p>ConfigObj now does no type checking against configspec when you set items.</p>
+<p>delete and add methods removed (they were unnecessary).</p>
+<p>Docs rewritten to include all this gumph and more; actually ConfigObj is
+<em>really</em> easy to use.</p>
+<p>Support for stdout was removed.</p>
+<p>A few new methods added.</p>
+<p>Charmap is now incorporated into ConfigObj.</p>
+</div>
+<div class="section" id="version-2-0-0-beta">
+<h2><a class="toc-backref" href="#id119">20.28&nbsp;&nbsp;&nbsp;2004/03/14 - Version 2.0.0 beta</a></h2>
+<p>Re-written it to subclass dict. My first forays into inheritance and operator
+overloading.</p>
+<p>The config object now behaves like a dictionary.</p>
+<p>I've completely broken the interface, but I don't think anyone was really
+using it anyway.</p>
+<p>This new version is much more 'classy'.</p>
+<p>It will also read straight from/to a filename and completely parse a config
+file without you <em>having</em> to supply a config spec.</p>
+<p>Uses listparse, so can handle nested list items as values.</p>
+<p>No longer has getval and setval methods: use normal dictionary methods, or add
+and delete.</p>
+</div>
+<div class="section" id="version-1-0-5">
+<h2><a class="toc-backref" href="#id120">20.29&nbsp;&nbsp;&nbsp;2004/01/29 - Version 1.0.5</a></h2>
+<p>Version 1.0.5 has a couple of bugfixes as well as a couple of useful additions
+over previous versions.</p>
+<p>Since 1.0.0 the buildconfig function has been moved into this distribution,
+and the methods reset, verify, getval and setval have been added.</p>
+<p>A couple of bugs have been fixed.</p>
+</div>
+<div class="section" id="origins">
+<h2><a class="toc-backref" href="#id121">20.30&nbsp;&nbsp;&nbsp;Origins</a></h2>
+<p>ConfigObj originated in a set of functions for reading config files in the
+<a class="reference external" href="http://www.voidspace.org.uk/atlantibots/">atlantibots</a> project. The original
+functions were written by Rob McNeur.</p>
+</div>
+</div>
+<hr class="docutils" />
+<div class="section" id="footnotes">
+<h1><a class="toc-backref" href="#id122">21&nbsp;&nbsp;&nbsp;Footnotes</a></h1>
+<table class="docutils footnote" frame="void" id="id15" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>And if you discover any bugs, let us know. We'll fix them quickly.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id16" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>If you specify a filename that doesn't exist, ConfigObj will assume you
+are creating a new one. See the <em>create_empty</em> and <em>file_error</em> options.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id17" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>They can be byte strings (<em>ordinary</em> strings) or Unicode.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id18" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id4">[4]</a></td><td>Except we don't support the RFC822 style line continuations, nor ':' as
+a divider.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id19" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id5">[5]</a></td><td>This is a change in ConfigObj 4.2.0. Note that ConfigObj doesn't call
+the seek method of any file like object you pass in. You may want to call
+<tt class="docutils literal">file_object.seek(0)</tt> yourself, first.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id20" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id6">[6]</a></td><td><p class="first">A side effect of this is that it enables you to copy a ConfigObj :</p>
+<div class="highlight"><pre><span class="c"># only copies members</span>
+<span class="c"># not attributes/comments</span>
+<span class="n">config2</span> <span class="o">=</span> <span class="n">ConfigObj</span><span class="p">(</span><span class="n">config1</span><span class="p">)</span>
+</pre></div>
+<p class="last">Since ConfigObj 4.7.0 the order of members and sections will be
+preserved when copying a ConfigObj instance.</p>
+</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id21" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id7">[7]</a></td><td>Other than lists of strings.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id22" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id8">[8]</a></td><td>The exception is if it detects a <tt class="docutils literal">UTF16</tt> encoded file which it
+must decode before parsing.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id23" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id9">[9]</a></td><td>The method signature shows that this method takes
+two arguments. The second is the section to be written. This is because the
+<tt class="docutils literal">write</tt> method is called recursively.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id24" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id10">[10]</a></td><td>The dict method doesn't actually use the deepcopy mechanism. This means
+if you add nested lists (etc) to your ConfigObj, then the dictionary
+returned by dict may contain some references. For all <em>normal</em> ConfigObjs
+it will return a deepcopy.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id25" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id11">[11]</a></td><td>Passing <tt class="docutils literal">(section, key)</tt> rather than <tt class="docutils literal">(value, key)</tt> allows you to
+change the value by setting <tt class="docutils literal">section[key] = newval</tt>. It also gives you
+access to the <em>rename</em> method of the section.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id26" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id12">[12]</a></td><td>Minimum required version of <em>validate.py</em> 0.2.0 .</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+</body>
+</html>

+ 2992 - 0
desktop/core/ext-py/configobj-4.7.2/docs/configobj.txt

@@ -0,0 +1,2992 @@
+==================================
+ Reading and Writing Config Files
+==================================
+----------------------------------------
+ ConfigObj 4 Introduction and Reference
+----------------------------------------
+
+:Authors: Michael Foord, Nicola Larosa
+:Version: ConfigObj 4.7.2
+:Date: 2010/02/27
+:Homepage: `ConfigObj Homepage`_
+:PyPI Entry: `ConfigObj on PyPI <http://pypi.python.org/pypi/configobj/>`_
+:Development: `Google Code Homepage`_
+:License: `BSD License`_
+:Support: `Mailing List`_
+
+.. _Mailing List: http://lists.sourceforge.net/lists/listinfo/configobj-develop
+.. _Google Code Homepage: http://code.google.com/p/configobj/
+
+.. meta::
+   :description: ConfigObj - a Python module for easy reading and writing of 
+                 config files.
+   :keywords: python, script, module, config, configuration, data, persistence,
+              developer, configparser
+
+
+.. contents:: ConfigObj Manual
+.. sectnum::
+
+.. note::
+
+    The best introduction to working with ConfigObj, including the powerful configuration validation system,
+    is the article:
+    
+    * `An Introduction to ConfigObj <http://www.voidspace.org.uk/python/articles/configobj.shtml>`_
+
+
+Introduction
+============
+
+**ConfigObj** is a simple but powerful config file reader and writer: an *ini
+file round tripper*. Its main feature is that it is very easy to use, with a
+straightforward programmer's interface and a simple syntax for config files.
+It has lots of other features though :
+    
+* Nested sections (subsections), to any level
+* List values
+* Multiple line values
+* String interpolation (substitution)
+* Integrated with a powerful validation system
+
+    - including automatic type checking/conversion
+    - repeated sections
+    - and allowing default values
+
+* When writing out config files, ConfigObj preserves all comments and the order of members and sections
+* Many useful methods and options for working with configuration files (like the 'reload' method)
+* Full Unicode support
+
+
+For support and bug reports please use the ConfigObj `Mailing List`_ or the issue tracker on the 
+`Google Code Homepage`_.
+
+
+Downloading
+===========
+
+The current version is **4.7.2**, dated 27th February 2010. ConfigObj 4 is
+stable and mature. We still expect to pick up a few bugs along the way though [#]_.
+
+You can get ConfigObj in the following ways :
+
+* configobj.py_ from Voidspace
+
+    ConfigObj has no external dependencies. This file is sufficient to access
+    all the functionality except Validation_.
+
+* configobj.zip_ from Voidspace
+
+    This also contains validate.py_  and `this document`_.
+
+* validate.py_ from Voidspace
+
+
+Installing
+----------
+
+ConfigObj has a source distribution `on PyPI <http://pypi.python.org/pypi/configobj/>`_. If you unzip
+the archive you can install it with::
+
+    setup.py install
+    
+Alternatively, you can install with easy install or pip::
+
+    easy_install configobj
+
+
+Documentation
+-------------
+
+*configobj.zip* also contains `this document`_.
+
+* You can view `this document`_ online at the `ConfigObj Homepage`_.
+
+
+Development Version
+-------------------
+
+It is sometimes possible to get the latest *development version* of ConfigObj
+from the Subversion Repository maintained on the `Google Code Homepage`_.
+
+.. _configobj.py: http://www.voidspace.org.uk/downloads/configobj.py
+.. _configobj.zip: http://www.voidspace.org.uk/downloads/configobj-4.7.2.zip
+.. _validate.py: http://www.voidspace.org.uk/downloads/validate.py
+.. _this document:
+.. _configobj homepage: http://www.voidspace.org.uk/python/configobj.html
+
+
+
+ConfigObj in the Real World
+===========================
+    
+**ConfigObj** is widely used. Projects using it include:
+
+* `Bazaar <http://bazaar-ng.org>`_.
+
+    Bazaar is a Python distributed {acro;VCS;Version Control System}.
+    ConfigObj is used to read ``bazaar.conf`` and ``branches.conf``.
+
+* `Chandler <http://chandler.osafoundation.org/>`_
+
+   A Python and `wxPython <http://www.wxpython.org>`_ 
+   Personal Information Manager, being developed by the 
+   `OSAFoundation <http://www.osafoundation.org/>`_.
+ 
+* `matplotlib <http://matplotlib.sourceforge.net/>`_
+
+    A 2D plotting library.
+
+* `IPython <http://ipython.scipy.org/moin/>`_
+
+    IPython is an enhanced interactive Python shell. IPython uses ConfigObj in a module called 'TConfig' that combines it with enthought `Traits <http://code.enthought.com/traits/>`_: `tconfig <http://ipython.scipy.org/ipython/ipython/browser/ipython/branches/saw/sandbox/tconfig>`_.
+    
+* `Elisa - the Fluendo Mediacenter <http://elisa.fluendo.com/>`_    
+    
+    Elisa is an open source cross-platform media center solution designed to be simple for people not particularly familiar with computers.
+
+
+Getting Started
+===============
+
+The outstanding feature of using ConfigObj is simplicity. Most functions can be
+performed with single line commands.
+
+
+Reading a Config File
+---------------------
+
+The normal way to read a config file, is to give ConfigObj the filename :
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    config = ConfigObj(filename)
+
+You can also pass the config file in as a list of lines, or a ``StringIO``
+instance, so it doesn't matter where your config data comes from.
+
+You can then access members of your config file as a dictionary. Subsections
+will also be dictionaries.
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    config = ConfigObj(filename)
+    #
+    value1 = config['keyword1']
+    value2 = config['keyword2']
+    #
+    section1 = config['section1']
+    value3 = section1['keyword3']
+    value4 = section1['keyword4']
+    #
+    # you could also write
+    value3 = config['section1']['keyword3']
+    value4 = config['section1']['keyword4']
+
+
+Writing a Config File
+---------------------
+
+Creating a new config file is just as easy as reading one. You can specify a
+filename when you create the ConfigObj, or do it later [#]_.
+
+If you *don't* set a filename, then the ``write`` method will return a list of
+lines instead of writing to file. See the write_ method for more details.
+
+Here we show creating an empty ConfigObj, setting a filename and some values,
+and then writing to file :
+
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    config = ConfigObj()
+    config.filename = filename
+    #
+    config['keyword1'] = value1
+    config['keyword2'] = value2
+    #
+    config['section1'] = {}
+    config['section1']['keyword3'] = value3
+    config['section1']['keyword4'] = value4
+    #
+    section2 = {
+        'keyword5': value5,
+        'keyword6': value6,
+        'sub-section': {
+            'keyword7': value7
+            }
+    }
+    config['section2'] = section2
+    #
+    config['section3'] = {}
+    config['section3']['keyword 8'] = [value8, value9, value10]
+    config['section3']['keyword 9'] = [value11, value12, value13]
+    #
+    config.write()
+
+    
+.. caution::
+
+    Keywords and section names can only be strings [#]_. Attempting to set
+    anything else will raise a ``ValueError``.
+    
+    See `String Interpolation and List Values`_ for an important note on
+    using lists in combination with `String Interpolation`_.
+
+
+Config Files
+------------
+
+The config files that ConfigObj will read and write are based on the 'INI'
+format. This means it will read and write files created for ``ConfigParser``
+[#]_.
+
+Keywords and values are separated by an ``'='``, and section markers are
+between square brackets. Keywords, values, and section names can be surrounded
+by single or double quotes. Indentation is not significant, but can be
+preserved.
+
+Subsections are indicated by repeating the square brackets in the section
+marker. You nest levels by using more brackets.
+
+You can have list values by separating items with a comma, and values spanning
+multiple lines by using triple quotes (single or double).
+
+For full details on all these see `the config file format`_. Here's an example
+to illustrate::
+
+    # This is the 'initial_comment'
+    # Which may be several lines
+    keyword1 = value1
+    'keyword 2' = 'value 2'
+
+    [ "section 1" ]
+    # This comment goes with keyword 3
+    keyword 3 = value 3
+    'keyword 4' = value4, value 5, 'value 6'
+
+        [[ sub-section ]]    # an inline comment
+        # sub-section is inside "section 1"
+        'keyword 5' = 'value 7'
+        'keyword 6' = '''A multiline value,
+    that spans more than one line :-)
+    The line breaks are included in the value.'''
+
+            [[[ sub-sub-section ]]]
+            # sub-sub-section is *in* 'sub-section'
+            # which is in 'section 1'
+            'keyword 7' = 'value 8'
+
+    [section 2]    # an inline comment
+    keyword8 = "value 9"
+    keyword9 = value10     # an inline comment
+    # The 'final_comment'
+    # Which also may be several lines
+
+
+ConfigObj specifications
+========================
+
+.. code-block:: python
+
+    config = ConfigObj(infile=None, options=None, configspec=None, encoding=None,
+                       interpolation=True, raise_errors=False, list_values=True,
+                       create_empty=False, file_error=False, stringify=True,
+                       indent_type=None, default_encoding=None, unrepr=False,
+                       write_empty_values=False, _inspec=False)
+
+Many of the keyword arguments are available as attributes after the config file has been
+parsed.
+
+.. note::
+
+    New in ConfigObj 4.7.0: Instantiating ConfigObj with
+    an ``options`` dictionary is now deprecated. To modify code that used to 
+    do this simply unpack the dictionary in the constructor call:
+    
+    .. code-block:: python
+    
+        config = ConfigObj(filename, **options)
+
+ConfigObj takes the following arguments (with the default values shown) :
+
+* infile: ``None``
+
+    You don't need to specify an infile. If you omit it, an empty ConfigObj will be
+    created. ``infile`` *can* be :
+
+    * Nothing. In which case the ``filename`` attribute of your ConfigObj will be
+      ``None``. You can set a filename at any time.
+
+    * A filename. What happens if the file doesn't already exist is determined by
+      the options ``file_error`` and ``create_empty``. The filename will be
+      preserved as the ``filename`` attribute. This can be changed at any time.
+
+    * A list of lines. Any trailing newlines will be removed from the lines. The
+      ``filename`` attribute of your ConfigObj will be ``None``.
+
+    * A ``StringIO`` instance or file object, or any object with a ``read`` method.
+      The ``filename`` attribute of your ConfigObj will be ``None`` [#]_.
+
+    * A dictionary. You can initialise a ConfigObj from a dictionary [#]_. The
+      ``filename`` attribute of your ConfigObj will be ``None``. All keys must be
+      strings. In this case, the order of values and sections is arbitrary.
+
+* 'raise_errors': ``False``
+
+    When parsing, it is possible that the config file will be badly formed. The
+    default is to parse the whole file and raise a single error at the end. You
+    can set ``raise_errors = True`` to have errors raised immediately. See the
+    exceptions_ section for more details.
+
+    Altering this value after initial parsing has no effect.
+
+* 'list_values': ``True``
+
+    If ``True`` (the default) then list values are possible. If ``False``, the
+    values are not parsed for lists.
+
+    If ``list_values = False`` then single line values are not quoted or
+    unquoted when reading and writing.
+
+    Changing this value affects whether single line values will be quoted or 
+    not when writing.
+
+* 'create_empty': ``False``
+
+    If this value is ``True`` and the file specified by ``infile`` doesn't
+    exist, ConfigObj will create an empty file. This can be a useful test that
+    the filename makes sense: an impossible filename will cause an error.
+
+    Altering this value after initial parsing has no effect.
+
+* 'file_error': ``False``
+
+    If this value is ``True`` and the file specified by ``infile`` doesn't
+    exist, ConfigObj will raise an ``IOError``.
+
+    Altering this value after initial parsing has no effect.
+
+* 'interpolation': ``True``
+
+    Whether string interpolation is switched on or not. It is on (``True``) by
+    default.
+
+    You can set this attribute to change whether string interpolation is done
+    when values are fetched. See the `String Interpolation`_ section for more details.
+    
+    New in ConfigObj 4.7.0: Interpolation will also be done in list values.
+
+* 'configspec': ``None``
+
+    If you want to use the validation system, you supply a configspec. This is
+    effectively a type of config file that specifies a check for each member.
+    This check can be used to do type conversion as well as check that the
+    value is within your required parameters.
+
+    You provide a configspec in the same way as you do the initial file: a
+    filename, or list of lines, etc. See the validation_ section for full
+    details on how to use the system.
+
+    When parsed, every section has a ``configspec`` with a dictionary of
+    configspec checks for *that section*.
+
+* 'stringify': ``True``
+
+    If you use the validation scheme, it can do type checking *and* conversion
+    for you. This means you may want to set members to integers, or other
+    non-string values.
+
+    If 'stringify' is set to ``True`` (default) then non-string values will
+    be converted to strings when you write the config file. The validation_
+    process converts values from strings to the required type.
+
+    If 'stringify' is set to ``False``, attempting to set a member to a
+    non-string value [#]_ will raise a ``TypeError`` (no type conversion is
+    done by validation).
+
+* 'indent_type': ``'    '``
+
+    Indentation is not significant; it can however be present in the input and
+    output config. Any combination of tabs and spaces may be used: the string
+    will be repeated for each level of indentation. Typical values are: ``''``
+    (no indentation), ``'    '`` (indentation with four spaces, the default),
+    ``'\t'`` (indentation with one tab).
+
+    If this option is not specified, and the ConfigObj is initialised with a
+    dictionary, the indentation used in the output is the default one, that is,
+    four spaces.
+
+    If this option is not specified, and the ConfigObj is initialised with a
+    list of lines or a file, the indentation used in the first indented line is
+    selected and used in all output lines. If no input line is indented, no
+    output line will be either.
+
+    If this option *is* specified, the option value is used in the output
+    config, overriding the type of indentation in the input config (if any).
+
+* 'encoding': ``None``
+
+    By default **ConfigObj** does not decode the file/strings you pass it into
+    Unicode [#]_. If you want your config file as Unicode (keys and members)
+    you need to provide an encoding to decode the file with. This encoding will
+    also be used to encode the config file when writing.
+    
+    You can change the encoding attribute at any time.
+    
+    Any characters in your strings that can't be encoded with the specified
+    encoding will raise a ``UnicodeEncodeError``.
+    
+    .. note::
+    
+        ``UTF16`` encoded files will automatically be detected and decoded,
+        even if ``encoding`` is ``None``.
+        
+        This is because it is a 16-bit encoding, and ConfigObj will mangle it
+        (split characters on byte boundaries) if it parses it without decoding.
+
+* 'default_encoding': ``None``
+
+    When using the ``write`` method, **ConfigObj** uses the ``encoding``
+    attribute to encode the Unicode strings. If any members (or keys) have
+    been set as byte strings instead of Unicode, these must first be decoded
+    to Unicode before outputting in the specified encoding.
+
+    ``default_encoding``, if specified, is the encoding used to decode byte
+    strings in the **ConfigObj** before writing. If this is ``None``, then
+    the Python default encoding (``sys.defaultencoding`` - usually ASCII) is
+    used.
+    
+    For most Western European users, a value of ``latin-1`` is sensible.
+    
+    ``default_encoding`` is *only* used if an ``encoding`` is specified.
+    
+    Any characters in byte-strings that can't be decoded using the
+    ``default_encoding`` will raise a ``UnicodeDecodeError``.
+
+* 'unrepr': ``False``
+
+    The ``unrepr`` option reads and writes files in a different mode. This
+    allows you to store and retrieve the basic Python data-types using config
+    files.
+    
+    This uses Python syntax for lists and quoting. See `unrepr mode`_ for the
+    full details.
+
+* 'write_empty_values': ``False`` 
+
+    If ``write_empty_values`` is ``True``, empty strings are written as
+    empty values. See `Empty Values`_ for more details.
+
+* '_inspec': ``False``
+
+    Used internally by ConfigObj when parsing configspec files. If you are
+    creating a ConfigObj instance from a configspec file you must pass True
+    for this argument as well as ``list_values=False``.
+
+
+Methods
+-------
+
+The ConfigObj is a subclass of an object called ``Section``, which is itself a
+subclass of ``dict``, the builtin dictionary type. This means it also has
+**all** the normal dictionary methods.
+
+In addition, the following `Section Methods`_ may be useful :
+
+* 'restore_default'
+* 'restore_defaults'
+* 'walk'
+* 'merge'
+* 'dict'
+* 'as_bool'
+* 'as_float'
+* 'as_int'
+* 'as_list'
+
+Read about Sections_ for details of all the methods.
+
+.. hint::
+
+    The *merge* method of sections is a recursive update.
+    
+    You can use this to merge sections, or even whole ConfigObjs, into each
+    other.
+    
+    You would typically use this to create a default ConfigObj and then merge
+    in user settings. This way users only need to specify values that are
+    different from the default. You can use configspecs and validation to
+    achieve the same thing of course.
+    
+
+The public methods available on ConfigObj are :
+
+* 'write'
+* 'validate'
+* 'reset'
+* 'reload'
+
+
+write
+~~~~~
+
+.. code-block:: python
+
+    write(file_object=None)
+
+This method writes the current ConfigObj and takes a single, optional argument
+[#]_.
+
+If you pass in a file like object to the ``write`` method, the config file will
+be written to this. (The only method of this object that is used is its
+``write`` method, so a ``StringIO`` instance, or any other file like object
+will work.)
+
+Otherwise, the behaviour of this method depends on the ``filename`` attribute
+of the ConfigObj.
+
+``filename``
+    ConfigObj will write the configuration to the file specified.
+
+``None``
+    ``write`` returns a list of lines. (Not ``'\n'`` terminated)
+
+First the 'initial_comment' is written, then the config file, followed by the
+'final_comment'. Comment lines and inline comments are written with each
+key/value.
+
+
+validate
+~~~~~~~~
+
+
+.. code-block:: python
+
+    validate(validator, preserve_errors=False, copy=False)
+
+.. code-block:: python
+
+    # filename is the config file
+    # filename2 is the configspec
+    # (which could also be hardcoded into your program)
+    config = ConfigObj(filename, configspec=filename2)
+    #
+    from validate import Validator
+    val = Validator()
+    test = config.validate(val)
+    if test == True:
+        print 'Succeeded.'
+
+The validate method uses the `validate 
+<http://www.voidspace.org.uk/python/validate.html>`__ module to do the
+validation.
+    
+This method validates the ConfigObj against the configspec. By doing type
+conversion as well it can abstract away the config file altogether and present
+the config *data* to your application (in the types it expects it to be).
+
+If the ``configspec`` attribute of the ConfigObj is ``None``, it raises a
+``ValueError``.
+
+If the stringify_ attribute is set, this process will convert values to the
+type defined in the configspec.
+
+The validate method uses checks specified in the configspec and defined in the
+``Validator`` object. It is very easy to extend.
+
+The configspec looks like the config file, but instead of the value, you
+specify the check (and any default value). See the validation_ section for
+details.
+
+.. hint::
+
+    The system of configspecs can seem confusing at first, but is actually
+    quite simple and powerful. The best guide to them is this article on
+    ConfigObj:
+    
+    * `An Introduction to ConfigObj`_
+
+The ``copy`` parameter fills in missing values from the configspec (default
+values), *without* marking the values as defaults. It also causes comments to
+be copied from the configspec into the config file. This allows you to use a
+configspec to create default config files. (Normally default values aren't
+written out by the ``write`` method.)
+
+As of ConfigObj 4.3.0 you can also pass in a ConfigObj instance as your
+configspec. This is especially useful if you need to specify the encoding of
+your configspec file. When you read your configspec file, you *must* specify
+``list_values=False``. If you need to support hashes inside the configspec
+values then you must also pass in ``_inspec=True``. This is because configspec
+files actually use a different syntax to config files and inline comment support
+must be switched off to correctly read configspec files with hashes in the values.
+
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    configspec = ConfigObj(configspecfilename, encoding='UTF8',
+                           list_values=False, _inspec=True)
+    config = ConfigObj(filename, configspec=configspec)
+
+
+Return Value
+############
+
+By default, the validate method either returns ``True`` (everything passed) 
+or a dictionary of ``True`` / ``False`` representing pass/fail. The dictionary 
+follows the structure of the ConfigObj.
+
+If a whole section passes then it is replaced with the value ``True``. If a 
+whole section fails, then it is replaced with the value ``False``.
+
+If a value is missing, and there is no default in the check, then the check 
+automatically fails.
+
+The ``validate`` method takes an optional keyword argument ``preserve_errors``.
+If you set this to ``True``, instead of getting ``False`` for failed checks you
+get the actual error object from the **validate** module. This usually contains
+useful information about why the check failed.
+
+See the `flatten_errors`_ function for how to turn your results dictionary into
+a useful list of error messages.
+
+Even if ``preserve_errors`` is ``True``, missing keys or sections will still be
+represented by a ``False`` in the results dictionary.
+
+
+Mentioning Default Values
+#########################
+
+In the check in your configspec, you can specify a default to be used - by 
+using the ``default`` keyword. E.g. ::
+
+    key1 = integer(0, 30, default=15)
+    key2 = integer(default=15)
+    key3 = boolean(default=True)
+    key4 = option('Hello', 'Goodbye', 'Not Today', default='Not Today')
+
+If the configspec check supplies a default and the value is missing in the
+config, then the default will be set in your ConfigObj. (It is still passed to
+the ``Validator`` so that type conversion can be done: this means the default
+value must still pass the check.)
+
+ConfigObj keeps a record of which values come from defaults, using the
+``defaults`` attribute of sections_. Any key in this list isn't written out by
+the ``write`` method. If a key is set from outside (even to the same value)
+then it is removed from the ``defaults`` list.
+
+.. note:
+
+    Even if all the keys in a section are in the defaults list, the section
+    marker is still written out.
+
+There is additionally a special case default value of ``None``. If you set the
+default value to ``None`` and the value is missing, the value will always be
+set to ``None``. As the other checks don't return ``None`` (unless you
+implement your own that do), you can tell that this value came from a default
+value (and was missing from the config file). It allows an easy way of
+implementing optional values. Simply check (and ignore) members that are set
+to ``None``.
+
+.. note::
+
+    If stringify_ is ``False`` then ``default=None`` returns ``''`` instead of
+    ``None``. This is because setting a value to a non-string raises an error
+    if stringify is unset.
+
+The default value can be a list. See `List Values`_ for the way to do this.
+
+Writing invalid default values is a *guaranteed* way of confusing your users.
+Default values **must** pass the check.
+
+
+Mentioning Repeated Sections and Values
+#######################################
+
+In the configspec it is possible to cause *every* sub-section in a section to
+be validated using the same configspec. You do this with a section in the
+configspec  called ``__many__``. Every sub-section in that section has the
+``__many__`` configspec applied to it (without you having to explicitly name
+them in advance).
+
+Your ``__many__`` section can have nested subsections, which can also include
+``__many__`` type sections.
+
+You can also specify that all values should be validated using the same configspec,
+by having a member with the name ``__many__``. If you want to use repeated values
+along with repeated sections then you can call one of them ``___many___`` (triple
+underscores).
+
+Sections with repeated sections or values can also have specifically named sub-sections
+or values. The ``__many__`` configspec will only be used to validate entries that don't 
+have an explicit configspec.
+
+See `Repeated Sections`_ for examples.
+
+
+Mentioning SimpleVal
+####################
+
+If you just want to check if all members are present, then you can use the
+``SimpleVal`` object that comes with ConfigObj. It only fails members if they
+are missing.
+
+Write a configspec that has all the members you want to check for, but set
+every section to ``''``.
+
+.. code-block:: python
+
+    val = SimpleVal()
+    test = config.validate(val)
+    if test is True:
+        print 'Succeeded.'
+
+
+Mentioning copy Mode
+####################
+
+As discussed in `Mentioning Default Values`_, you can use a configspec to
+supply default values. These are marked in the ConfigObj instance as defaults,
+and *not* written out by the ``write`` mode. This means that your users only
+need to supply values that are different from the defaults.
+
+This can be inconvenient if you *do* want to write out the default values,
+for example to write out a default config file.
+
+If you set ``copy=True`` when you call validate, then no values are marked as
+defaults. In addition, all comments from the configspec are copied into
+your ConfigObj instance. You can then call ``write`` to create your config
+file.
+    
+There is a limitation with this. In order to allow `String Interpolation`_ to work
+within configspecs, ``DEFAULT`` sections are not processed by
+validation; even in copy mode.
+
+
+reload
+~~~~~~
+
+If a ConfigObj instance was loaded from the filesystem, then this method will reload it. It
+will also reuse any configspec you supplied at instantiation (including reloading it from
+the filesystem if you passed it in as a filename).
+
+If the ConfigObj does not have a filename attribute pointing to a file, then a ``ReloadError`` 
+will be raised.
+
+
+reset
+~~~~~
+
+This method takes no arguments and doesn't return anything. It restores a ConfigObj
+instance to a freshly created state.
+
+
+Attributes
+----------
+
+A ConfigObj has the following attributes :
+
+* indent_type
+* interpolation
+* stringify
+* BOM
+* initial_comment
+* final_comment
+* list_values
+* encoding
+* default_encoding
+* unrepr
+* write_empty_values
+* newlines
+
+.. note::
+
+    This doesn't include *comments*, *inline_comments*, *defaults*, or
+    *configspec*. These are actually attributes of Sections_.
+
+It also has the following attributes as a result of parsing. They correspond to
+options when the ConfigObj was created, but changing them has no effect.
+
+* raise_errors
+* create_empty
+* file_error
+
+
+interpolation
+~~~~~~~~~~~~~
+
+ConfigObj can perform string interpolation in a *similar* way to
+``ConfigParser``. See the `String Interpolation`_ section for full details.
+
+If ``interpolation`` is set to ``False``, then interpolation is *not* done when
+you fetch values.
+
+
+stringify
+~~~~~~~~~
+
+If this attribute is set (``True``) then the validate_ method changes the
+values in the ConfigObj. These are turned back into strings when write_ is
+called.
+
+If stringify is unset (``False``) then attempting to set a value to a non
+string (or a list of strings) will raise a ``TypeError``.
+
+
+BOM
+~~~
+
+If the initial config file *started* with the UTF8 Unicode signature (known
+slightly incorrectly as the BOM - Byte Order Mark), or the UTF16 BOM, then
+this attribute is set to ``True``. Otherwise it is ``False``.
+
+If it is set to ``True`` when ``write`` is called then, if ``encoding`` is set
+to ``None`` *or* to ``utf_8`` (and variants) a UTF BOM will be written.
+
+For UTF16 encodings, a BOM is *always* written.
+
+
+initial_comment
+~~~~~~~~~~~~~~~
+
+This is a list of lines. If the ConfigObj is created from an existing file, it
+will contain any lines of comments before the start of the members.
+
+If you create a new ConfigObj, this will be an empty list.
+
+The write method puts these lines before it starts writing out the members.
+
+
+final_comment
+~~~~~~~~~~~~~
+
+This is a list of lines. If the ConfigObj is created from an existing file, it
+will contain any lines of comments after the last member.
+
+If you create a new ConfigObj, this will be an empty list.
+
+The ``write`` method puts these lines after it finishes writing out the
+members.
+
+
+list_values
+~~~~~~~~~~~
+
+This attribute is ``True`` or ``False``. If set to ``False`` then values are
+not parsed for list values. In addition single line values are not unquoted.
+
+This allows you to do your own parsing of values. It exists primarily to
+support the reading of the configspec_ - but has other use cases.
+
+For example you could use the ``LineParser`` from the
+`listquote module <http://www.voidspace.org.uk/python/listquote.html#lineparser>`_ 
+to read values for nested lists.
+
+Single line values aren't quoted when writing - but multiline values are
+handled as normal.
+
+.. caution::
+
+    Because values aren't quoted, leading or trailing whitespace can be lost. This behaviour was changed in version 4.0.1. Prior to this, single line values might have been quoted; even with ``list_values=False``. This means that files written by earlier versions of ConfigObj *could* now be incompatible and need the quotes removing by hand.
+
+
+encoding
+~~~~~~~~
+
+This is the encoding used to encode the output, when you call ``write``. It
+must be a valid encoding `recognised by Python <http://docs.python.org/lib/standard-encodings.html>`_.
+
+If this value is ``None`` then no encoding is done when ``write`` is called.
+
+
+default_encoding
+~~~~~~~~~~~~~~~~
+
+If encoding is set, any byte-strings in your ConfigObj instance (keys or
+members) will first be decoded to Unicode using the encoding specified by the
+``default_encoding`` attribute. This ensures that the output is in the encoding
+specified.
+
+If this value is ``None`` then ``sys.defaultencoding`` is used instead.
+
+
+unrepr
+~~~~~~
+
+Another boolean value. If this is set, then ``repr(value)`` is used to write
+values. This writes values in a slightly different way to the normal ConfigObj
+file syntax.
+
+This preserves basic Python data-types when read back in. See `unrepr mode`_
+for more details.
+
+
+write_empty_values
+~~~~~~~~~~~~~~~~~~
+
+Also boolean. If set, values that are an empty string (``''``) are written as
+empty values. See `Empty Values`_ for more details.
+
+
+newlines
+~~~~~~~~
+
+When a config file is read, ConfigObj records the type of newline separators in the
+file and uses this separator when writing. It defaults to ``None``, and ConfigObj
+uses the system default (``os.sep``) if write is called without newlines having
+been set.
+
+
+The Config File Format
+======================
+
+You saw an example config file in the `Config Files`_ section. Here is a fuller
+specification of the config files used and created by ConfigObj.
+
+The basic pattern for keywords is::
+
+    # comment line
+    # comment line
+    keyword = value # inline comment
+
+Both keyword and value can optionally be surrounded in quotes. The equals sign
+is the only valid divider.
+
+Values can have comments on the lines above them, and an inline comment after
+them. This, of course, is optional. See the comments_ section for details.
+
+If a keyword or value starts or ends with whitespace, or contains a quote mark
+or comma, then it should be surrounded by quotes. Quotes are not necessary if
+whitespace is surrounded by non-whitespace.
+
+Values can also be lists. Lists are comma separated. You indicate a single
+member list by a trailing comma. An empty list is shown by a single comma::
+
+    keyword1 = value1, value2, value3
+    keyword2 = value1, # a single member list
+    keyword3 = , # an empty list
+
+Values that contain line breaks (multi-line values) can be surrounded by triple
+quotes. These can also be used if a value contains both types of quotes. List
+members cannot be surrounded by triple quotes::
+
+    keyword1 = ''' A multi line value
+    on several
+    lines'''     # with a comment
+    keyword2 = '''I won't be "afraid".'''
+    #
+    keyword3 = """ A multi line value
+    on several
+    lines"""     # with a comment
+    keyword4 = """I won't be "afraid"."""
+
+.. warning::
+
+    There is no way of safely quoting values that contain both types of triple
+    quotes.
+
+A line that starts with a '#', possibly preceded by whitespace, is a comment.
+
+New sections are indicated by a section marker line. That is the section name
+in square brackets. Whitespace around the section name is ignored. The name can
+be quoted with single or double quotes. The marker can have comments before it
+and an inline comment after it::
+
+    # The First Section
+    [ section name 1 ] # first section
+    keyword1 = value1
+
+    # The Second Section
+    [ "section name 2" ] # second section
+    keyword2 = value2
+
+Any subsections (sections that are *inside* the current section) are
+designated by repeating the square brackets before and after the section name.
+The number of square brackets represents the nesting level of the sub-section.
+Square brackets may be separated by whitespace; such whitespace, however, will
+not be present in the output config written by the ``write`` method.
+
+Indentation is not significant, but can be preserved. See the description of
+the ``indent_type`` option, in the `ConfigObj specifications`_ chapter, for the
+details.
+
+A *NestingError* will be raised if the number of the opening and the closing
+brackets in a section marker is not the same, or if a sub-section's nesting
+level is greater than the nesting level of it parent plus one.
+
+In the outer section, single values can only appear before any sub-section.
+Otherwise they will belong to the sub-section immediately before them::
+
+    # initial comment
+    keyword1 = value1
+    keyword2 = value2
+
+    [section 1]
+    keyword1 = value1
+    keyword2 = value2
+
+        [[sub-section]]
+        # this is in section 1
+        keyword1 = value1
+        keyword2 = value2
+
+            [[[nested section]]]
+            # this is in sub section
+            keyword1 = value1
+            keyword2 = value2
+
+        [[sub-section2]]
+        # this is in section 1 again
+        keyword1 = value1
+        keyword2 = value2
+
+    [[sub-section3]]
+    # this is also in section 1, indentation is misleading here
+    keyword1 = value1
+    keyword2 = value2
+
+    # final comment
+
+When parsed, the above config file produces the following data structure:
+
+
+.. code-block:: python
+
+    ConfigObj({
+        'keyword1': 'value1',
+        'keyword2': 'value2',
+        'section 1': {
+            'keyword1': 'value1',
+            'keyword2': 'value2',
+            'sub-section': {
+                'keyword1': 'value1',
+                'keyword2': 'value2',
+                'nested section': {
+                    'keyword1': 'value1',
+                    'keyword2': 'value2',
+                },
+            },
+            'sub-section2': {
+                'keyword1': 'value1',
+                'keyword2': 'value2',
+            },
+            'sub-section3': {
+                'keyword1': 'value1',
+                'keyword2': 'value2',
+            },
+        },
+    })
+
+    
+Sections are ordered: note how the structure of the resulting ConfigObj is in
+the same order as the original file.
+
+.. note::
+
+    In ConfigObj 4.3.0 *empty values* became valid syntax. They are read as the
+    empty string. There is also an option/attribute (``write_empty_values``) to
+    allow the writing of these.
+    
+    This is mainly to support 'legacy' config files, written from other
+    applications. This is documented under `Empty Values`_.
+    
+    `unrepr mode`_ introduces *another* syntax variation, used for storing
+    basic Python datatypes in config files.
+
+
+Sections
+========
+
+Every section in a ConfigObj has certain properties. The ConfigObj itself also
+has these properties, because it too is a section (sometimes called the *root
+section*).
+
+``Section`` is a subclass of the standard new-class dictionary, therefore it
+has **all** the methods of a normal dictionary. This means you can ``update``
+and ``clear`` sections.
+
+.. note::
+
+    You create a new section by assigning a member to be a dictionary.
+    
+    The new ``Section`` is created *from* the dictionary, but isn't the same
+    thing as the dictionary. (So references to the dictionary you use to create
+    the section *aren't* references to the new section).
+    
+    Note the following.
+
+    .. code-block:: python
+
+        config = ConfigObj()
+        vals = {'key1': 'value 1', 
+                'key2': 'value 2'
+               }
+        config['vals'] = vals
+        config['vals'] == vals
+        True
+        config['vals'] is vals
+        False
+     
+    If you now change ``vals``, the changes won't be reflected in ``config['vals']``.
+
+A section is ordered, following its ``scalars`` and ``sections``
+attributes documented below. This means that the following dictionary
+attributes return their results in order.
+
+* '__iter__'
+
+    More commonly known as ``for member in section:``.
+
+* '__repr__' and '__str__'
+
+    Any time you print or display the ConfigObj.
+
+* 'items'
+
+* 'iteritems'
+
+* 'iterkeys'
+
+* 'itervalues'
+
+* 'keys'
+
+* 'popitem'
+
+* 'values'
+
+
+Section Attributes
+------------------
+
+* main
+
+    A reference to the main ConfigObj.
+
+* parent
+
+    A reference to the 'parent' section, the section that this section is a
+    member of.
+
+    On the ConfigObj this attribute is a reference to itself. You can use this
+    to walk up the sections, stopping when ``section.parent is section``.
+
+* depth
+
+    The nesting level of the current section.
+
+    If you create a new ConfigObj and add sections, 1 will be added to the
+    depth level between sections.
+
+* defaults
+
+    This attribute is a list of scalars that came from default values. Values
+    that came from defaults aren't written out by the ``write`` method.
+    Setting any of these values in the section removes them from the defaults
+    list.
+
+* default_values
+
+    This attribute is a dictionary mapping keys to the default values for the
+    keys. By default it is an empty dictionary and is populated when you
+    validate the ConfigObj.
+
+* scalars, sections
+
+    These attributes are normal lists, representing the order that members,
+    single values and subsections appear in the section. The order will either
+    be the order of the original config file, *or* the order that you added
+    members.
+
+    The order of members in this lists is the order that ``write`` creates in
+    the config file. The ``scalars`` list is output before the ``sections``
+    list.
+
+    Adding or removing members also alters these lists. You can manipulate the
+    lists directly to alter the order of members.
+
+    .. warning::
+
+        If you alter the ``scalars``, ``sections``, or ``defaults`` attributes
+        so that they no longer reflect the contents of the section, you will
+        break your ConfigObj.
+
+    See also the ``rename`` method.
+
+* comments
+
+    This is a dictionary of comments associated with each member. Each entry is
+    a list of lines. These lines are written out before the member.
+
+* inline_comments
+
+    This is *another* dictionary of comments associated with each member. Each
+    entry is a string that is put inline with the member.
+
+* configspec
+
+    The configspec attribute is a dictionary mapping scalars to *checks*. A
+    check defines the expected type and possibly the allowed values for a
+    member.
+
+    The configspec has the same format as a config file, but instead of values
+    it has a specification for the value (which may include a default value).
+    The validate_ method uses it to check the config file makes sense. If a
+    configspec is passed in when the ConfigObj is created, then it is parsed
+    and broken up to become the ``configspec`` attribute of each section.
+
+    If you didn't pass in a configspec, this attribute will be ``None`` on the
+    root section (the main ConfigObj).
+
+    You can set the configspec attribute directly on a section.
+
+    See the validation_ section for full details of how to write configspecs.
+
+* extra_values
+
+    By default an empty list. After validation_ this is populated with any members
+    of the section that don't appear in the configspec (i.e. they are additional
+    values). Rather than accessing this directly it may be more convenient to get
+    all the extra values in a config file using the get_extra_values_ function.
+    
+    New in ConfigObj 4.7.0.
+    
+
+Section Methods
+---------------
+
+* **dict**
+
+    This method takes no arguments. It returns a deep copy of the section as a
+    dictionary. All subsections will also be dictionaries, and list values will
+    be copies, rather than references to the original [#]_.
+
+* **rename**
+
+    ``rename(oldkey, newkey)``
+
+    This method renames a key, without affecting its position in the sequence.
+
+* **merge**
+
+    ``merge(indict)``
+    
+    This method is a *recursive update* method. It allows you to merge two
+    config files together.
+    
+    You would typically use this to create a default ConfigObj and then merge
+    in user settings. This way users only need to specify values that are
+    different from the default.
+    
+    For example :
+    
+    .. code-block:: python
+
+        # def_cfg contains your default config settings
+        # user_cfg contains the user settings
+        cfg = ConfigObj(def_cfg)
+        usr = ConfigObj(user_cfg)
+        #
+        cfg.merge(usr)
+        
+        """
+        cfg now contains a combination of the default settings and the user
+        settings.
+        
+        The user settings will have overwritten any of the default ones.
+        """
+    
+* **walk**
+
+    This method can be used to transform values and names. See `walking a
+    section`_ for examples and explanation.
+
+* **as_bool**
+
+    ``as_bool(key)``
+    
+    Returns ``True`` if the key contains a string that represents ``True``, or
+    is the ``True`` object.
+    
+    Returns ``False`` if the key contains a string that represents ``False``, 
+    or is the ``False`` object. 
+
+    Raises a ``ValueError`` if the key contains anything else.
+    
+    Strings that represent ``True`` are (not case sensitive)::
+    
+        true, yes, on, 1
+        
+    Strings that represent ``False`` are::
+    
+        false, no, off, 0
+    
+        
+* **as_int**
+
+    ``as_int(key)``
+    
+    This returns the value contained in the specified key as an integer.
+    
+    It raises a ``ValueError`` if the conversion can't be done.
+
+    
+* **as_float**
+
+    ``as_float(key)``
+    
+    This returns the value contained in the specified key as a float.
+    
+    It raises a ``ValueError`` if the conversion can't be done.
+    
+    
+* **as_list**
+
+    ``as_list(key)``
+    
+    This returns the value contained in the specified key as a list.
+    
+    If it isn't a list it will be wrapped as a list so that you can 
+    guarantee the returned value will be a list.
+    
+
+* **restore_default**
+
+    ``restore_default(key)``
+    
+    Restore (and return) the default value for the specified key.
+    
+    This method will only work for a ConfigObj that was created
+    with a configspec and has been validated.
+    
+    If there is no default value for this key, ``KeyError`` is raised.
+
+* **restore_defaults**
+    
+    ``restore_defaults()``
+
+    Recursively restore default values to all members
+    that have them.
+    
+    This method will only work for a ConfigObj that was created
+    with a configspec and has been validated.
+    
+    It doesn't delete or modify entries without default values.
+
+
+Walking a Section
+-----------------
+
+.. note::
+
+    The walk method allows you to call a function on every member/name.
+
+.. code-block:: python
+
+    walk(function, raise_errors=True,
+         call_on_sections=False, **keywargs)
+
+
+``walk`` is a method of the ``Section`` object. This means it is also a method
+of ConfigObj.
+
+It walks through every member and calls a function on the keyword and value. It
+walks recursively through subsections.
+
+It returns a dictionary of all the computed values.
+
+If the function raises an exception, the default is to propagate the error, and
+stop. If ``raise_errors=False`` then it sets the return value for that keyword
+to ``False`` instead, and continues. This is similar to the way validation_
+works.
+
+Your function receives the arguments ``(section, key)``. The current value is
+then ``section[key]`` [#]_. Any unrecognised keyword arguments you pass to
+walk, are passed on to the function.
+
+Normally ``walk`` just recurses into subsections. If you are transforming (or
+checking) names as well as values, then you want to be able to change the names
+of sections. In this case set ``call_on_sections`` to ``True``. Now, on
+encountering a sub-section, *first* the function is called for the *whole*
+sub-section, and *then* it recurses into it's members. This means your function
+must be able to handle receiving dictionaries as well as strings and lists.
+
+If you are using the return value from ``walk`` *and* ``call_on_sections``,
+note that walk discards the return value when it calls your function.
+
+.. caution::
+
+    You can use ``walk`` to transform the names of members of a section
+    but you mustn't add or delete members.
+
+
+Examples
+--------
+
+You can use this for transforming all values in your ConfigObj. For example
+you might like the nested lists from ConfigObj 3. This was provided by the
+listquote_ module. You could switch off the parsing for list values
+(``list_values=False``) and use listquote to parse every value.
+
+Another thing you might want to do is use the Python escape codes in your
+values. You might be *used* to using ``\n`` for line feed and ``\t`` for tab.
+Obviously we'd need to decode strings that come from the config file (using the
+escape codes). Before writing out we'll need to put the escape codes back in
+encode.
+
+As an example we'll write a function to use with walk, that encodes or decodes
+values using the ``string-escape`` codec.
+
+The function has to take each value and set the new value. As a bonus we'll
+create one function that will do decode *or* encode depending on a keyword
+argument.
+
+We don't want to work with section names, we're only transforming values, so
+we can leave ``call_on_sections`` as ``False``. This means the two datatypes we
+have to handle are strings and lists, we can ignore everything else. (We'll
+treat tuples as lists as well).
+
+We're not using the return values, so it doesn't need to return anything, just
+change the values if appropriate.
+
+
+.. code-block:: python
+
+    def string_escape(section, key, encode=False):
+        """
+        A function to encode or decode using the 'string-escape' codec.
+        To be passed to the walk method of a ConfigObj.
+        By default it decodes.
+        To encode, pass in the keyword argument ``encode=True``.
+        """
+        val = section[key]
+        # is it a type we can work with
+        # NOTE: for platforms where Python > 2.2
+        # you can use basestring instead of (str, unicode)
+        if not isinstance(val, (str, unicode, list, tuple)):
+            # no !
+            return
+        elif isinstance(val, (str, unicode)):
+            # it's a string !
+            if not encode:
+                section[key] = val.decode('string-escape')
+            else:
+                section[key] = val.encode('string-escape')
+        else:
+            # it must be a list or tuple!
+            # we'll be lazy and create a new list
+            newval = []
+            # we'll check every member of the list
+            for entry in val:
+                if isinstance(entry, (str, unicode)):
+                    if not encode:
+                        newval.append(entry.decode('string-escape'))
+                    else:
+                       newval.append(entry.encode('string-escape'))
+                else:
+                    newval.append(entry)
+            # done !
+            section[key] =  newval
+
+    # assume we have a ConfigObj called ``config``
+    #
+    # To decode
+    config.walk(string_escape)
+    #
+    # To encode.
+    # Because ``walk`` doesn't recognise the ``encode`` argument
+    # it passes it to our function.
+    config.walk(string_escape, encode=True)
+
+
+Here's a simple example of using ``walk`` to transform names and values. One
+usecase of this would be to create a *standard* config file with placeholders
+for section and keynames. You can then use walk to create new config files
+and change values and member names :
+
+.. code-block:: python
+
+    # We use 'XXXX' as a placeholder
+    config = '''
+    XXXXkey1 = XXXXvalue1
+    XXXXkey2 = XXXXvalue2
+    XXXXkey3 = XXXXvalue3
+    [XXXXsection1]
+    XXXXkey1 = XXXXvalue1
+    XXXXkey2 = XXXXvalue2
+    XXXXkey3 = XXXXvalue3
+    [XXXXsection2]
+    XXXXkey1 = XXXXvalue1
+    XXXXkey2 = XXXXvalue2
+    XXXXkey3 = XXXXvalue3
+        [[XXXXsection1]]
+        XXXXkey1 = XXXXvalue1
+        XXXXkey2 = XXXXvalue2
+        XXXXkey3 = XXXXvalue3
+    '''.splitlines()
+    cfg = ConfigObj(config)
+    #
+    def transform(section, key):
+        val = section[key]
+        newkey = key.replace('XXXX', 'CLIENT1')
+        section.rename(key, newkey)
+        if isinstance(val, (tuple, list, dict)):
+            pass
+        else:
+            val = val.replace('XXXX', 'CLIENT1')
+            section[newkey] = val
+    #
+    cfg.walk(transform, call_on_sections=True)
+    print cfg
+    ConfigObj({'CLIENT1key1': 'CLIENT1value1', 'CLIENT1key2': 'CLIENT1value2', 
+    'CLIENT1key3': 'CLIENT1value3', 
+    'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1', 
+        'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}, 
+    'CLIENT1section2': {'CLIENT1key1': 'CLIENT1value1', 
+        'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3', 
+        'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1', 
+            'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}}})
+
+
+Exceptions
+==========
+
+There are several places where ConfigObj may raise exceptions (other than
+because of bugs).
+
+1) If a configspec filename you pass in doesn't exist, or a config file
+    filename doesn't exist *and* ``file_error=True``, an ``IOError`` will be
+    raised.
+
+2) If you try to set a non-string key, or a non string value when
+    ``stringify=False``, a ``TypeError`` will be raised.
+
+3) A badly built config file will cause parsing errors.
+
+4) A parsing error can also occur when reading a configspec.
+
+5) In string interpolation you can specify a value that doesn't exist, or
+    create circular references (recursion).
+
+Number 5 (which is actually two different types of exceptions) is documented
+in `String Interpolation`_.
+
+*This* section is about errors raised during parsing.
+
+The base error class is ``ConfigObjError``. This is a subclass of
+``SyntaxError``, so you can trap for ``SyntaxError`` without needing to
+directly import any of the ConfigObj exceptions.
+
+The following other exceptions are defined (all deriving from
+``ConfigObjError``) :
+
+* ``NestingError``
+
+    This error indicates either a mismatch in the brackets in a section marker,
+    or an excessive level of nesting.
+
+* ``ParseError``
+
+    This error indicates that a line is badly written. It is neither a valid
+    ``key = value`` line, nor a valid section marker line, nor a comment line.
+
+* ``DuplicateError``
+
+    The keyword or section specified already exists.
+
+* ``ConfigspecError``
+
+    An error occurred whilst parsing a configspec.
+
+* ``UnreprError``
+
+    An error occurred when parsing a value in `unrepr mode`_.
+    
+* ``ReloadError``
+
+    ``reload`` was called on a ConfigObj instance that doesn't have a valid 
+    filename attribute.
+
+When parsing a configspec, ConfigObj will stop on the first error it
+encounters.  It will raise a ``ConfigspecError``. This will have an ``error``
+attribute, which is the actual error that was raised.
+
+Behaviour when parsing a config file depends on the option ``raise_errors``.
+If ConfigObj encounters an error while parsing a config file:
+
+    If ``raise_errors=True`` then ConfigObj will raise the appropriate error
+    and parsing will stop.
+
+    If ``raise_errors=False`` (the default) then parsing will continue to the
+    end and *all* errors will be collected.
+
+If ``raise_errors`` is False and multiple errors are found a ``ConfigObjError``
+is raised. The error raised has a ``config`` attribute, which is the parts of
+the ConfigObj that parsed successfully. It also has an attribute ``errors``,
+which is a list of *all* the errors raised. Each entry in the list is an
+instance of the appropriate error type. Each one has the following attributes
+(useful for delivering a sensible error message to your user) :
+
+* ``line``: the original line that caused the error.
+
+* ``line_number``: its number in the config file.
+
+* ``message``: the error message that accompanied the error.
+
+If only one error is found, then that error is re-raised. The error still has
+the ``config`` and ``errors`` attributes. This means that your error handling
+code can be the same whether one error is raised in parsing , or several.
+
+It also means that in the most common case (a single error) a useful error
+message will be raised.
+
+.. note::
+
+    One wrongly written line could break the basic structure of your config
+    file. This could cause every line after it to flag an error, so having a
+    list of all the lines that caused errors may not be as useful as it sounds.
+
+
+Validation
+==========
+
+.. hint::
+
+    The system of configspecs can seem confusing at first, but is actually
+    quite simple and powerful. The best reference is my article on ConfigObj:
+    
+    * `An Introduction to ConfigObj`_
+    
+    
+Validation is done through a combination of the configspec_ and a ``Validator``
+object. For this you need *validate.py* [#]_. See downloading_ if you don't
+have a copy.
+
+Validation can perform two different operations :
+
+1) Check that a value meets a specification. For example, check that a value
+    is an integer between one and six, or is a choice from a specific set of
+    options.
+
+2) It can convert the value into the type required. For example, if one of
+    your values is a port number, validation will turn it into an integer for
+    you.
+
+So validation can act as a transparent layer between the datatypes of your
+application configuration (boolean, integers, floats, etc) and the text format
+of your config file.
+
+
+configspec
+----------
+
+The ``validate`` method checks members against an entry in the configspec. Your
+configspec therefore resembles your config file, with a check for every member.
+
+In order to perform validation you need a ``Validator`` object. This has
+several useful built-in check functions. You can also create your own custom
+functions and register them with your Validator object.
+
+Each check is the name of one of these functions, including any parameters and
+keyword arguments. The configspecs look like function calls, and they map to
+function calls.
+
+The basic datatypes that an un-extended Validator can test for are :
+
+* boolean values (True and False)
+* integers (including minimum and maximum values)
+* floats (including min and max)
+* strings (including min and max length)
+* IP addresses (v4 only)
+
+It can also handle lists of these types and restrict a value to being one from
+a set of options.
+
+An example configspec is going to look something like::
+
+    port = integer(0, 100)
+    user = string(max=25)
+    mode = option('quiet', 'loud', 'silent')
+
+You can specify default values, and also have the same configspec applied to
+several sections. This is called `repeated sections`_.
+
+For full details on writing configspecs, please refer to the `validate.py
+documentation`_.
+
+.. important::
+
+    Your configspec is read by ConfigObj in the same way as a config file.
+    
+    That means you can do interpolation *within* your configspec.
+    
+    In order to allow this, checks in the 'DEFAULT' section (of the root level
+    of your configspec) are *not* used.
+    
+    If you want to use a configspec *without* interpolation being done in it
+    you can create your configspec manually and switch off interpolation:
+    
+    .. code-block:: python
+    
+        from configobj import ConfigObj
+        
+        configspec = ConfigObj(spec_filename, interpolation=False, list_values=False,
+                               _inspec=True)
+        conf = ConfigObj(config_filename, configspec=configspec)
+
+If you need to specify the encoding of your configspec, then you can pass in a
+ConfigObj instance as your configspec. When you read your configspec file, you
+*must* specify ``list_values=False``. If you need to support hashes in
+configspec values then you must also pass in ``_inspec=True``.
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    configspec = ConfigObj(configspecfilename, encoding='UTF8',
+                           list_values=False, _inspec=True)
+    config = ConfigObj(filename, configspec=configspec)
+
+.. _validate.py documentation: http://www.voidspace.org.uk/python/validate.html
+
+
+Type Conversion
+---------------
+
+By default, validation does type conversion. This means that if you specify
+``integer`` as the check, then calling validate_ will actually change the value
+to an integer (so long as the check succeeds).
+
+It also means that when you call the write_ method, the value will be converted
+back into a string using the ``str`` function.
+
+To switch this off, and leave values as strings after validation, you need to
+set the stringify_ attribute to ``False``. If this is the case, attempting to
+set a value to a non-string will raise an error.
+
+
+Default Values
+--------------
+
+You can set a default value in your check. If the value is missing from the
+config file then this value will be used instead. This means that your user
+only has to supply values that differ from the defaults.
+
+If you *don't* supply a default then for a value to be missing is an error,
+and this will show in the `return value`_ from validate.
+
+Additionally you can set the default to be ``None``. This means the value will
+be set to ``None`` (the object) *whichever check is used*. (It will be set to
+``''`` rather than ``None`` if stringify_ is ``False``). You can use this
+to easily implement optional values in your config files. ::
+
+    port = integer(0, 100, default=80)
+    user = string(max=25, default=0)
+    mode = option('quiet', 'loud', 'silent', default='loud')
+    nick = string(default=None)
+
+.. note::
+
+    Because the default goes through type conversion, it also has to pass the
+    check.
+
+    Note that ``default=None`` is case sensitive.
+
+
+List Values
+~~~~~~~~~~~
+
+It's possible that you will want to specify a list as a default value. To avoid
+confusing syntax with commas and quotes you use a list constructor to specify 
+that keyword arguments are lists. This includes the ``default`` value. This 
+makes checks look something like::
+
+    checkname(default=list('val1', 'val2', 'val3'))
+
+This works with all keyword arguments, but is most useful for default values.
+
+
+Repeated Sections
+-----------------
+
+Repeated sections are a way of specifying a configspec for a section that
+should be applied to all unspecified subsections in the same section.
+
+The easiest way of explaining this is to give an example. Suppose you have a
+config file that describes a dog. That dog has various attributes, but it can
+also have many fleas. You don't know in advance how many fleas there will be,
+or what they will be called, but you want each flea validated against the same
+configspec.
+
+We can define a section called *fleas*. We want every flea in that section
+(every sub-section) to have the same configspec applied to it. We do this by
+defining a single section called ``__many__``. ::
+
+    [dog]
+    name = string(default=Rover)
+    age = float(0, 99, default=0)
+
+        [[fleas]]
+
+            [[[__many__]]]
+            bloodsucker = boolean(default=True)
+            children = integer(default=10000)
+            size = option(small, tiny, micro, default=tiny)
+
+Every flea on our dog will now be validated using the ``__many__`` configspec.
+
+``__many__`` sections can have sub-sections, including their own ``__many__``
+sub-sections. Defaults work in the normal way in repeated sections.
+
+
+Repeated Values
+---------------
+
+As well as using ``__many__`` to validate unspecified sections you can use it to validate values. For
+example, to specify that all values in a section should be integers::
+
+    [section]
+	__many__ = integer
+	
+If you want to use repeated values alongside repeated sections you can call one ``__many__`` and the
+other ``___many___`` (with three underscores).
+
+
+Copy Mode
+---------
+
+Because you can specify default values in your configspec, you can use
+ConfigObj to write out default config files for your application.
+
+However, normally values supplied from a default in a configspec are *not*
+written out by the ``write`` method.
+
+To do this, you need to specify ``copy=True`` when you call validate. As well
+as not marking values as default, all the comments in the configspec file
+will be copied into your ConfigObj instance.
+
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    from validate import Validator
+    vdt = Validator()
+    config = ConfigObj(configspec='default.ini')
+    config.filename = 'new_default.ini'
+    config.validate(vdt, copy=True)
+    config.write()
+    
+If you need to support hashes in the configspec values then you must create
+it with ``_inspec=True``. This has the side effect of switching off the parsing
+of inline comments, meaning that they won't be copied into the new config file.
+(ConfigObj syntax is slightly different from configspec syntax and the parser
+can't support both inline comments and hashes in configspec values.)
+
+
+Validation and Interpolation
+----------------------------
+
+String interpolation and validation don't play well together. When validation
+changes type it sets the value. If the value uses interpolation, then the 
+interpolation reference would normally be overwritten. Calling ``write`` would
+then use the absolute value and the interpolation reference would be lost.
+
+As a compromise - if the value is unchanged by validation then it is not reset.
+This means strings that pass through validation unmodified will not be 
+overwritten. If validation changes type - the value has to be overwritten, and
+any interpolation references are lost.
+
+
+Extra Values
+------------
+
+After validation the ``extra_values`` member of every section that is listed in
+the configspec will be populated with the names of members that are in the
+config file but not in the configspec.
+
+If you are reporting configuration errors to your user this information can be
+useful, for example some missing entries may be due to misspelt entries that
+appear as extra values.
+
+See the get_extra_values_ function
+
+New in ConfigObj 4.7.0.
+
+
+
+SimpleVal
+---------
+
+You may not need a full validation process, but still want to check if all the
+expected values are present.
+
+Provided as part of the ConfigObj module is the ``SimpleVal`` object. This has
+a dummy ``test`` method that always passes.
+
+The only reason a test will fail is if the value is missing. The return value
+from ``validate`` will either be ``True``, meaning all present, or a dictionary
+with ``False`` for all missing values/sections.
+
+To use it, you still need to pass in a valid configspec when you create the
+ConfigObj, but just set all the values to ``''``. Then create an instance of
+``SimpleVal`` and pass it to the ``validate`` method.
+
+As a trivial example if you had the following config file::
+
+    # config file for an application
+    port = 80
+    protocol = http
+    domain = voidspace
+    top_level_domain = org.uk
+
+You would write the following configspec::
+
+    port = ''
+    protocol = ''
+    domain = ''
+    top_level_domain = ''
+
+
+.. code-block:: python
+
+    config = Configobj(filename, configspec=configspec)
+    val = SimpleVal()
+    test = config.validate(val)
+    if test == True:
+        print 'All values present.'
+    elif test == False:
+        print 'No values present!'
+    else:
+        for entry in test:
+            if test[entry] == False:
+                print '"%s" missing.' % entry
+
+
+Empty values
+============
+
+Many config files from other applications allow empty values. As of version
+4.3.0, ConfigObj will read these as an empty string.
+
+A new option/attribute has been added (``write_empty_values``) to allow
+ConfigObj to write empty strings as empty values.
+
+.. code-block:: python
+
+    from configobj import ConfigObj
+    cfg = '''
+        key =
+        key2 = # a comment
+    '''.splitlines()
+    config = ConfigObj(cfg)
+    print config
+    ConfigObj({'key': '', 'key2': ''})
+    
+    config.write_empty_values = True
+    for line in config.write():
+        print line
+    
+    key = 
+    key2 =     # a comment
+
+
+unrepr mode
+===========
+
+The ``unrepr`` option allows you to store and retrieve the basic Python
+data-types using config files. It has to use a slightly different syntax to
+normal ConfigObj files. Unsurprisingly it uses Python syntax.
+
+This means that lists are different (they are surrounded by square brackets),
+and strings *must* be quoted.
+
+The types that ``unrepr`` can work with are :
+
+    | strings, lists tuples
+    | None, True, False
+    | dictionaries, integers, floats
+    | longs and complex numbers
+    
+You can't store classes, types or instances.
+
+``unrepr`` uses ``repr(object)`` to write out values, so it currently *doesn't*
+check that you are writing valid objects. If you attempt to read an unsupported
+value, ConfigObj will raise a ``configobj.UnknownType`` exception.
+
+Values that are triple quoted cased. The triple quotes are removed *before*
+converting. This means that you can use triple quotes to write dictionaries
+over several lines in your config files. They won't be written like this
+though.
+
+If you are writing config files by hand, for use with ``unrepr``, you should
+be aware of the following differences from normal ConfigObj syntax :
+
+    | List : ``['A List', 'With', 'Strings']``
+    | Strings : ``"Must be quoted."``
+    | Backslash : ``"The backslash must be escaped \\"``
+
+These all follow normal Python syntax.
+
+In unrepr mode *inline comments* are not saved. This is because lines are
+parsed using the `compiler package <http://docs.python.org/lib/compiler.html>`_
+which discards comments.
+
+
+String Interpolation
+====================
+
+.. note::
+    
+    String interpolation can slow down (slightly) the fetching of values
+    from your config object. If you aren't using interpolation and it
+    is performance critical then create your instance with
+    ``interpolation=False``.
+
+ConfigObj allows string interpolation *similar* to the way ``ConfigParser``
+or ``string.Template`` work. The value of the ``interpolation`` attribute
+determines which style of interpolation you want to use. Valid values are
+"ConfigParser" or "Template" (case-insensitive, so "configparser" and
+"template" will also work). For backwards compatibility reasons, the value
+``True`` is also a valid value for the ``interpolation`` attribute, and
+will select ``ConfigParser``-style interpolation. At some undetermined point
+in the future, that default *may* change to ``Template``-style interpolation.
+
+For ``ConfigParser``-style interpolation, you specify a value to be
+substituted by including ``%(name)s`` in the value.
+
+For ``Template``-style interpolation, you specify a value to be substituted
+by including ``${cl}name{cr}`` in the value. Alternately, if 'name' is a valid
+Python identifier (i.e., is composed of nothing but alphanumeric characters,
+plus the underscore character), then the braces are optional and the value
+can be written as ``$name``.
+
+Note that ``ConfigParser``-style interpolation and ``Template``-style
+interpolation are mutually exclusive; you cannot have a configuration file
+that's a mix of one or the other. Pick one and stick to it. ``Template``-style
+interpolation is simpler to read and write by hand, and is recommended if
+you don't have a particular reason to use ``ConfigParser``-style.
+
+Interpolation checks first the current section to see if ``name`` is the key
+to a value. ('name' is case sensitive).
+
+If it doesn't find it, next it checks the 'DEFAULT' sub-section of the current
+section.
+
+If it still doesn't find it, it moves on to check the parent section and the
+parent section's 'DEFAULT' subsection, and so on all the way up to the main
+section.
+
+If the value specified isn't found in any of these locations, then a
+``MissingInterpolationOption`` error is raised (a subclass of
+``ConfigObjError``).
+
+If it is found then the returned value is also checked for substitutions. This
+allows you to make up compound values (for example directory paths) that use
+more than one default value. It also means it's possible to create circular
+references. If there are any circular references which would cause an infinite
+interpolation loop, an ``InterpolationLoopError`` is raised.
+
+Both of these errors are subclasses of ``InterpolationError``, which is a
+subclass of ``ConfigObjError``.
+
+String interpolation and validation don't play well together. This is because 
+validation overwrites values - and so may erase the interpolation references.
+See `Validation and Interpolation`_. (This can only happen if validation
+has to *change* the value).
+
+New in ConfigObj 4.7.0: String interpolation is now done in members of list
+values.
+
+
+String Interpolation and List Values
+------------------------------------
+
+Since version 4.7 string interpolation is done on string members of list values.
+If interpolation changes any members of the list then what you get back is a
+*copy* of the list rather than the original list.
+
+This makes fetching list values slightly slower when interpolation is on, it
+also means that if you mutate the list changes won't be reflected in the
+original list:
+
+.. code-block:: python
+
+    >>> c = ConfigObj()
+    >>> c['foo'] = 'boo'
+    >>> c['bar'] = ['%(foo)s'] 
+    >>> c['bar']
+    ['boo']
+    >>> c['bar'].append('fish')
+    >>> c['bar']
+    ['boo']
+
+Instead of mutating the list you must create a new list and reassign it.
+
+
+Comments
+========
+
+Any line that starts with a '#', possibly preceded by whitespace, is a comment.
+
+If a config file starts with comments then these are preserved as the
+initial_comment_.
+
+If a config file ends with comments then these are preserved as the
+final_comment_.
+
+Every key or section marker may have lines of comments immediately above it.
+These are saved as the ``comments`` attribute of the section. Each member is a
+list of lines.
+
+You can also have a comment inline with a value. These are saved as the
+``inline_comments`` attribute of the section, with one entry per member of the
+section.
+
+Subsections (section markers in the config file) can also have comments.
+
+See `Section Attributes`_ for more on these attributes.
+
+These comments are all written back out by the ``write`` method.
+
+
+flatten_errors
+==============
+
+.. code-block:: python
+
+    flatten_errors(cfg, res)
+
+Validation_ is a powerful way of checking that the values supplied by the user
+make sense.
+
+The validate_ method returns a results dictionary that represents pass or fail
+for each value. This doesn't give you any information about *why* the check
+failed.
+
+``flatten_errors`` is an example function that turns a results dictionary into
+a flat list, that only contains values that *failed*.
+
+``cfg`` is the ConfigObj instance being checked, ``res`` is the results
+dictionary returned by ``validate``.
+
+It returns a list of keys that failed. Each member of the list is a tuple::
+
+    ([list of sections...], key, result)
+
+If ``validate`` was called with ``preserve_errors=False`` (the default)
+then ``result`` will always be ``False``.
+
+*list of sections* is a flattened list of sections that the key was found
+in.
+
+If the section was missing then key will be ``None``.
+
+If the value (or section) was missing then ``result`` will be ``False``.
+
+If ``validate`` was called with ``preserve_errors=True`` and a value
+was present, but failed the check, then ``result`` will be the exception
+object returned. You can use this as a string that describes the failure.
+
+For example :
+
+    *The value "3" is of the wrong type*.
+
+
+Example Usage
+-------------
+
+The output from ``flatten_errors`` is a list of tuples.
+
+Here is an example of how you could present this information to the user.
+
+
+.. code-block:: python
+
+    vtor = validate.Validator()
+    # ini is your config file - cs is the configspec
+    cfg = ConfigObj(ini, configspec=cs)
+    res = cfg.validate(vtor, preserve_errors=True)
+    for entry in flatten_errors(cfg, res):
+        # each entry is a tuple
+        section_list, key, error = entry
+        if key is not None:
+           section_list.append(key)
+        else:
+            section_list.append('[missing section]')
+        section_string = ', '.join(section_list)
+        if error == False:
+            error = 'Missing value or section.'
+        print section_string, ' = ', error
+
+
+get_extra_values
+================
+
+
+.. code-block:: python
+
+    get_extra_values(conf)
+
+New in ConfigObj 4.7.0.
+
+Find all the values and sections not in the configspec from a validated
+ConfigObj.
+
+``get_extra_values`` returns a list of tuples where each tuple represents
+either an extra section, or an extra value.
+
+The tuples contain two values, a tuple representing the section the value 
+is in and the name of the extra values. For extra values in the top level
+section the first member will be an empty tuple. For values in the 'foo'
+section the first member will be ``('foo',)``. For members in the 'bar'
+subsection of the 'foo' section the first member will be ``('foo', 'bar')``.
+
+Extra sections will only have one entry. Values and subsections inside
+an extra section aren't listed separately.
+
+NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't
+been validated it will return an empty list.
+
+
+Example Usage
+-------------
+
+The output from ``get_extra_values`` is a list of tuples.
+
+Here is an example of how you could present this information to the user.
+
+.. code-block:: python
+
+    vtor = validate.Validator()
+    # ini is your config file - cs is the configspec
+    cfg = ConfigObj(ini, configspec=cs)
+    cfg.validate(vtor, preserve_errors=True)
+    
+    for sections, name in get_extra_values(cfg):
+    
+        # this code gets the extra values themselves
+        the_section = cfg
+        for section in sections:
+            the_section = cfg[section]
+            
+        # the_value may be a section or a value
+        the_value = the_section[name]
+        
+        section_or_value = 'value
+        if isinstance(the_value, dict):
+            # Sections are subclasses of dict
+            section_or_value = 'section'
+        
+        section_string = ', '.join(sections) or "top level"
+        print 'Extra entry in section: %s. Entry %r is a %s' % (section_string, name, section_or_value)
+        
+
+
+CREDITS
+=======
+
+ConfigObj 4 is written by (and copyright) `Michael Foord`_ and 
+`Nicola Larosa`_.
+
+Particularly thanks to Nicola Larosa for help on the config file spec, the
+validation system and the doctests.
+
+*validate.py* was originally written by Michael Foord and Mark Andrews.
+
+Thanks to many others for input, patches and bugfixes.
+
+
+
+LICENSE
+=======
+
+ConfigObj, and related files, are licensed under the BSD license. This is a
+very unrestrictive license, but it comes with the usual disclaimer. This is
+free software: test it, break it, just don't blame us if it eats your data !
+Of course if it does, let us know and we'll fix the problem so it doesn't
+happen to anyone else::
+
+    Copyright (c) 2004 - 2010, Michael Foord & Nicola Larosa
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+
+        * Redistributions of source code must retain the above copyright
+          notice, this list of conditions and the following disclaimer.
+
+        * Redistributions in binary form must reproduce the above
+          copyright notice, this list of conditions and the following
+          disclaimer in the documentation and/or other materials provided
+          with the distribution.
+
+        * Neither the name of Michael Foord nor Nicola Larosa
+          may be used to endorse or promote products derived from this
+          software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+You should also be able to find a copy of this license at : `BSD License`_
+
+.. _BSD License: http://www.voidspace.org.uk/python/license.shtml
+
+
+TODO
+====
+
+Better support for configuration from multiple files, including tracking
+*where* the original file came from and writing changes to the correct
+file.
+
+Make ``newline`` a keyword argument (as well as an attribute) ?
+
+``UTF16`` encoded files, when returned as a list of lines, will have the
+BOM at the start of every line. Should this be removed from all but the
+first line ?
+
+Option to set warning type for unicode decode ? (Defaults to strict).
+
+A method to optionally remove uniform indentation from multiline values.
+(do as an example of using ``walk`` - along with string-escape)
+
+Should the results dictionary from validate be an ordered dictionary if
+`odict <http://www.voidspace.org.uk/python/odict.html>`_ is available ?
+
+Implement some of the sequence methods (which include slicing) from the
+newer ``odict`` ?
+
+Preserve line numbers of values (and possibly the original text of each value).
+
+
+ISSUES
+======
+
+.. note::
+
+    Please file any bug reports to `Michael Foord`_ or the **ConfigObj**
+    `Mailing List`_.
+
+There is currently no way to specify the encoding of a configspec file.
+
+As a consequence of the changes to configspec handling in version 4.6.0, when
+you create a ConfigObj instance and provide a configspec, the configspec
+attribute is only set on the ConfigObj instance - it isn't set on the sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't documented but did work previously.
+
+In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments in configspecs. This will only affect you if you are using ``copy=True`` when validating and expecting inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be copied as usual).
+    
+If you *create* the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or list of lines) then you should pass in ``_inspec=True`` to the constructor to allow hashes in values. This is the magic that switches off inline comment parsing.
+
+When using ``copy`` mode for validation, it won't copy ``DEFAULT``
+sections. This is so that you *can* use interpolation in configspec
+files. This is probably true even if interpolation is off in the 
+configspec.
+
+You can't have a keyword with the same name as a section (in the same
+section). They are both dictionary keys - so they would overlap.
+
+ConfigObj doesn't quote and unquote values if ``list_values=False``.
+This means that leading or trailing whitespace in values will be lost when
+writing. (Unless you manually quote).
+
+Interpolation checks first the current section, then the 'DEFAULT' subsection
+of the current section, before moving on to the current section's parent and
+so on up the tree.
+
+Does it matter that we don't support the ':' divider, which is supported
+by ``ConfigParser`` ?
+
+String interpolation and validation don't play well together. When
+validation changes type it sets the value. This will correctly fetch the
+value using interpolation - but then overwrite the interpolation reference.
+If the value is unchanged by validation (it's a string) - but other types
+will be.
+
+
+CHANGELOG
+=========
+
+This is an abbreviated changelog showing the major releases up to version 4.
+From version 4 it lists all releases and changes.
+
+
+2010/02/27 - Version 4.7.2
+--------------------------
+
+* BUGFIX: Restore Python 2.3 compatibility
+* BUGFIX: Members that were lists were being returned as copies due to interpolation
+  introduced in 4.7. Lists are now only copies if interpolation changes a list
+  member.
+* BUGFIX: ``pop`` now does interpolation in list values as well.
+* BUGFIX: where interpolation matches a section name rather than a value it is
+  ignored instead of raising an exception on fetching the item.
+* BUGFIX: values that use interpolation to reference members that don't exist can
+  now be repr'd.
+* BUGFIX: Fix to avoid writing '\\r\\r\\n' on Windows when given a file opened in
+  text write mode ('w').
+  
+See `String Interpolation and List Values`_ for information about the problem with lists and interpolation.
+
+
+2010/02/06 - Version 4.7.1
+--------------------------
+
+* Fix bug in options deprecation warning added in 4.7.0
+
+
+2010/01/09 - Version 4.7.0
+--------------------------
+
+* Minimum supported version of Python is now 2.3
+* ~25% performance improvement thanks to Christian Heimes
+* String interpolation now works in list value members
+* After validation any additional entries not in the configspec are listed in
+  the ``extra_values`` section member
+* Addition of the ``get_extra_values`` function for finding all extra values
+  in a validated ConfigObj instance
+* Deprecated the use of the ``options`` dictionary in the ConfigObj constructor
+  and added explicit keyword arguments instead. Use \*\*options if you want
+  to initialise a ConfigObj instance from a dictionary
+* Constructing a ConfigObj from an existing ConfigObj instance now preserves
+  the order of values and sections from the original instance in the new one
+* BUGFIX: Checks that failed validation would not populate ``default_values`` and
+  ``restore_default_value()`` wouldn't work for those entries
+* BUGFIX: clear() now clears 'defaults'
+* BUGFIX: empty values in list values were accidentally valid syntax. They now
+  raise a ``ParseError``. e.g. "value = 1, , 2"
+* BUGFIX: Change to the result of a call to ``validate`` when ``preserve_errors``
+  is True. Previously sections where *all* values failed validation would
+  return False for the section rather than preserving the errors. False will
+  now only be returned for a section if it is missing
+* Distribution includes version 1.0.1 of validate.py
+* Removed __revision__ and __docformat__
+
+
+2009/04/13 - Version 4.6.0
+--------------------------
+
+* Pickling of ConfigObj instances now supported (thanks to Christian Heimes)
+* Hashes in confgspecs are now allowed (see note below)
+* Replaced use of hasattr (which can swallow exceptions) with getattr
+* __many__ in configspecs can refer to scalars (ordinary values) as well as sections
+* You can use ___many___ (three underscores!) where you want to use __many__ as well
+* You can now have normal sections inside configspec sections that use __many__
+* You can now create an empty ConfigObj with a configspec, programmatically set values and then validate
+* A section that was supplied as a value (or vice-versa) in the actual config file would cause an exception during validation (the config file is still broken of course, but it is now handled gracefully)
+* Added ``as_list`` method
+* Removed the deprecated ``istrue``, ``encode`` and ``decode`` methods
+* Running test_configobj.py now also runs the doctests in the configobj module
+
+As a consequence of the changes to configspec handling, when you create a ConfigObj instance and provide 
+a configspec, the configspec attribute is only set on the ConfigObj instance - it isn't set on the 
+sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't 
+documented but did work previously.
+
+In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments 
+in configspecs. This will only affect you if you are using ``copy=True`` when validating and expecting 
+inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be 
+copied as usual).
+    
+If you *create* the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or 
+list of lines) then you should pass in ``_inspec=True`` to the constructor to allow hashes in values. 
+This is the magic that switches off inline comment parsing.
+
+    
+2008/06/27 - Version 4.5.3
+--------------------------
+
+BUGFIX: fixed a problem with ``copy=True`` when validating with configspecs that use
+``__many__`` sections.
+
+
+2008/02/05 - Version 4.5.2
+--------------------------
+
+Distribution updated to include version 0.3.2 of validate_. This means that
+``None`` as a default value in configspecs works.
+
+
+2008/02/05 - Version 4.5.1
+--------------------------
+
+Distribution updated to include version 0.3.1 of validate_. This means that
+Unicode configspecs now work.
+
+
+2008/02/05 - Version 4.5.0
+--------------------------
+
+ConfigObj will now guarantee that files will be written terminated with a
+newline.
+
+ConfigObj will no longer attempt to import the ``validate`` module, until/unless 
+you call ``ConfigObj.validate`` with ``preserve_errors=True``. This makes it 
+faster to import.
+
+New methods ``restore_default`` and ``restore_defaults``. ``restore_default``
+resets an entry to its default value (and returns that value). ``restore_defaults``
+resets all entries to their default value. It doesn't modify entries without a 
+default value. You must have validated a ConfigObj (which populates the
+``default_values`` dictionary) before calling these methods.
+
+BUGFIX: Proper quoting of keys, values and list values that contain hashes 
+(when writing).  When ``list_values=False``, values containing hashes are 
+triple quoted.
+
+Added the ``reload`` method. This reloads a ConfigObj from file. If the filename
+attribute is not set then a ``ReloadError`` (a new exception inheriting from
+``IOError``) is raised.
+
+BUGFIX: Files are read in with 'rb' mode, so that native/non-native line endings work!
+
+Minor efficiency improvement in ``unrepr`` mode.
+
+Added missing docstrings for some overidden dictionary methods.
+
+Added the ``reset`` method. This restores a ConfigObj to a freshly created state.
+
+Removed old CHANGELOG file.
+
+
+2007/02/04 - Version 4.4.0
+--------------------------
+
+Official release of 4.4.0
+
+
+2006/12/17 - Version 4.3.3-alpha4
+---------------------------------
+
+By Nicola Larosa
+
+Allowed arbitrary indentation in the ``indent_type`` parameter, removed the
+``NUM_INDENT_SPACES`` and ``MAX_INTERPOL_DEPTH`` (a leftover) constants,
+added indentation tests (including another docutils workaround, sigh), updated
+the documentation.
+
+By Michael Foord
+
+Made the import of ``compiler`` conditional so that ``ConfigObj`` can be used
+with `IronPython <http://www.codeplex.com/IronPython>`_.
+
+
+2006/12/17 - Version 4.3.3-alpha3
+---------------------------------
+
+By Nicola Larosa
+
+Added a missing ``self.`` in the _handle_comment method and a related test,
+per Sourceforge bug #1523975.
+
+
+2006/12/09 - Version 4.3.3-alpha2
+---------------------------------
+
+By Nicola Larosa
+
+Changed interpolation search strategy, based on this patch by Robin Munn:
+http://sourceforge.net/mailarchive/message.php?msg_id=17125993
+
+
+2006/12/09 - Version 4.3.3-alpha1
+---------------------------------
+
+By Nicola Larosa
+
+Added Template-style interpolation, with tests, based on this patch by
+Robin Munn: http://sourceforge.net/mailarchive/message.php?msg_id=17125991
+(awful archives, bad Sourceforge, bad).
+
+
+2006/06/04 - Version 4.3.2
+--------------------------
+
+Changed error handling, if parsing finds a single error then that error will
+be re-raised. That error will still have an ``errors`` and a ``config``
+attribute.
+
+Fixed bug where '\\n' terminated files could be truncated.
+
+Bugfix in ``unrepr`` mode, it couldn't handle '#' in values. (Thanks to
+Philippe Normand for the report.)
+
+As a consequence of this fix, ConfigObj doesn't now keep inline comments in
+``unrepr`` mode. This is because the parser in the `compiler package`_
+doesn't keep comments.
+
+Error messages are now more useful. They tell you the number of parsing errors
+and the line number of the first error. (In the case of multiple errors.)
+
+Line numbers in exceptions now start at 1, not 0.
+
+Errors in ``unrepr`` mode are now handled the same way as in the normal mode.
+The errors stored will be an ``UnreprError``.
+
+
+2006/04/29 - Version 4.3.1
+--------------------------
+
+Added ``validate.py`` back into ``configobj.zip``. (Thanks to Stewart
+Midwinter)
+
+Updated to `validate.py`_ 0.2.2.
+
+Preserve tuples when calling the ``dict`` method. (Thanks to Gustavo Niemeyer.)
+
+Changed ``__repr__`` to return a string that contains ``ConfigObj({ ... })``.
+
+Change so that an options dictionary isn't modified by passing it to ConfigObj.
+(Thanks to Artarious.)
+
+Added ability to handle negative integers in ``unrepr``. (Thanks to Kevin
+Dangoor.)
+
+
+2006/03/24 - Version 4.3.0
+--------------------------
+
+Moved the tests and the CHANGELOG (etc) into a separate file. This has reduced
+the size of ``configobj.py`` by about 40%.
+
+Added the ``unrepr`` mode to reading and writing config files. Thanks to Kevin
+Dangoor for this suggestion.
+
+Empty values are now valid syntax. They are read as an empty string ``''``.
+(``key =``, or ``key = # comment``.)
+
+``validate`` now honours the order of the configspec.
+
+Added the ``copy`` mode to validate. Thanks to Louis Cordier for this
+suggestion.
+
+Fixed bug where files written on windows could be given ``'\r\r\n'`` line
+terminators.
+
+Fixed bug where last occurring comment line could be interpreted as the
+final comment if the last line isn't terminated.
+
+Fixed bug where nested list values would be flattened when ``write`` is
+called. Now sub-lists have a string representation written instead.
+
+Deprecated ``encode`` and ``decode`` methods instead.
+
+You can now pass in a ConfigObj instance as a configspec (remember to read
+the configspec file using ``list_values=False``).
+
+Sorted footnotes in the docs.
+
+
+2006/02/16 - Version 4.2.0
+--------------------------
+
+Removed ``BOM_UTF8`` from ``__all__``.
+
+The ``BOM`` attribute has become a boolean. (Defaults to ``False``.) It is
+*only* ``True`` for the ``UTF16/UTF8`` encodings.
+
+File like objects no longer need a ``seek`` attribute.
+
+Full unicode support added. New options/attributes ``encoding``,
+``default_encoding``.
+
+ConfigObj no longer keeps a reference to file like objects. Instead the
+``write`` method takes a file like object as an optional argument. (Which
+will be used in preference of the ``filename`` attribute if that exists as
+well.)
+
+utf16 files decoded to unicode.
+
+If ``BOM`` is ``True``, but no encoding specified, then the utf8 BOM is
+written out at the start of the file. (It will normally only be ``True`` if
+the utf8 BOM was found when the file was read.)
+
+Thanks to Aaron Bentley for help and testing on the unicode issues.
+
+File paths are *not* converted to absolute paths, relative paths will
+remain relative as the ``filename`` attribute.
+
+Fixed bug where ``final_comment`` wasn't returned if ``write`` is returning
+a list of lines.
+
+Deprecated ``istrue``, replaced it with ``as_bool``.
+
+Added ``as_int`` and ``as_float``.
+
+
+2005/12/14 - Version 4.1.0
+--------------------------
+
+Added ``merge``, a recursive update.
+
+Added ``preserve_errors`` to ``validate`` and the ``flatten_errors``
+example function.
+
+Thanks to Matthew Brett for suggestions and helping me iron out bugs.
+    
+Fixed bug where a config file is *all* comment, the comment will now be
+``initial_comment`` rather than ``final_comment``.
+
+Validation no longer done on the 'DEFAULT' section (only in the root level).
+This allows interpolation in configspecs.
+
+Also use the new list syntax in validate_ 0.2.1. (For configspecs).
+
+
+2005/12/02 - Version 4.0.2
+--------------------------
+
+Fixed bug in ``create_empty``. Thanks to Paul Jimenez for the report.
+
+
+2005/11/05 - Version 4.0.1
+--------------------------
+
+Fixed bug in ``Section.walk`` when transforming names as well as values.
+
+Added the ``istrue`` method. (Fetches the boolean equivalent of a string
+value).
+
+Fixed ``list_values=False`` - they are now only quoted/unquoted if they
+are multiline values.
+
+List values are written as ``item, item`` rather than ``item,item``.
+
+
+2005/10/17 - Version 4.0.0
+--------------------------
+
+**ConfigObj 4.0.0 Final**
+
+Fixed bug in ``setdefault``. When creating a new section with setdefault the
+reference returned would be to the dictionary passed in *not* to the new 
+section. Bug fixed and behaviour documented.
+
+Obscure typo/bug fixed in ``write``. Wouldn't have affected anyone though.
+
+
+2005/09/09 - Version 4.0.0 beta 5
+---------------------------------
+
+Removed ``PositionError``.
+
+Allowed quotes around keys as documented.
+
+Fixed bug with commas in comments. (matched as a list value)
+
+
+2005/09/07 - Version 4.0.0 beta 4
+---------------------------------
+
+Fixed bug in ``__delitem__``. Deleting an item no longer deletes the 
+``inline_comments`` attribute.
+
+Fixed bug in initialising ConfigObj from a ConfigObj.
+
+Changed the mailing list address.
+
+
+2005/08/28 - Version 4.0.0 beta 3
+---------------------------------
+
+Interpolation is switched off before writing out files.
+
+Fixed bug in handling ``StringIO`` instances. (Thanks to report from
+Gustavo Niemeyer.)
+
+Moved the doctests from the ``__init__`` method to a separate function.
+(For the sake of IDE calltips).
+
+
+2005/08/25 - Version 4.0.0 beta 2
+---------------------------------
+
+Amendments to *validate.py*.
+
+First public release.
+
+
+2005/08/21 - Version 4.0.0 beta 1
+---------------------------------
+
+Reads nested subsections to any depth.
+
+Multiline values.
+
+Simplified options and methods.
+
+New list syntax.
+
+Faster, smaller, and better parser.
+
+Validation greatly improved. Includes:
+
+    * type conversion
+    * default values
+    * repeated sections
+
+Improved error handling.
+
+Plus lots of other improvements.
+
+
+2004/05/24 - Version 3.0.0
+--------------------------
+
+Several incompatible changes: another major overhaul and change. (Lots of
+improvements though).
+
+Added support for standard config files with sections. This has an entirely
+new interface: each section is a dictionary of values.
+
+Changed the update method to be called writein: update clashes with a dict
+method.
+
+Made various attributes keyword arguments, added several.
+
+Configspecs and orderlists have changed a great deal.
+
+Removed support for adding dictionaries: use update instead.
+
+Now subclasses a new class called caselessDict. This should add various
+dictionary methods that could have caused errors before.
+
+It also preserves the original casing of keywords when writing them back out.
+
+Comments are also saved using a ``caselessDict``.
+
+Using a non-string key will now raise a ``TypeError`` rather than converting 
+the key.
+
+Added an exceptions keyword for *much* better handling of errors.
+
+Made ``creatempty=False`` the default.
+
+Now checks indict *and* any keyword args. Keyword args take precedence over
+indict.
+
+``' ', ':', '=', ','`` and ``'\t'`` are now all valid dividers where the 
+keyword is unquoted.
+
+ConfigObj now does no type checking against configspec when you set items.
+
+delete and add methods removed (they were unnecessary).
+
+Docs rewritten to include all this gumph and more; actually ConfigObj is
+*really* easy to use.
+
+Support for stdout was removed.
+
+A few new methods added.
+
+Charmap is now incorporated into ConfigObj.
+
+
+2004/03/14 - Version 2.0.0 beta
+-------------------------------
+
+Re-written it to subclass dict. My first forays into inheritance and operator
+overloading.
+
+The config object now behaves like a dictionary.
+
+I've completely broken the interface, but I don't think anyone was really
+using it anyway.
+
+This new version is much more 'classy'.
+
+It will also read straight from/to a filename and completely parse a config
+file without you *having* to supply a config spec.
+
+Uses listparse, so can handle nested list items as values.
+
+No longer has getval and setval methods: use normal dictionary methods, or add
+and delete.
+
+
+2004/01/29 - Version 1.0.5
+--------------------------
+
+Version 1.0.5 has a couple of bugfixes as well as a couple of useful additions
+over previous versions.
+
+Since 1.0.0 the buildconfig function has been moved into this distribution,
+and the methods reset, verify, getval and setval have been added.
+
+A couple of bugs have been fixed.
+
+
+Origins
+-------
+
+ConfigObj originated in a set of functions for reading config files in the
+`atlantibots <http://www.voidspace.org.uk/atlantibots/>`_ project. The original
+functions were written by Rob McNeur.
+
+
+----------
+
+
+Footnotes
+=========
+
+.. [#] And if you discover any bugs, let us know. We'll fix them quickly.
+
+.. [#] If you specify a filename that doesn't exist, ConfigObj will assume you
+    are creating a new one. See the *create_empty* and *file_error* options.
+
+.. [#] They can be byte strings (*ordinary* strings) or Unicode.
+
+.. [#] Except we don't support the RFC822 style line continuations, nor ':' as
+    a divider.
+
+.. [#] This is a change in ConfigObj 4.2.0. Note that ConfigObj doesn't call
+    the seek method of any file like object you pass in. You may want to call
+    ``file_object.seek(0)`` yourself, first.
+
+.. [#] A side effect of this is that it enables you to copy a ConfigObj :
+
+    .. code-block:: python
+
+        # only copies members
+        # not attributes/comments
+        config2 = ConfigObj(config1)
+
+    Since ConfigObj 4.7.0 the order of members and sections will be
+    preserved when copying a ConfigObj instance.
+
+.. [#] Other than lists of strings.
+
+.. [#] The exception is if it detects a ``UTF16`` encoded file which it
+    must decode before parsing.
+     
+.. [#] The method signature shows that this method takes
+    two arguments. The second is the section to be written. This is because the
+    ``write`` method is called recursively.
+
+.. [#] The dict method doesn't actually use the deepcopy mechanism. This means
+    if you add nested lists (etc) to your ConfigObj, then the dictionary
+    returned by dict may contain some references. For all *normal* ConfigObjs
+    it will return a deepcopy.
+
+.. [#] Passing ``(section, key)`` rather than ``(value, key)`` allows you to
+    change the value by setting ``section[key] = newval``. It also gives you
+    access to the *rename* method of the section.
+
+.. [#] Minimum required version of *validate.py* 0.2.0 .
+
+.. _listquote: http://www.voidspace.org.uk/python/modules.shtml#listquote
+.. _Michael Foord: http://www.voidspace.org.uk/python/weblog/index.shtml
+.. _Nicola Larosa: http://www.teknico.net

+ 45 - 30
desktop/core/ext-py/configobj/docs/stylesheets/default.css → desktop/core/ext-py/configobj-4.7.2/docs/default.css

@@ -1,8 +1,6 @@
 /*
-:Author: David Goodger
-:Contact: goodger@users.sourceforge.net
-:Date: $Date: 2005-09-25 17:49:54 +0200 (Sun, 25 Sep 2005) $
-:Revision: $Revision: 3901 $
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 5951 2009-05-18 18:03:10Z milde $
 :Copyright: This stylesheet has been placed in the public domain.
 
 Default cascading style sheet for the HTML output of Docutils.
@@ -11,10 +9,17 @@ See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
 customize this style sheet.
 */
 
-/* "! important" is used here to override other ``margin-top`` and
-   ``margin-bottom`` styles that are later in the stylesheet or 
-   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+  border: 0 }
+
+table.borderless td, table.borderless th {
+  /* Override padding for "table.docutils td" with "! important".
+     The right padding separates the table cells. */
+  padding: 0 0.5em 0 0 ! important }
+
 .first {
+  /* Override more specific margin styles with "! important". */
   margin-top: 0 ! important }
 
 .last, .with-subtitle {
@@ -83,7 +88,8 @@ div.dedication p.topic-title {
   font-style: normal }
 
 div.figure {
-  margin-left: 2em }
+  margin-left: 2em ;
+  margin-right: 2em }
 
 div.footer, div.header {
   clear: both;
@@ -100,7 +106,7 @@ div.line-block div.line-block {
   margin-left: 1.5em }
 
 div.sidebar {
-  margin-left: 1em ;
+  margin: 0 0 0.5em 1em ;
   border: medium outset ;
   padding: 1em ;
   background-color: #ffffee ;
@@ -142,14 +148,32 @@ h2.subtitle {
 hr.docutils {
   width: 75% }
 
-img.align-left {
-  clear: left }
+img.align-left, .figure.align-left{
+  clear: left ;
+  float: left ;
+  margin-right: 1em }
 
-img.align-right {
-  clear: right }
+img.align-right, .figure.align-right {
+  clear: right ;
+  float: right ;
+  margin-left: 1em }
 
-img.borderless {
-  border: 0 }
+.align-left {
+  text-align: left }
+
+.align-center {
+  clear: both ;
+  text-align: center }
+
+.align-right {
+  text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+  text-align: left }
+
+/* div.align-center * { */
+/*   text-align: left } */
 
 ol.simple, ul.simple {
   margin-bottom: 1em }
@@ -204,17 +228,11 @@ p.topic-title {
 pre.address {
   margin-bottom: 0 ;
   margin-top: 0 ;
-  font-family: serif ;
-  font-size: 100% }
-
-pre.line-block {
-  font-family: serif ;
-  font-size: 100% }
+  font: inherit }
 
 pre.literal-block, pre.doctest-block {
   margin-left: 2em ;
-  margin-right: 2em ;
-  background-color: #eeeeee }
+  margin-right: 2em }
 
 span.classifier {
   font-family: sans-serif ;
@@ -230,10 +248,8 @@ span.interpreted {
 span.option {
   white-space: nowrap }
 
- /* 
 span.pre {
   white-space: pre }
-*/
 
 span.problematic {
   color: red }
@@ -243,7 +259,8 @@ span.section-subtitle {
   font-size: 80% }
 
 table.citation {
-  border-left: solid thin gray }
+  border-left: solid 1px gray;
+  margin-left: 1px }
 
 table.docinfo {
   margin: 2em 4em }
@@ -253,7 +270,8 @@ table.docutils {
   margin-bottom: 0.5em }
 
 table.footnote {
-  border-left: solid thin black }
+  border-left: solid 1px black;
+  margin-left: 1px }
 
 table.docutils td, table.docutils th,
 table.docinfo td, table.docinfo th {
@@ -271,8 +289,5 @@ h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
 h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
   font-size: 100% }
 
-tt.docutils {
-  background-color: #eeeeee }
-
 ul.auto-toc {
   list-style-type: none }

+ 5 - 0
desktop/core/ext-py/configobj-4.7.2/docs/docutils.conf

@@ -0,0 +1,5 @@
+[html4css1 writer]
+embed-stylesheet: no
+cloak_email_addresses: yes
+stylesheet: docutils.css
+template: template.tmp

+ 1 - 1
desktop/core/ext-py/configobj/docs/stylesheets/voidspace_docutils.css → desktop/core/ext-py/configobj-4.7.2/docs/docutils.css

@@ -11,7 +11,7 @@ and ``default.css`` revision 3442
 */
 
 @import url(default.css);
-@import url(pysrc.css);
+@import url(pygments.css);
 
 body {
   font-family: Arial, sans-serif;

+ 61 - 0
desktop/core/ext-py/configobj-4.7.2/docs/pygments.css

@@ -0,0 +1,61 @@
+.hll { background-color: #ffffcc }
+.c { color: #408080; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #008000; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.cp { color: #BC7A00 } /* Comment.Preproc */
+.c1 { color: #408080; font-style: italic } /* Comment.Single */
+.cs { color: #408080; font-style: italic } /* Comment.Special */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #808080 } /* Generic.Output */
+.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #008000 } /* Keyword.Pseudo */
+.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #B00040 } /* Keyword.Type */
+.m { color: #666666 } /* Literal.Number */
+.s { color: #BA2121 } /* Literal.String */
+.na { color: #7D9029 } /* Name.Attribute */
+.nb { color: #008000 } /* Name.Builtin */
+.nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.no { color: #880000 } /* Name.Constant */
+.nd { color: #AA22FF } /* Name.Decorator */
+.ni { color: #999999; font-weight: bold } /* Name.Entity */
+.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.nf { color: #0000FF } /* Name.Function */
+.nl { color: #A0A000 } /* Name.Label */
+.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.nt { color: #008000; font-weight: bold } /* Name.Tag */
+.nv { color: #19177C } /* Name.Variable */
+.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #666666 } /* Literal.Number.Float */
+.mh { color: #666666 } /* Literal.Number.Hex */
+.mi { color: #666666 } /* Literal.Number.Integer */
+.mo { color: #666666 } /* Literal.Number.Oct */
+.sb { color: #BA2121 } /* Literal.String.Backtick */
+.sc { color: #BA2121 } /* Literal.String.Char */
+.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #BA2121 } /* Literal.String.Double */
+.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #BA2121 } /* Literal.String.Heredoc */
+.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.sx { color: #008000 } /* Literal.String.Other */
+.sr { color: #BB6688 } /* Literal.String.Regex */
+.s1 { color: #BA2121 } /* Literal.String.Single */
+.ss { color: #19177C } /* Literal.String.Symbol */
+.bp { color: #008000 } /* Name.Builtin.Pseudo */
+.vc { color: #19177C } /* Name.Variable.Class */
+.vg { color: #19177C } /* Name.Variable.Global */
+.vi { color: #19177C } /* Name.Variable.Instance */
+.il { color: #666666 } /* Literal.Number.Integer.Long */

+ 8 - 0
desktop/core/ext-py/configobj-4.7.2/docs/template.tmp

@@ -0,0 +1,8 @@
+%(head_prefix)s
+%(head)s
+%(stylesheet)s
+%(body_prefix)s
+%(body_pre_docinfo)s
+%(docinfo)s
+%(body)s
+%(body_suffix)s

+ 639 - 0
desktop/core/ext-py/configobj-4.7.2/docs/validate.html

@@ -0,0 +1,639 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
+<title>Validation Schema with validate.py</title>
+<meta name="authors" content="Michael Foord  Nicola Larosa  Mark Andrews" />
+<meta name="date" content="2010/01/09" />
+<link rel="stylesheet" href="docutils.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="validation-schema-with-validate-py">
+<h1 class="title">Validation Schema with validate.py</h1>
+<h2 class="subtitle" id="using-the-validator-class">Using the Validator class</h2>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr><th class="docinfo-name">Authors:</th>
+<td>Michael Foord
+<br />Nicola Larosa
+<br />Mark Andrews</td></tr>
+<tr><th class="docinfo-name">Version:</th>
+<td>Validate 1.0.1</td></tr>
+<tr><th class="docinfo-name">Date:</th>
+<td>2010/01/09</td></tr>
+<tr class="field"><th class="docinfo-name">Homepage:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">Validate Homepage</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">Repository:</th><td class="field-body"><a class="reference external" href="http://code.google.com/p/configobj/">Google code homepage</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">PyPI Entry:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/validate">Validate on Python Packaging Index</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">License:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">Support:</th><td class="field-body"><a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a></td>
+</tr>
+</tbody>
+</table>
+<div class="contents topic" id="validate-manual">
+<p class="topic-title first">Validate Manual</p>
+<ul class="auto-toc simple">
+<li><a class="reference internal" href="#introduction" id="id1">1&nbsp;&nbsp;&nbsp;Introduction</a></li>
+<li><a class="reference internal" href="#downloading" id="id2">2&nbsp;&nbsp;&nbsp;Downloading</a><ul class="auto-toc">
+<li><a class="reference internal" href="#files" id="id3">2.1&nbsp;&nbsp;&nbsp;Files</a></li>
+<li><a class="reference internal" href="#documentation" id="id4">2.2&nbsp;&nbsp;&nbsp;Documentation</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#the-standard-functions" id="id5">3&nbsp;&nbsp;&nbsp;The standard functions</a></li>
+<li><a class="reference internal" href="#using-validator" id="id6">4&nbsp;&nbsp;&nbsp;Using Validator</a><ul class="auto-toc">
+<li><a class="reference internal" href="#instantiate" id="id7">4.1&nbsp;&nbsp;&nbsp;Instantiate</a></li>
+<li><a class="reference internal" href="#adding-functions" id="id8">4.2&nbsp;&nbsp;&nbsp;Adding functions</a></li>
+<li><a class="reference internal" href="#writing-the-check" id="id9">4.3&nbsp;&nbsp;&nbsp;Writing the check</a></li>
+<li><a class="reference internal" href="#the-check-method" id="id10">4.4&nbsp;&nbsp;&nbsp;The check method</a><ul class="auto-toc">
+<li><a class="reference internal" href="#default-values" id="id11">4.4.1&nbsp;&nbsp;&nbsp;Default Values</a></li>
+<li><a class="reference internal" href="#list-values" id="id12">4.4.2&nbsp;&nbsp;&nbsp;List Values</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#get-default-value" id="id13">4.5&nbsp;&nbsp;&nbsp;get_default_value</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#validator-exceptions" id="id14">5&nbsp;&nbsp;&nbsp;Validator Exceptions</a></li>
+<li><a class="reference internal" href="#writing-check-functions" id="id15">6&nbsp;&nbsp;&nbsp;Writing check functions</a><ul class="auto-toc">
+<li><a class="reference internal" href="#example" id="id16">6.1&nbsp;&nbsp;&nbsp;Example</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#known-issues" id="id17">7&nbsp;&nbsp;&nbsp;Known Issues</a></li>
+<li><a class="reference internal" href="#todo" id="id18">8&nbsp;&nbsp;&nbsp;TODO</a></li>
+<li><a class="reference internal" href="#issues" id="id19">9&nbsp;&nbsp;&nbsp;ISSUES</a></li>
+<li><a class="reference internal" href="#changelog" id="id20">10&nbsp;&nbsp;&nbsp;CHANGELOG</a><ul class="auto-toc">
+<li><a class="reference internal" href="#version-1-0-1" id="id21">10.1&nbsp;&nbsp;&nbsp;2009/10/25 - Version 1.0.1</a></li>
+<li><a class="reference internal" href="#version-1-0-0" id="id22">10.2&nbsp;&nbsp;&nbsp;2009/04/13 - Version 1.0.0</a></li>
+<li><a class="reference internal" href="#version-0-3-2" id="id23">10.3&nbsp;&nbsp;&nbsp;2008/02/24 - Version 0.3.2</a></li>
+<li><a class="reference internal" href="#version-0-3-1" id="id24">10.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.1</a></li>
+<li><a class="reference internal" href="#version-0-3-0" id="id25">10.5&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.0</a></li>
+<li><a class="reference internal" href="#version-0-2-3" id="id26">10.6&nbsp;&nbsp;&nbsp;2007/02/04      Version 0.2.3</a></li>
+<li><a class="reference internal" href="#version-0-2-3-alpha1" id="id27">10.7&nbsp;&nbsp;&nbsp;2006/12/17      Version 0.2.3-alpha1</a></li>
+<li><a class="reference internal" href="#version-0-2-2" id="id28">10.8&nbsp;&nbsp;&nbsp;2006/04/29      Version 0.2.2</a></li>
+<li><a class="reference internal" href="#version-0-2-1" id="id29">10.9&nbsp;&nbsp;&nbsp;2005/12/16      Version 0.2.1</a></li>
+<li><a class="reference internal" href="#version-0-2-0" id="id30">10.10&nbsp;&nbsp;&nbsp;2005/08/18      Version 0.2.0</a></li>
+<li><a class="reference internal" href="#version-0-1-0" id="id31">10.11&nbsp;&nbsp;&nbsp;2005/02/01      Version 0.1.0</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id1">1&nbsp;&nbsp;&nbsp;Introduction</a></h1>
+<p>Validation is used to check that supplied values conform to a specification.</p>
+<p>The value can be supplied as a string, e.g. from a config file. In this case
+the check will also <em>convert</em> the value to the required type. This allows you
+to add validation as a transparent layer to access data stored as strings. The
+validation checks that the data is correct <em>and</em> converts it to the expected
+type.</p>
+<p>Checks are also strings, and are easy to write. One generic system can be used
+to validate information from different sources via a single consistent
+mechanism.</p>
+<p>Checks look like function calls, and map to function calls. They can include
+parameters and keyword arguments. These arguments are passed to the relevant
+function by the <tt class="docutils literal">Validator</tt> instance, along with the value being checked.</p>
+<p>The syntax for checks also allows for specifying a default value. This default
+value can be <tt class="docutils literal">None</tt>, no matter what the type of the check. This can be used
+to indicate that a value was missing, and so holds no useful value.</p>
+<p>Functions either return a new value, or raise an exception. See <a class="reference internal" href="#validator-exceptions">Validator
+Exceptions</a> for the low down on the exception classes that <tt class="docutils literal">validate.py</tt>
+defines.</p>
+<p>Some standard functions are provided, for basic data types; these come built
+into every validator. Additional checks are easy to write: they can be provided
+when the <tt class="docutils literal">Validator</tt> is instantiated, or added afterwards.</p>
+<p>Validate was primarily written to support <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a>, but is designed to be
+applicable to many other situations.</p>
+<p>For support and bug reports please use the ConfigObj <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
+</div>
+<div class="section" id="downloading">
+<h1><a class="toc-backref" href="#id2">2&nbsp;&nbsp;&nbsp;Downloading</a></h1>
+<p>The current version is <strong>1.0.1</strong>, dated 9th January 2010.</p>
+<p>You can get obtain validate in the following ways :</p>
+<div class="section" id="files">
+<h2><a class="toc-backref" href="#id3">2.1&nbsp;&nbsp;&nbsp;Files</a></h2>
+<ul>
+<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/cgi-bin/voidspace/download/validate.py">validate.py</a> from Voidspace</p>
+</li>
+<li><p class="first">configobj.zip from Voidspace - See the homepage of <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> for the latest
+version and download links.</p>
+<blockquote>
+<p>This contains validate.py and <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a>. (As well as <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> and
+the ConfigObj documentation).</p>
+</blockquote>
+</li>
+<li><p class="first">The latest development version can be obtained from the <a class="reference external" href="http://code.google.com/p/configobj/">Subversion Repository</a>.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="documentation">
+<h2><a class="toc-backref" href="#id4">2.2&nbsp;&nbsp;&nbsp;Documentation</a></h2>
+<p><em>configobj.zip</em> contains <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a>.</p>
+<ul class="simple">
+<li>You can view <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a> online as the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">Validate Homepage</a>.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="the-standard-functions">
+<h1><a class="toc-backref" href="#id5">3&nbsp;&nbsp;&nbsp;The standard functions</a></h1>
+<p>The standard functions come built-in to every <tt class="docutils literal">Validator</tt> instance. They work
+with the following basic data types :</p>
+<ul class="simple">
+<li>integer</li>
+<li>float</li>
+<li>boolean</li>
+<li>string</li>
+<li>ip_addr</li>
+</ul>
+<p>plus lists of these datatypes.</p>
+<p>Adding additional checks is done through coding simple functions.</p>
+<p>The full set of standard checks are :</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">'integer':</th><td class="field-body"><p class="first">matches integer values (including negative). Takes optional 'min'
+and 'max' arguments:</p>
+<pre class="literal-block">
+integer()
+integer(3, 9)    # any value from 3 to 9
+integer(min=0) # any positive value
+integer(max=9)
+</pre>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'float':</th><td class="field-body"><p class="first">matches float values
+Has the same parameters as the integer check.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'boolean':</th><td class="field-body"><dl class="first docutils">
+<dt>matches boolean values: <tt class="docutils literal">True</tt> or <tt class="docutils literal">False</tt>.</dt>
+<dd><p class="first">Acceptable string values for True are:</p>
+<pre class="last literal-block">
+true, on, yes, 1
+</pre>
+</dd>
+</dl>
+<p>Acceptable string values for False are:</p>
+<pre class="literal-block">
+false, off, no, 0
+</pre>
+<p>Any other value raises an error.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'string':</th><td class="field-body"><p class="first">matches any string. Takes optional keyword args 'min' and 'max' to
+specify min and max length of string.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'ip_addr':</th><td class="field-body"><p class="first">matches an Internet Protocol address, v.4, represented by a
+dotted-quad string, i.e. '1.2.3.4'.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'list':</th><td class="field-body"><p class="first">matches any list. Takes optional keyword args 'min', and 'max' to
+specify min and max sizes of the list. The list checks always
+return a list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">force_list:</th><td class="field-body"><p class="first">matches any list, but if a single value is passed in will
+coerce it into a list containing that value. Useful for
+configobj if the user forgot the trailing comma to turn
+a single value into a list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'tuple':</th><td class="field-body"><p class="first">matches any list. This check returns a tuple rather than a list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'int_list':</th><td class="field-body"><p class="first">Matches a list of integers. Takes the same arguments as list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'float_list':</th><td class="field-body"><p class="first">Matches a list of floats. Takes the same arguments as list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'bool_list':</th><td class="field-body"><p class="first">Matches a list of boolean values. Takes the same arguments as
+list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'string_list':</th><td class="field-body"><p class="first">Matches a list of strings. Takes the same arguments as list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'ip_addr_list':</th><td class="field-body"><p class="first">Matches a list of IP addresses. Takes the same arguments as
+list.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'mixed_list':</th><td class="field-body"><p class="first">Matches a list with different types in specific positions.
+List size must match the number of arguments.</p>
+<p>Each position can be one of:</p>
+<pre class="literal-block">
+int, str, boolean, float, ip_addr
+</pre>
+<p>So to specify a list with two strings followed by two integers,
+you write the check as:</p>
+<pre class="literal-block">
+mixed_list(str, str, int, int)
+</pre>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'pass':</th><td class="field-body"><p class="first">matches everything: it never fails and the value is unchanged. It is
+also the default if no check is specified.</p>
+</td>
+</tr>
+<tr class="field"><th class="field-name">'option':</th><td class="field-body"><p class="first">matches any from a list of options.
+You specify this test with:</p>
+<pre class="last literal-block">
+option('option 1', 'option 2', 'option 3')
+</pre>
+</td>
+</tr>
+</tbody>
+</table>
+<p>The following code will work without you having to specifically add the
+functions yourself.</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="c">#</span>
+<span class="n">vtor</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+<span class="n">newval1</span> <span class="o">=</span> <span class="n">vtor</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="s">&#39;integer&#39;</span><span class="p">,</span> <span class="n">value1</span><span class="p">)</span>
+<span class="n">newval2</span> <span class="o">=</span> <span class="n">vtor</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="s">&#39;boolean&#39;</span><span class="p">,</span> <span class="n">value2</span><span class="p">)</span>
+<span class="c"># etc ...</span>
+</pre></div>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Of course, if these checks fail they raise exceptions. So you should wrap
+them in <tt class="docutils literal"><span class="pre">try...except</span></tt> blocks. Better still,  use ConfigObj for a higher
+level interface.</p>
+</div>
+</div>
+<div class="section" id="using-validator">
+<h1><a class="toc-backref" href="#id6">4&nbsp;&nbsp;&nbsp;Using Validator</a></h1>
+<p>Using <tt class="docutils literal">Validator</tt> is very easy. It has one public attribute and one public
+method.</p>
+<p>Shown below are the different steps in using <tt class="docutils literal">Validator</tt>.</p>
+<p>The only additional thing you need to know, is about <a class="reference internal" href="#writing-check-functions">Writing check
+functions</a>.</p>
+<div class="section" id="instantiate">
+<h2><a class="toc-backref" href="#id7">4.1&nbsp;&nbsp;&nbsp;Instantiate</a></h2>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="n">vtor</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+</pre></div>
+<p>or even :</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="c">#</span>
+<span class="n">fdict</span> <span class="o">=</span> <span class="p">{</span>
+    <span class="s">&#39;check_name1&#39;</span><span class="p">:</span> <span class="n">function1</span><span class="p">,</span>
+    <span class="s">&#39;check_name2&#39;</span><span class="p">:</span> <span class="n">function2</span><span class="p">,</span>
+    <span class="s">&#39;check_name3&#39;</span><span class="p">:</span> <span class="n">function3</span><span class="p">,</span>
+<span class="p">}</span>
+<span class="c">#</span>
+<span class="n">vtor</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">(</span><span class="n">fdict</span><span class="p">)</span>
+</pre></div>
+<p>The second method adds a set of your functions as soon as your validator is
+created. They are stored in the <tt class="docutils literal">vtor.functions</tt> dictionary. The 'key' you
+give them in this dictionary is the name you use in your checks (not the
+original function name).</p>
+<p>Dictionary keys/functions you pass in can override the built-in ones if you
+want.</p>
+</div>
+<div class="section" id="adding-functions">
+<h2><a class="toc-backref" href="#id8">4.2&nbsp;&nbsp;&nbsp;Adding functions</a></h2>
+<p>The code shown above, for adding functions on instantiation, has exactly the
+same effect as the following code :</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span>
+<span class="c">#</span>
+<span class="n">vtor</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+<span class="n">vtor</span><span class="o">.</span><span class="n">functions</span><span class="p">[</span><span class="s">&#39;check_name1&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">function1</span>
+<span class="n">vtor</span><span class="o">.</span><span class="n">functions</span><span class="p">[</span><span class="s">&#39;check_name2&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">function2</span>
+<span class="n">vtor</span><span class="o">.</span><span class="n">functions</span><span class="p">[</span><span class="s">&#39;check_name3&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">function3</span>
+</pre></div>
+<p><tt class="docutils literal">vtor.functions</tt> is just a dictionary that maps names to functions, so we
+could also have called <tt class="docutils literal">vtor.functions.update(fdict)</tt>.</p>
+</div>
+<div class="section" id="writing-the-check">
+<h2><a class="toc-backref" href="#id9">4.3&nbsp;&nbsp;&nbsp;Writing the check</a></h2>
+<p>As we've heard, the checks map to the names in the <tt class="docutils literal">functions</tt> dictionary.
+You've got a full list of <a class="reference internal" href="#the-standard-functions">The standard functions</a> and the arguments they
+take.</p>
+<p>If you're using <tt class="docutils literal">Validator</tt> from ConfigObj, then your checks will look like:</p>
+<pre class="literal-block">
+keyword = int_list(max=6)
+</pre>
+<p>but the check part will be identical .</p>
+</div>
+<div class="section" id="the-check-method">
+<h2><a class="toc-backref" href="#id10">4.4&nbsp;&nbsp;&nbsp;The check method</a></h2>
+<p>If you're not using <tt class="docutils literal">Validator</tt> from ConfigObj, then you'll need to call the
+<tt class="docutils literal">check</tt> method yourself.</p>
+<p>If the check fails then it will raise an exception, so you'll want to trap
+that. Here's the basic example :</p>
+<div class="highlight"><pre><span class="kn">from</span> <span class="nn">validate</span> <span class="kn">import</span> <span class="n">Validator</span><span class="p">,</span> <span class="n">ValidateError</span>
+<span class="c">#</span>
+<span class="n">vtor</span> <span class="o">=</span> <span class="n">Validator</span><span class="p">()</span>
+<span class="n">check</span> <span class="o">=</span> <span class="s">&quot;integer(0, 9)&quot;</span>
+<span class="n">value</span> <span class="o">=</span> <span class="mi">3</span>
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">newvalue</span> <span class="o">=</span> <span class="n">vtor</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">check</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
+<span class="k">except</span> <span class="n">ValidateError</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;Check Failed.&#39;</span>
+<span class="k">else</span><span class="p">:</span>
+    <span class="k">print</span> <span class="s">&#39;Check passed.&#39;</span>
+</pre></div>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p class="last">Although the value can be a string, if it represents a list it should
+already have been turned into a list of strings.</p>
+</div>
+<div class="section" id="default-values">
+<h3><a class="toc-backref" href="#id11">4.4.1&nbsp;&nbsp;&nbsp;Default Values</a></h3>
+<p>Some values may not be available, and you may want to be able to specify a
+default as part of the check.</p>
+<p>You do this by passing the keyword <tt class="docutils literal">missing=True</tt> to the <tt class="docutils literal">check</tt> method, as
+well as a <tt class="docutils literal">default=value</tt> in the check. (Constructing these checks is done
+automatically by ConfigObj: you only need to know about the <tt class="docutils literal">default=value</tt>
+part) :</p>
+<div class="highlight"><pre><span class="n">check1</span> <span class="o">=</span> <span class="s">&#39;integer(default=50)&#39;</span>
+<span class="n">check2</span> <span class="o">=</span> <span class="s">&#39;option(&quot;val 1&quot;, &quot;val 2&quot;, &quot;val 3&quot;, default=&quot;val 1&quot;)&#39;</span>
+
+<span class="k">assert</span> <span class="n">vtor</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">check1</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">missing</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="o">==</span> <span class="mi">50</span>
+<span class="k">assert</span> <span class="n">vtor</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">check2</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">missing</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="o">==</span> <span class="s">&quot;val 1&quot;</span>
+</pre></div>
+<p>If you pass in <tt class="docutils literal">missing=True</tt> to the check method, then the actual value is
+ignored. If no default is specified in the check, a <tt class="docutils literal">ValidateMissingValue</tt>
+exception is raised. If a default is specified then that is passed to the
+check instead.</p>
+<p>If the check has <tt class="docutils literal">default=None</tt> (case sensitive) then <tt class="docutils literal">vtor.check</tt> will
+<em>always</em> return <tt class="docutils literal">None</tt> (the object). This makes it easy to tell your program
+that this check contains no useful value when missing, i.e. the value is
+optional, and may be omitted without harm.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">As of version 0.3.0, if you specify <tt class="docutils literal"><span class="pre">default='None'</span></tt> (note the quote marks
+around <tt class="docutils literal">None</tt>) then it will be interpreted as the string <tt class="docutils literal">'None'</tt>.</p>
+</div>
+</div>
+<div class="section" id="list-values">
+<h3><a class="toc-backref" href="#id12">4.4.2&nbsp;&nbsp;&nbsp;List Values</a></h3>
+<p>It's possible that you would like your default value to be a list. It's even
+possible that you will write your own check functions - and would like to pass
+them keyword arguments as lists from within the check.</p>
+<p>To avoid confusing syntax with commas and quotes you use a list constructor to
+specify that keyword arguments are lists. This includes the <tt class="docutils literal">default</tt> value.
+This makes checks look something like:</p>
+<pre class="literal-block">
+checkname(default=list('val1', 'val2', 'val3'))
+</pre>
+</div>
+</div>
+<div class="section" id="get-default-value">
+<h2><a class="toc-backref" href="#id13">4.5&nbsp;&nbsp;&nbsp;get_default_value</a></h2>
+<p><tt class="docutils literal">Validator</tt> instances have a <tt class="docutils literal">get_default_value</tt> method. It takes a <tt class="docutils literal">check</tt> string
+(the same string you would pass to the <tt class="docutils literal">check</tt> method) and returns the default value,
+converted to the right type. If the check doesn't define a default value then this method
+raises a <tt class="docutils literal">KeyError</tt>.</p>
+<p>If the <tt class="docutils literal">check</tt> has been seen before then it will have been parsed and cached already,
+so this method is not expensive to call (however the conversion is done each time).</p>
+</div>
+</div>
+<div class="section" id="validator-exceptions">
+<h1><a class="toc-backref" href="#id14">5&nbsp;&nbsp;&nbsp;Validator Exceptions</a></h1>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">If you only use Validator through ConfigObj, it traps these Exceptions for
+you. You will still need to know about them for writing your own check
+functions.</p>
+</div>
+<p><tt class="docutils literal">vtor.check</tt> indicates that the check has failed by raising an exception.
+The appropriate error should be raised in the check function.</p>
+<p>The base error class is <tt class="docutils literal">ValidateError</tt>. All errors (except for <tt class="docutils literal">VdtParamError</tt>)
+raised are sub-classes of this.</p>
+<p>If an unrecognised check is specified then <tt class="docutils literal">VdtUnknownCheckError</tt> is
+raised.</p>
+<p>There are also <tt class="docutils literal">VdtTypeError</tt> and <tt class="docutils literal">VdtValueError</tt>.</p>
+<p>If incorrect parameters are passed to a check function then it will (or should)
+raise <tt class="docutils literal">VdtParamError</tt>. As this indicates <em>programmer</em> error, rather than an error
+in the value, it is a subclass of <tt class="docutils literal">SyntaxError</tt> instead of <tt class="docutils literal">ValidateError</tt>.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">This means it <em>won't</em> be caught by ConfigObj - but propagated instead.</p>
+</div>
+<p>If the value supplied is the wrong type, then the check should raise
+<tt class="docutils literal">VdtTypeError</tt>. e.g. the check requires the value to be an integer (or
+representation of an integer) and something else was supplied.</p>
+<p>If the value supplied is the right type, but an unacceptable value, then the
+check should raise <tt class="docutils literal">VdtValueError</tt>. e.g. the check requires the value to
+be an integer (or representation of an integer) less than ten and a higher
+value was supplied.</p>
+<p>Both <tt class="docutils literal">VdtTypeError</tt> and <tt class="docutils literal">VdtValueError</tt> are initialised with the
+incorrect value. In other words you raise them like this :</p>
+<div class="highlight"><pre><span class="k">raise</span> <span class="n">VdtTypeError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+<span class="c">#</span>
+<span class="k">raise</span> <span class="n">VdtValueError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+</pre></div>
+<p><tt class="docutils literal">VdtValueError</tt> has the following subclasses, which should be raised if
+they are more appropriate.</p>
+<ul class="simple">
+<li><tt class="docutils literal">VdtValueTooSmallError</tt></li>
+<li><tt class="docutils literal">VdtValueTooBigError</tt></li>
+<li><tt class="docutils literal">VdtValueTooShortError</tt></li>
+<li><tt class="docutils literal">VdtValueTooLongError</tt></li>
+</ul>
+</div>
+<div class="section" id="writing-check-functions">
+<h1><a class="toc-backref" href="#id15">6&nbsp;&nbsp;&nbsp;Writing check functions</a></h1>
+<p>Writing check functions is easy.</p>
+<p>The check function will receive the value as its first argument, followed by
+any other parameters and keyword arguments.</p>
+<p>If the check fails, it should raise a <tt class="docutils literal">VdtTypeError</tt> or a
+<tt class="docutils literal">VdtValueError</tt> (or an appropriate subclass).</p>
+<p>All parameters and keyword arguments are <em>always</em> passed as strings. (Parsed
+from the check string).</p>
+<p>The value might be a string (or list of strings) and need
+converting to the right type - alternatively it might already be a list of
+integers. Our function needs to be able to handle either.</p>
+<p>If the check passes then it should return the value (possibly converted to the
+right type).</p>
+<p>And that's it !</p>
+<div class="section" id="example">
+<h2><a class="toc-backref" href="#id16">6.1&nbsp;&nbsp;&nbsp;Example</a></h2>
+<p>Here is an example function that requires a list of integers. Each integer
+must be between 0 and 99.</p>
+<p>It takes a single argument specifying the length of the list. (Which allows us
+to use the same check in more than one place). If the length can't be converted
+to an integer then we need to raise <tt class="docutils literal">VdtParamError</tt>.</p>
+<p>Next we check that the value is a list. Anything else should raise a
+<tt class="docutils literal">VdtTypeError</tt>. The list should also have 'length' entries. If the list
+has more or less entries then we will need to raise a
+<tt class="docutils literal">VdtValueTooShortError</tt> or a <tt class="docutils literal">VdtValueTooLongError</tt>.</p>
+<p>Then we need to check every entry in the list. Each entry should be an integer
+between 0 and 99, or a string representation of an integer between 0 and 99.
+Any other type is a <tt class="docutils literal">VdtTypeError</tt>, any other value is a
+<tt class="docutils literal">VdtValueError</tt> (either too big, or too small).</p>
+<div class="highlight"><pre><span class="k">def</span> <span class="nf">special_list</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">length</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;</span>
+<span class="sd">    Check that the supplied value is a list of integers,</span>
+<span class="sd">    with &#39;length&#39; entries, and each entry between 0 and 99.</span>
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="c"># length is supplied as a string</span>
+    <span class="c"># we need to convert it to an integer</span>
+    <span class="k">try</span><span class="p">:</span>
+        <span class="n">length</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
+    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
+        <span class="k">raise</span> <span class="n">VdtParamError</span><span class="p">(</span><span class="s">&#39;length&#39;</span><span class="p">,</span> <span class="n">length</span><span class="p">)</span>
+    <span class="c">#</span>
+    <span class="c"># Check the supplied value is a list</span>
+    <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
+        <span class="k">raise</span> <span class="n">VdtTypeError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+    <span class="c">#</span>
+    <span class="c"># check the length of the list is correct</span>
+    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">length</span><span class="p">:</span>
+        <span class="k">raise</span> <span class="n">VdtValueTooLongError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+    <span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">length</span><span class="p">:</span>
+        <span class="k">raise</span> <span class="n">VdtValueTooShortError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+    <span class="c">#</span>
+    <span class="c"># Next, check every member in the list</span>
+    <span class="c"># converting strings as necessary</span>
+    <span class="n">out</span> <span class="o">=</span> <span class="p">[]</span>
+    <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">,</span> <span class="nb">int</span><span class="p">)):</span>
+            <span class="c"># a value in the list</span>
+            <span class="c"># is neither an integer nor a string</span>
+            <span class="k">raise</span> <span class="n">VdtTypeError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">)):</span>
+            <span class="k">if</span> <span class="ow">not</span> <span class="n">entry</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span>
+                <span class="k">raise</span> <span class="n">VdtTypeError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="n">entry</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">entry</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
+            <span class="k">raise</span> <span class="n">VdtValueTooSmallError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+        <span class="k">elif</span> <span class="n">entry</span> <span class="o">&gt;</span> <span class="mi">99</span><span class="p">:</span>
+            <span class="k">raise</span> <span class="n">VdtValueTooBigError</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
+        <span class="n">out</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
+    <span class="c">#</span>
+    <span class="c"># if we got this far, all is well</span>
+    <span class="c"># return the new list</span>
+    <span class="k">return</span> <span class="n">out</span>
+</pre></div>
+<p>If you are only using validate from ConfigObj then the error type (<em>TooBig</em>,
+<em>TooSmall</em>, etc) is lost - so you may only want to raise <tt class="docutils literal">VdtValueError</tt>.</p>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p>If your function raises an exception that isn't a subclass of
+<tt class="docutils literal">ValidateError</tt>, then ConfigObj won't trap it. This means validation will
+fail.</p>
+<p class="last">This is why our function starts by checking the type of the value. If we
+are passed the wrong type (e.g. an integer rather than a list) we get a
+<tt class="docutils literal">VdtTypeError</tt> rather than bombing out when we try to iterate over
+the value.</p>
+</div>
+<p>If you are using validate in another circumstance you may want to create your
+own subclasses of <tt class="docutils literal">ValidateError</tt> which convey more specific information.</p>
+</div>
+</div>
+<div class="section" id="known-issues">
+<h1><a class="toc-backref" href="#id17">7&nbsp;&nbsp;&nbsp;Known Issues</a></h1>
+<p>The following parses and then blows up. The resulting error message
+is confusing:</p>
+<blockquote>
+<tt class="docutils literal">checkname(default=list(1, 2, 3, 4)</tt></blockquote>
+<p>This is because it parses as: <tt class="docutils literal"><span class="pre">checkname(default=&quot;list(1&quot;,</span> 2, 3, 4)</tt>.
+That isn't actually unreasonable, but the error message won't help you
+work out what has happened.</p>
+</div>
+<div class="section" id="todo">
+<h1><a class="toc-backref" href="#id18">8&nbsp;&nbsp;&nbsp;TODO</a></h1>
+<ul class="simple">
+<li>A regex check function ?</li>
+<li>A timestamp check function ? (Using the <tt class="docutils literal">parse</tt> function from <tt class="docutils literal">DateUtil</tt> perhaps).</li>
+</ul>
+</div>
+<div class="section" id="issues">
+<h1><a class="toc-backref" href="#id19">9&nbsp;&nbsp;&nbsp;ISSUES</a></h1>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Please file any bug reports to <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a> or the ConfigObj
+<a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
+</div>
+<p>If we could pull tuples out of arguments, it would be easier
+to specify arguments for 'mixed_lists'.</p>
+</div>
+<div class="section" id="changelog">
+<h1><a class="toc-backref" href="#id20">10&nbsp;&nbsp;&nbsp;CHANGELOG</a></h1>
+<div class="section" id="version-1-0-1">
+<h2><a class="toc-backref" href="#id21">10.1&nbsp;&nbsp;&nbsp;2009/10/25 - Version 1.0.1</a></h2>
+<ul class="simple">
+<li>BUGFIX: Fixed compatibility with Python 2.3.</li>
+</ul>
+</div>
+<div class="section" id="version-1-0-0">
+<h2><a class="toc-backref" href="#id22">10.2&nbsp;&nbsp;&nbsp;2009/04/13 - Version 1.0.0</a></h2>
+<ul class="simple">
+<li>BUGFIX: can now handle multiline strings.</li>
+<li>Addition of 'force_list' validation option.</li>
+</ul>
+<p>As the API is stable and there are no known bugs or outstanding feature requests I am marking this 1.0.</p>
+</div>
+<div class="section" id="version-0-3-2">
+<h2><a class="toc-backref" href="#id23">10.3&nbsp;&nbsp;&nbsp;2008/02/24 - Version 0.3.2</a></h2>
+<p>BUGFIX: Handling of None as default value fixed.</p>
+</div>
+<div class="section" id="version-0-3-1">
+<h2><a class="toc-backref" href="#id24">10.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.1</a></h2>
+<p>BUGFIX: Unicode checks no longer broken.</p>
+</div>
+<div class="section" id="version-0-3-0">
+<h2><a class="toc-backref" href="#id25">10.5&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.0</a></h2>
+<p>Improved performance with a parse cache.</p>
+<p>New <tt class="docutils literal">get_default_value</tt> method. Given a check it returns the default
+value (converted to the correct type) or raises a <tt class="docutils literal">KeyError</tt> if the
+check doesn't specify a default.</p>
+<p>Added 'tuple' check and corresponding 'is_tuple' function (which always returns a tuple).</p>
+<p>BUGFIX: A quoted 'None' as a default value is no longer treated as None,
+but as the string 'None'.</p>
+<p>BUGFIX: We weren't unquoting keyword arguments of length two, so an
+empty string didn't work as a default.</p>
+<p>BUGFIX: Strings no longer pass the 'is_list' check. Additionally, the
+list checks always return lists.</p>
+<p>A couple of documentation bug fixes.</p>
+<p>Removed CHANGELOG from module.</p>
+</div>
+<div class="section" id="version-0-2-3">
+<h2><a class="toc-backref" href="#id26">10.6&nbsp;&nbsp;&nbsp;2007/02/04      Version 0.2.3</a></h2>
+<p>Release of 0.2.3</p>
+</div>
+<div class="section" id="version-0-2-3-alpha1">
+<h2><a class="toc-backref" href="#id27">10.7&nbsp;&nbsp;&nbsp;2006/12/17      Version 0.2.3-alpha1</a></h2>
+<p>By Nicola Larosa</p>
+<p>Fixed validate doc to talk of <tt class="docutils literal">boolean</tt> instead of <tt class="docutils literal">bool</tt>; changed the
+<tt class="docutils literal">is_bool</tt> function to <tt class="docutils literal">is_boolean</tt> (Sourceforge bug #1531525).</p>
+</div>
+<div class="section" id="version-0-2-2">
+<h2><a class="toc-backref" href="#id28">10.8&nbsp;&nbsp;&nbsp;2006/04/29      Version 0.2.2</a></h2>
+<p>Addressed bug where a string would pass the <tt class="docutils literal">is_list</tt> test. (Thanks to
+Konrad Wojas.)</p>
+</div>
+<div class="section" id="version-0-2-1">
+<h2><a class="toc-backref" href="#id29">10.9&nbsp;&nbsp;&nbsp;2005/12/16      Version 0.2.1</a></h2>
+<p>Fixed bug so we can handle keyword argument values with commas.</p>
+<p>We now use a list constructor for passing list values to keyword arguments
+(including <tt class="docutils literal">default</tt>):</p>
+<pre class="literal-block">
+default=list(&quot;val&quot;, &quot;val&quot;, &quot;val&quot;)
+</pre>
+<p>Added the <tt class="docutils literal">_test</tt> test.</p>
+<p>Moved a function call outside a try...except block.</p>
+</div>
+<div class="section" id="version-0-2-0">
+<h2><a class="toc-backref" href="#id30">10.10&nbsp;&nbsp;&nbsp;2005/08/18      Version 0.2.0</a></h2>
+<p>Updated by <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a> and <a class="reference external" href="mailto:nico&#37;&#52;&#48;teknico&#46;net">Nicola Larosa</a></p>
+<p>Does type conversion as well.</p>
+</div>
+<div class="section" id="version-0-1-0">
+<h2><a class="toc-backref" href="#id31">10.11&nbsp;&nbsp;&nbsp;2005/02/01      Version 0.1.0</a></h2>
+<p>Initial version developed by <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a>
+and Mark Andrews.</p>
+</div>
+</div>
+</div>
+</body>
+</html>

+ 686 - 0
desktop/core/ext-py/configobj-4.7.2/docs/validate.txt

@@ -0,0 +1,686 @@
+===================================
+ Validation Schema with validate.py
+===================================
+--------------------------
+ Using the Validator class
+--------------------------
+
+
+:Authors: `Michael Foord`_, `Nicola Larosa`_, `Mark Andrews`_
+:Version: Validate 1.0.1
+:Date: 2010/01/09
+:Homepage: `Validate Homepage`_
+:Repository: `Google code homepage <http://code.google.com/p/configobj/>`_
+:PyPI Entry: `Validate on Python Packaging Index <http://pypi.python.org/pypi/validate>`_
+:License: `BSD License`_
+:Support: `Mailing List`_
+
+.. _Mailing List: http://lists.sourceforge.net/lists/listinfo/configobj-develop
+.. _Michael Foord: fuzzyman@voidspace.org.uk
+.. _Nicola Larosa: nico@teknico.net
+.. _This Document:
+.. _Validate Homepage: http://www.voidspace.org.uk/python/validate.html
+.. _BSD License: http://www.voidspace.org.uk/python/license.shtml
+
+
+.. contents:: Validate Manual
+.. sectnum::
+
+
+Introduction
+============
+
+Validation is used to check that supplied values conform to a specification.
+
+The value can be supplied as a string, e.g. from a config file. In this case
+the check will also *convert* the value to the required type. This allows you
+to add validation as a transparent layer to access data stored as strings. The
+validation checks that the data is correct *and* converts it to the expected
+type.
+
+Checks are also strings, and are easy to write. One generic system can be used
+to validate information from different sources via a single consistent
+mechanism.
+
+Checks look like function calls, and map to function calls. They can include
+parameters and keyword arguments. These arguments are passed to the relevant
+function by the ``Validator`` instance, along with the value being checked.
+
+The syntax for checks also allows for specifying a default value. This default
+value can be ``None``, no matter what the type of the check. This can be used
+to indicate that a value was missing, and so holds no useful value.
+
+Functions either return a new value, or raise an exception. See `Validator
+Exceptions`_ for the low down on the exception classes that ``validate.py``
+defines.
+
+Some standard functions are provided, for basic data types; these come built
+into every validator. Additional checks are easy to write: they can be provided
+when the ``Validator`` is instantiated, or added afterwards.
+
+Validate was primarily written to support ConfigObj_, but is designed to be 
+applicable to many other situations.
+
+For support and bug reports please use the ConfigObj `Mailing List`_.
+
+.. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html
+
+
+Downloading
+===========
+
+The current version is **1.0.1**, dated 9th January 2010. 
+
+You can get obtain validate in the following ways :
+
+
+Files
+-----
+
+* validate.py_ from Voidspace
+
+* configobj.zip from Voidspace - See the homepage of ConfigObj_ for the latest 
+  version and download links.
+
+    This contains validate.py and `this document`_. (As well as ConfigObj_ and 
+    the ConfigObj documentation).
+    
+* The latest development version can be obtained from the `Subversion Repository`_.
+
+
+Documentation
+-------------
+
+*configobj.zip* contains `this document`_.
+
+* You can view `this document`_ online as the `Validate Homepage`_.
+
+.. _configobj.py: http://www.voidspace.org.uk/cgi-bin/voidspace/download/configobj.py
+.. _configobj.zip: http://www.voidspace.org.uk/cgi-bin/voidspace/download/configobj-4.7.0.zip
+.. _validate.py: http://www.voidspace.org.uk/cgi-bin/voidspace/download/validate.py
+.. _Subversion Repository: http://code.google.com/p/configobj/
+.. _Sourceforge: http://sourceforge.net/projects/configobj
+.. _validate: http://www.voidspace.org.uk/python/validate.html
+
+
+The standard functions
+======================
+
+The standard functions come built-in to every ``Validator`` instance. They work
+with the following basic data types :
+
+* integer
+* float
+* boolean
+* string
+* ip_addr
+
+plus lists of these datatypes.
+
+Adding additional checks is done through coding simple functions.
+
+The full set of standard checks are :
+
+:'integer': matches integer values (including negative). Takes optional 'min'
+            and 'max' arguments::
+
+                integer()
+                integer(3, 9)    # any value from 3 to 9
+                integer(min=0) # any positive value
+                integer(max=9)
+
+:'float': matches float values
+          Has the same parameters as the integer check.
+
+:'boolean': matches boolean values: ``True`` or ``False``.
+            Acceptable string values for True are::
+
+             true, on, yes, 1
+
+         Acceptable string values for False are::
+
+             false, off, no, 0
+
+         Any other value raises an error.
+
+:'string': matches any string. Takes optional keyword args 'min' and 'max' to
+           specify min and max length of string.
+
+:'ip_addr': matches an Internet Protocol address, v.4, represented by a
+            dotted-quad string, i.e. '1.2.3.4'.
+
+:'list': matches any list. Takes optional keyword args 'min', and 'max' to
+         specify min and max sizes of the list. The list checks always 
+         return a list.
+         
+:force_list: matches any list, but if a single value is passed in will
+             coerce it into a list containing that value. Useful for
+             configobj if the user forgot the trailing comma to turn
+             a single value into a list.
+         
+:'tuple': matches any list. This check returns a tuple rather than a list.
+
+:'int_list': Matches a list of integers. Takes the same arguments as list.
+
+:'float_list': Matches a list of floats. Takes the same arguments as list.
+
+:'bool_list': Matches a list of boolean values. Takes the same arguments as
+              list.
+
+:'string_list': Matches a list of strings. Takes the same arguments as list.
+
+:'ip_addr_list': Matches a list of IP addresses. Takes the same arguments as
+                 list.
+
+:'mixed_list': Matches a list with different types in specific positions.
+               List size must match the number of arguments.
+
+               Each position can be one of::
+
+                   int, str, boolean, float, ip_addr
+
+               So to specify a list with two strings followed by two integers,
+               you write the check as::
+
+                   mixed_list(str, str, int, int)
+
+:'pass': matches everything: it never fails and the value is unchanged. It is
+         also the default if no check is specified.
+
+:'option': matches any from a list of options.
+           You specify this test with::
+
+               option('option 1', 'option 2', 'option 3')
+
+The following code will work without you having to specifically add the
+functions yourself.
+
+.. code-block:: python
+
+    from validate import Validator
+    #
+    vtor = Validator()
+    newval1 = vtor.check('integer', value1)
+    newval2 = vtor.check('boolean', value2)
+    # etc ...
+
+.. note::
+
+    Of course, if these checks fail they raise exceptions. So you should wrap
+    them in ``try...except`` blocks. Better still,  use ConfigObj for a higher
+    level interface.
+
+
+Using Validator
+===============
+
+Using ``Validator`` is very easy. It has one public attribute and one public
+method.
+
+Shown below are the different steps in using ``Validator``.
+
+The only additional thing you need to know, is about `Writing check
+functions`_.
+
+Instantiate
+-----------
+
+.. code-block:: python
+
+    from validate import Validator
+    vtor = Validator()
+
+or even :
+
+.. code-block:: python
+
+    from validate import Validator
+    #
+    fdict = {
+        'check_name1': function1,
+        'check_name2': function2,
+        'check_name3': function3,
+    }
+    #
+    vtor = Validator(fdict)
+
+
+The second method adds a set of your functions as soon as your validator is
+created. They are stored in the ``vtor.functions`` dictionary. The 'key' you
+give them in this dictionary is the name you use in your checks (not the
+original function name).
+
+Dictionary keys/functions you pass in can override the built-in ones if you
+want.
+
+
+Adding functions
+----------------
+
+The code shown above, for adding functions on instantiation, has exactly the
+same effect as the following code :
+
+.. code-block:: python
+
+    from validate import Validator
+    #
+    vtor = Validator()
+    vtor.functions['check_name1'] = function1
+    vtor.functions['check_name2'] = function2
+    vtor.functions['check_name3'] = function3
+
+``vtor.functions`` is just a dictionary that maps names to functions, so we
+could also have called ``vtor.functions.update(fdict)``.
+
+
+Writing the check
+-----------------
+
+As we've heard, the checks map to the names in the ``functions`` dictionary.
+You've got a full list of `The standard functions`_ and the arguments they
+take.
+
+If you're using ``Validator`` from ConfigObj, then your checks will look like::
+
+    keyword = int_list(max=6)
+
+but the check part will be identical .
+
+
+The check method
+----------------
+
+If you're not using ``Validator`` from ConfigObj, then you'll need to call the
+``check`` method yourself.
+
+If the check fails then it will raise an exception, so you'll want to trap
+that. Here's the basic example :
+
+.. code-block:: python
+
+    from validate import Validator, ValidateError
+    #
+    vtor = Validator()
+    check = "integer(0, 9)"
+    value = 3
+    try:
+        newvalue = vtor.check(check, value)
+    except ValidateError:
+        print 'Check Failed.'
+    else:
+        print 'Check passed.'
+
+
+.. caution::
+
+    Although the value can be a string, if it represents a list it should
+    already have been turned into a list of strings.
+
+
+Default Values
+~~~~~~~~~~~~~~
+
+Some values may not be available, and you may want to be able to specify a
+default as part of the check.
+
+You do this by passing the keyword ``missing=True`` to the ``check`` method, as
+well as a ``default=value`` in the check. (Constructing these checks is done
+automatically by ConfigObj: you only need to know about the ``default=value``
+part) :
+
+.. code-block:: python
+
+    check1 = 'integer(default=50)'
+    check2 = 'option("val 1", "val 2", "val 3", default="val 1")'
+
+    assert vtor.check(check1, '', missing=True) == 50
+    assert vtor.check(check2, '', missing=True) == "val 1"
+
+
+If you pass in ``missing=True`` to the check method, then the actual value is
+ignored. If no default is specified in the check, a ``ValidateMissingValue``
+exception is raised. If a default is specified then that is passed to the
+check instead.
+
+If the check has ``default=None`` (case sensitive) then ``vtor.check`` will
+*always* return ``None`` (the object). This makes it easy to tell your program
+that this check contains no useful value when missing, i.e. the value is
+optional, and may be omitted without harm.
+
+
+.. note:: 
+
+    As of version 0.3.0, if you specify ``default='None'`` (note the quote marks
+    around ``None``) then it will be interpreted as the string ``'None'``.
+
+
+List Values
+~~~~~~~~~~~
+
+It's possible that you would like your default value to be a list. It's even
+possible that you will write your own check functions - and would like to pass
+them keyword arguments as lists from within the check.
+
+To avoid confusing syntax with commas and quotes you use a list constructor to
+specify that keyword arguments are lists. This includes the ``default`` value.
+This makes checks look something like::
+
+    checkname(default=list('val1', 'val2', 'val3'))
+
+
+get_default_value
+-----------------
+
+``Validator`` instances have a ``get_default_value`` method. It takes a ``check`` string 
+(the same string you would pass to the ``check`` method) and returns the default value,
+converted to the right type. If the check doesn't define a default value then this method
+raises a ``KeyError``.
+
+If the ``check`` has been seen before then it will have been parsed and cached already, 
+so this method is not expensive to call (however the conversion is done each time).
+
+
+
+Validator Exceptions
+====================
+
+.. note::
+
+    If you only use Validator through ConfigObj, it traps these Exceptions for
+    you. You will still need to know about them for writing your own check
+    functions.
+
+``vtor.check`` indicates that the check has failed by raising an exception.
+The appropriate error should be raised in the check function.
+
+The base error class is ``ValidateError``. All errors (except for ``VdtParamError``) 
+raised are sub-classes of this.
+
+If an unrecognised check is specified then ``VdtUnknownCheckError`` is
+raised.
+
+There are also ``VdtTypeError`` and ``VdtValueError``.
+
+If incorrect parameters are passed to a check function then it will (or should)
+raise ``VdtParamError``. As this indicates *programmer* error, rather than an error
+in the value, it is a subclass of ``SyntaxError`` instead of ``ValidateError``. 
+
+.. note::
+
+    This means it *won't* be caught by ConfigObj - but propagated instead.
+
+If the value supplied is the wrong type, then the check should raise
+``VdtTypeError``. e.g. the check requires the value to be an integer (or
+representation of an integer) and something else was supplied.
+
+If the value supplied is the right type, but an unacceptable value, then the
+check should raise ``VdtValueError``. e.g. the check requires the value to
+be an integer (or representation of an integer) less than ten and a higher
+value was supplied.
+
+Both ``VdtTypeError`` and ``VdtValueError`` are initialised with the
+incorrect value. In other words you raise them like this :
+
+.. code-block:: python
+
+    raise VdtTypeError(value)
+    #
+    raise VdtValueError(value)
+
+
+``VdtValueError`` has the following subclasses, which should be raised if
+they are more appropriate.
+
+* ``VdtValueTooSmallError``
+* ``VdtValueTooBigError``
+* ``VdtValueTooShortError``
+* ``VdtValueTooLongError``
+
+
+Writing check functions
+=======================
+
+Writing check functions is easy.
+
+The check function will receive the value as its first argument, followed by
+any other parameters and keyword arguments.
+
+If the check fails, it should raise a ``VdtTypeError`` or a
+``VdtValueError`` (or an appropriate subclass).
+
+All parameters and keyword arguments are *always* passed as strings. (Parsed
+from the check string).
+
+The value might be a string (or list of strings) and need
+converting to the right type - alternatively it might already be a list of 
+integers. Our function needs to be able to handle either.
+
+If the check passes then it should return the value (possibly converted to the
+right type).
+
+And that's it !
+
+
+Example
+-------
+
+Here is an example function that requires a list of integers. Each integer
+must be between 0 and 99.
+
+It takes a single argument specifying the length of the list. (Which allows us
+to use the same check in more than one place). If the length can't be converted
+to an integer then we need to raise ``VdtParamError``.
+
+Next we check that the value is a list. Anything else should raise a
+``VdtTypeError``. The list should also have 'length' entries. If the list
+has more or less entries then we will need to raise a
+``VdtValueTooShortError`` or a ``VdtValueTooLongError``.
+
+Then we need to check every entry in the list. Each entry should be an integer
+between 0 and 99, or a string representation of an integer between 0 and 99.
+Any other type is a ``VdtTypeError``, any other value is a
+``VdtValueError`` (either too big, or too small).
+
+.. code-block:: python
+
+    def special_list(value, length):
+        """
+        Check that the supplied value is a list of integers,
+        with 'length' entries, and each entry between 0 and 99.
+        """
+        # length is supplied as a string
+        # we need to convert it to an integer
+        try:
+            length = int(length)
+        except ValueError:
+            raise VdtParamError('length', length)
+        #
+        # Check the supplied value is a list
+        if not isinstance(value, list):
+            raise VdtTypeError(value)
+        #
+        # check the length of the list is correct
+        if len(value) > length:
+            raise VdtValueTooLongError(value)
+        elif len(value) < length:
+            raise VdtValueTooShortError(value)
+        #
+        # Next, check every member in the list
+        # converting strings as necessary
+        out = []
+        for entry in value:
+            if not isinstance(entry, (str, unicode, int)):
+                # a value in the list
+                # is neither an integer nor a string
+                raise VdtTypeError(value)
+            elif isinstance(entry, (str, unicode)):
+                if not entry.isdigit():
+                    raise VdtTypeError(value)
+                else:
+                    entry = int(entry)
+            if entry < 0:
+                raise VdtValueTooSmallError(value)
+            elif entry > 99:
+                raise VdtValueTooBigError(value)
+            out.append(entry)
+        #
+        # if we got this far, all is well
+        # return the new list
+        return out
+
+If you are only using validate from ConfigObj then the error type (*TooBig*, 
+*TooSmall*, etc) is lost - so you may only want to raise ``VdtValueError``.
+
+.. caution::
+
+    If your function raises an exception that isn't a subclass of 
+    ``ValidateError``, then ConfigObj won't trap it. This means validation will 
+    fail.
+    
+    This is why our function starts by checking the type of the value. If we 
+    are passed the wrong type (e.g. an integer rather than a list) we get a 
+    ``VdtTypeError`` rather than bombing out when we try to iterate over 
+    the value.
+
+If you are using validate in another circumstance you may want to create your 
+own subclasses of ``ValidateError`` which convey more specific information.
+
+
+Known Issues
+============
+
+The following parses and then blows up. The resulting error message
+is confusing:
+
+    ``checkname(default=list(1, 2, 3, 4)``
+    
+This is because it parses as: ``checkname(default="list(1", 2, 3, 4)``.
+That isn't actually unreasonable, but the error message won't help you
+work out what has happened.
+    
+
+TODO
+====
+
+* A regex check function ?
+* A timestamp check function ? (Using the ``parse`` function from ``DateUtil`` perhaps).
+
+
+ISSUES
+======
+
+.. note::
+
+    Please file any bug reports to `Michael Foord`_ or the ConfigObj
+    `Mailing List`_.
+
+If we could pull tuples out of arguments, it would be easier
+to specify arguments for 'mixed_lists'.
+
+
+CHANGELOG
+=========
+
+2009/10/25 - Version 1.0.1
+--------------------------
+
+* BUGFIX: Fixed compatibility with Python 2.3.
+
+2009/04/13 - Version 1.0.0
+--------------------------
+
+* BUGFIX: can now handle multiline strings.
+* Addition of 'force_list' validation option.
+
+As the API is stable and there are no known bugs or outstanding feature requests I am marking this 1.0.
+
+
+2008/02/24 - Version 0.3.2
+--------------------------
+
+BUGFIX: Handling of None as default value fixed.
+
+
+2008/02/05 - Version 0.3.1
+--------------------------
+
+BUGFIX: Unicode checks no longer broken.
+
+
+2008/02/05 - Version 0.3.0
+--------------------------
+
+Improved performance with a parse cache.
+
+New ``get_default_value`` method. Given a check it returns the default
+value (converted to the correct type) or raises a ``KeyError`` if the
+check doesn't specify a default.
+
+Added 'tuple' check and corresponding 'is_tuple' function (which always returns a tuple).
+
+BUGFIX: A quoted 'None' as a default value is no longer treated as None,
+but as the string 'None'.
+
+BUGFIX: We weren't unquoting keyword arguments of length two, so an
+empty string didn't work as a default.
+
+BUGFIX: Strings no longer pass the 'is_list' check. Additionally, the
+list checks always return lists.
+
+A couple of documentation bug fixes.
+
+Removed CHANGELOG from module.
+
+
+2007/02/04      Version 0.2.3
+-----------------------------
+
+Release of 0.2.3
+
+
+2006/12/17      Version 0.2.3-alpha1
+------------------------------------
+
+By Nicola Larosa
+
+Fixed validate doc to talk of ``boolean`` instead of ``bool``; changed the
+``is_bool`` function to ``is_boolean`` (Sourceforge bug #1531525).
+
+
+2006/04/29      Version 0.2.2
+-----------------------------
+
+Addressed bug where a string would pass the ``is_list`` test. (Thanks to
+Konrad Wojas.)
+
+
+2005/12/16      Version 0.2.1
+-----------------------------
+
+Fixed bug so we can handle keyword argument values with commas.
+
+We now use a list constructor for passing list values to keyword arguments
+(including ``default``)::
+
+    default=list("val", "val", "val")
+
+Added the ``_test`` test.
+
+Moved a function call outside a try...except block.
+
+
+2005/08/18      Version 0.2.0
+-----------------------------
+
+Updated by `Michael Foord`_ and `Nicola Larosa`_
+
+Does type conversion as well.
+
+
+2005/02/01      Version 0.1.0
+-----------------------------
+
+Initial version developed by `Michael Foord`_
+and Mark Andrews.
+
+

+ 83 - 0
desktop/core/ext-py/configobj-4.7.2/setup.py

@@ -0,0 +1,83 @@
+# setup.py
+# Install script for ConfigObj
+# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+#         mark AT la-la DOT com
+#         nico AT tekNico DOT net
+
+# This software is licensed under the terms of the BSD license.
+# http://www.voidspace.org.uk/python/license.shtml
+
+import sys
+from distutils.core import setup
+from configobj import __version__ as VERSION
+
+NAME = 'configobj'
+
+MODULES = 'configobj', 'validate'
+
+DESCRIPTION = 'Config file reading, writing and validation.'
+
+URL = 'http://www.voidspace.org.uk/python/configobj.html'
+
+DOWNLOAD_URL = "http://www.voidspace.org.uk/downloads/configobj-%s.zip" % VERSION
+
+LONG_DESCRIPTION = """**ConfigObj** is a simple but powerful config file reader and writer: an *ini
+file round tripper*. Its main feature is that it is very easy to use, with a
+straightforward programmer's interface and a simple syntax for config files.
+It has lots of other features though :
+
+* Nested sections (subsections), to any level
+* List values
+* Multiple line values
+* Full Unicode support
+* String interpolation (substitution)
+* Integrated with a powerful validation system
+
+    - including automatic type checking/conversion
+    - and allowing default values
+    - repeated sections
+
+* All comments in the file are preserved
+* The order of keys/sections is preserved
+* Powerful ``unrepr`` mode for storing/retrieving Python data-types
+
+| Release 4.7.2 fixes several bugs in 4.7.1
+| Release 4.7.1 fixes a bug with the deprecated options keyword in
+| 4.7.0.
+| Release 4.7.0 improves performance adds features for validation and
+| fixes some bugs."""
+
+CLASSIFIERS = [
+    'Development Status :: 6 - Mature',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: BSD License',
+    'Programming Language :: Python',
+    'Programming Language :: Python :: 2.3',
+    'Programming Language :: Python :: 2.4',
+    'Programming Language :: Python :: 2.5',
+    'Programming Language :: Python :: 2.6',
+    'Operating System :: OS Independent',
+    'Topic :: Software Development :: Libraries',
+    'Topic :: Software Development :: Libraries :: Python Modules',
+]
+
+AUTHOR = 'Michael Foord & Nicola Larosa'
+
+AUTHOR_EMAIL = 'fuzzyman@voidspace.org.uk'
+
+KEYWORDS = "config, ini, dictionary, application, admin, sysadmin, configuration, validation".split(', ')
+
+
+setup(name=NAME,
+      version=VERSION,
+      description=DESCRIPTION,
+      long_description=LONG_DESCRIPTION,
+      download_url=DOWNLOAD_URL,
+      author=AUTHOR,
+      author_email=AUTHOR_EMAIL,
+      url=URL,
+      py_modules=MODULES,
+      classifiers=CLASSIFIERS,
+      keywords=KEYWORDS
+     )

+ 0 - 0
desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/__init__.py


+ 10 - 0
desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/conf.ini

@@ -0,0 +1,10 @@
+
+extra = 3
+
+[extra-section]
+
+[section]
+    [[sub-section]]
+    extra = 3
+    [[extra-sub-section]]
+    extra = 3

+ 13 - 0
desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/conf.spec

@@ -0,0 +1,13 @@
+
+value = integer
+
+[section]
+    value = integer
+
+    [[sub-section]]
+        value = integer
+    [[missing-subsection]]
+        value = integer
+
+[missing-section]
+    value = integer

+ 101 - 0
desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/test_configobj.py

@@ -0,0 +1,101 @@
+from __future__ import with_statement
+
+import os
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from configobj import ConfigObj
+
+try:
+    # Python 2.6 only
+    from warnings import catch_warnings
+except ImportError:
+    # this will cause an error, but at least the other tests
+    # will run on Python 2.5
+    catch_warnings = None
+
+class TestConfigObj(unittest.TestCase):
+    
+    def test_order_preserved(self):
+        c = ConfigObj()
+        c['a'] = 1
+        c['b'] = 2
+        c['c'] = 3
+        c['section'] = {}
+        c['section']['a'] = 1
+        c['section']['b'] = 2
+        c['section']['c'] = 3
+        c['section']['section'] = {}
+        c['section']['section2'] = {}
+        c['section']['section3'] = {}
+        c['section2'] = {}
+        c['section3'] = {}
+        
+        c2 = ConfigObj(c)
+        self.assertEqual(c2.scalars, ['a', 'b', 'c'])
+        self.assertEqual(c2.sections, ['section', 'section2', 'section3'])
+        self.assertEqual(c2['section'].scalars, ['a', 'b', 'c'])
+        self.assertEqual(c2['section'].sections, ['section', 'section2', 'section3'])
+        
+        self.assertFalse(c['section'] is c2['section'])
+        self.assertFalse(c['section']['section'] is c2['section']['section'])
+    
+    if catch_warnings is not None:
+        # poor man's skipTest
+        def test_options_deprecation(self):
+            with catch_warnings(record=True) as log:
+                ConfigObj(options={})
+            
+            # unpack the only member of log
+            warning, = log
+            self.assertEqual(warning.category, DeprecationWarning)
+    
+    def test_list_members(self):
+        c = ConfigObj()
+        c['a'] = []
+        c['a'].append('foo')
+        self.assertEqual(c['a'], ['foo'])
+    
+    def test_list_interpolation_with_pop(self):
+        c = ConfigObj()
+        c['a'] = []
+        c['a'].append('%(b)s')
+        c['b'] = 'bar'
+        self.assertEqual(c.pop('a'), ['bar'])
+    
+    def test_with_default(self):
+        c = ConfigObj()
+        c['a'] = 3
+        
+        self.assertEqual(c.pop('a'), 3)
+        self.assertEqual(c.pop('b', 3), 3)
+        self.assertRaises(KeyError, c.pop, 'c')
+    
+    
+    def test_interpolation_with_section_names(self):
+        cfg = """
+item1 = 1234
+[section]
+    [[item1]]
+    foo='bar'
+    [[DEFAULT]]
+        [[[item1]]]
+        why = would you do this?
+    [[other-subsection]]
+    item2 = '$item1'""".splitlines()
+        c = ConfigObj(cfg, interpolation='Template')
+        
+        # This raises an exception in 4.7.1 and earlier due to the section
+        # being found as the interpolation value
+        repr(c)
+    
+    def test_interoplation_repr(self):
+        c = ConfigObj(['foo = $bar'], interpolation='Template')
+        c['baz'] = {}
+        c['baz']['spam'] = '%(bar)s'
+        
+        # This raises a MissingInterpolationOption exception in 4.7.1 and earlier
+        repr(c)
+

+ 66 - 0
desktop/core/ext-py/configobj-4.7.2/tests/functionaltests/test_validate_errors.py

@@ -0,0 +1,66 @@
+import os
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from configobj import ConfigObj, get_extra_values
+from validate import Validator
+
+thisdir = os.path.dirname(os.path.join(os.getcwd(), __file__))
+inipath = os.path.join(thisdir, 'conf.ini')
+specpath = os.path.join(thisdir, 'conf.spec')
+
+
+class TestValidateErrors(unittest.TestCase):
+    
+    def test_validate_no_valid_entries(self):
+        conf = ConfigObj(inipath, configspec=specpath)
+        
+        validator = Validator()
+        result = conf.validate(validator)
+        self.assertFalse(result)
+    
+    
+    def test_validate_preserve_errors(self):
+        conf = ConfigObj(inipath, configspec=specpath)
+        
+        validator = Validator()
+        result = conf.validate(validator, preserve_errors=True)
+        
+        self.assertFalse(result['value'])
+        self.assertFalse(result['missing-section'])
+        
+        section = result['section']
+        self.assertFalse(section['value'])
+        self.assertFalse(section['sub-section']['value'])
+        self.assertFalse(section['missing-subsection'])
+        
+    
+    def test_validate_extra_values(self):
+        conf = ConfigObj(inipath, configspec=specpath)
+        conf.validate(Validator(), preserve_errors=True)
+        
+        self.assertEqual(conf.extra_values, ['extra', 'extra-section'])
+        
+        self.assertEqual(conf['section'].extra_values, ['extra-sub-section'])
+        self.assertEqual(conf['section']['sub-section'].extra_values,
+                         ['extra'])
+        
+    
+    def test_get_extra_values(self):
+        conf = ConfigObj(inipath, configspec=specpath)
+        
+        conf.validate(Validator(), preserve_errors=True)
+        extra_values = get_extra_values(conf)
+        
+        expected = sorted([
+            ((), 'extra'),
+            ((), 'extra-section'),
+            (('section', 'sub-section'), 'extra'),
+            (('section',), 'extra-sub-section'),
+        ])
+        self.assertEqual(sorted(extra_values), expected)
+
+if __name__ == '__main__':
+    unittest.main()

+ 2221 - 0
desktop/core/ext-py/configobj-4.7.2/tests/test_configobj.py

@@ -0,0 +1,2221 @@
+# configobj_test.py
+# doctests for ConfigObj
+# A config file reader/writer that supports nested sections in config files.
+# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+#         nico AT tekNico DOT net
+
+# ConfigObj 4
+# http://www.voidspace.org.uk/python/configobj.html
+
+# Released subject to the BSD License
+# Please see http://www.voidspace.org.uk/python/license.shtml
+
+# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
+# For information about bugfixes, updates and support, please join the
+# ConfigObj mailing list:
+# http://lists.sourceforge.net/lists/listinfo/configobj-develop
+# Comments, suggestions and bug reports welcome.
+
+
+from __future__ import generators
+from StringIO import StringIO
+
+import os
+import sys
+INTP_VER = sys.version_info[:2]
+if INTP_VER < (2, 2):
+    raise RuntimeError("Python v.2.2 or later needed")
+
+try:
+    from codecs import BOM_UTF8
+except ImportError:
+    # Python 2.2 does not have this
+    # UTF-8
+    BOM_UTF8 = '\xef\xbb\xbf'
+
+from configobj import *
+from validate import Validator, VdtValueTooSmallError
+
+
+"""
+    >>> z = ConfigObj()
+    >>> z['a'] = 'a'
+    >>> z['sect'] = {
+    ...    'subsect': {
+    ...         'a': 'fish',
+    ...         'b': 'wobble',
+    ...     },
+    ...     'member': 'value',
+    ... }
+    >>> x = ConfigObj(z.write())
+    >>> z == x
+    1
+"""
+
+
+def _error_test():
+    """
+    Testing the error classes.
+    
+    >>> raise ConfigObjError
+    Traceback (most recent call last):
+    ConfigObjError
+
+    >>> raise NestingError
+    Traceback (most recent call last):
+    NestingError
+    
+    >>> raise ParseError
+    Traceback (most recent call last):
+    ParseError
+    
+    >>> raise DuplicateError
+    Traceback (most recent call last):
+    DuplicateError
+    
+    >>> raise ConfigspecError
+    Traceback (most recent call last):
+    ConfigspecError
+    
+    >>> raise InterpolationLoopError('yoda')
+    Traceback (most recent call last):
+    InterpolationLoopError: interpolation loop detected in value "yoda".
+    
+    >>> raise RepeatSectionError
+    Traceback (most recent call last):
+    RepeatSectionError
+    
+    >>> raise MissingInterpolationOption('yoda')
+    Traceback (most recent call last):
+    MissingInterpolationOption: missing option "yoda" in interpolation.
+    
+    
+    >>> raise ReloadError()
+    Traceback (most recent call last):
+    ReloadError: reload failed, filename is not set.
+    >>> try:
+    ...     raise ReloadError()
+    ... except IOError:
+    ...     pass
+    ... else:
+    ...     raise Exception('We should catch a ReloadError as an IOError')
+    >>>
+    
+    """
+
+
+def _section_test():
+    """
+    Tests from Section methods.
+    
+    >>> n = a.dict()
+    >>> n == a
+    1
+    >>> n is a
+    0
+        
+    >>> a = '''[section1]
+    ...     option1 = True
+    ...     [[subsection]]
+    ...     more_options = False
+    ...     # end of file'''.splitlines()
+    >>> b = '''# File is user.ini
+    ...     [section1]
+    ...     option1 = False
+    ...     # end of file'''.splitlines()
+    >>> c1 = ConfigObj(b)
+    >>> c2 = ConfigObj(a)
+    >>> c2.merge(c1)
+    >>> c2
+    ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}})
+    
+    >>> config = '''[XXXXsection]
+    ... XXXXkey = XXXXvalue'''.splitlines()
+    >>> cfg = ConfigObj(config)
+    >>> cfg
+    ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
+    >>> def transform(section, key):
+    ...     val = section[key]
+    ...     newkey = key.replace('XXXX', 'CLIENT1')
+    ...     section.rename(key, newkey)
+    ...     if isinstance(val, (tuple, list, dict)):
+    ...         pass
+    ...     else:
+    ...         val = val.replace('XXXX', 'CLIENT1')
+    ...         section[newkey] = val
+    >>> cfg.walk(transform, call_on_sections=True)
+    {'CLIENT1section': {'CLIENT1key': None}}
+    >>> cfg
+    ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}})
+    """
+
+
+def _test_reset():
+    """
+    >>> something = object()
+    >>> c = ConfigObj()
+    >>> c['something'] = something
+    >>> c['section'] = {'something': something}
+    >>> c.filename = 'fish'
+    >>> c.raise_errors = something
+    >>> c.list_values = something
+    >>> c.create_empty = something
+    >>> c.file_error = something
+    >>> c.stringify = something
+    >>> c.indent_type = something
+    >>> c.encoding = something
+    >>> c.default_encoding = something
+    >>> c.BOM = something
+    >>> c.newlines = something
+    >>> c.write_empty_values = something
+    >>> c.unrepr = something
+    >>> c.initial_comment = something
+    >>> c.final_comment = something
+    >>> c.configspec = something
+    >>> c.inline_comments = something
+    >>> c.comments = something
+    >>> c.defaults = something
+    >>> c.default_values = something
+    >>> c.reset()
+    >>> 
+    >>> c.filename
+    >>> c.raise_errors
+    False
+    >>> c.list_values
+    True
+    >>> c.create_empty
+    False
+    >>> c.file_error
+    False
+    >>> c.interpolation
+    True
+    >>> c.configspec
+    >>> c.stringify
+    True
+    >>> c.indent_type
+    >>> c.encoding
+    >>> c.default_encoding
+    >>> c.unrepr
+    False
+    >>> c.write_empty_values
+    False
+    >>> c.inline_comments
+    {}
+    >>> c.comments
+    {}
+    >>> c.defaults
+    []
+    >>> c.default_values
+    {}
+    >>> c == ConfigObj()
+    True
+    >>> c
+    ConfigObj({})
+    """
+
+
+def _test_reload():
+    """
+    >>> c = ConfigObj(StringIO())
+    >>> c.reload()
+    Traceback (most recent call last):
+    ReloadError: reload failed, filename is not set.
+    >>> c = ConfigObj()
+    >>> c.reload()
+    Traceback (most recent call last):
+    ReloadError: reload failed, filename is not set.
+    >>> c = ConfigObj([])
+    >>> c.reload()
+    Traceback (most recent call last):
+    ReloadError: reload failed, filename is not set.
+    
+    We need to use a real file as reload is only for files loaded from
+    the filesystem.
+    >>> h = open('temp', 'w')
+    >>> h.write('''
+    ...     test1=40
+    ...     test2=hello
+    ...     test3=3
+    ...     test4=5.0
+    ...     [section]
+    ...         test1=40
+    ...         test2=hello
+    ...         test3=3
+    ...         test4=5.0
+    ...         [[sub section]]
+    ...             test1=40
+    ...             test2=hello
+    ...             test3=3
+    ...             test4=5.0
+    ...     [section2]
+    ...         test1=40
+    ...         test2=hello
+    ...         test3=3
+    ...         test4=5.0
+    ... ''')
+    >>> h.close()
+    >>> configspec = '''
+    ...     test1= integer(30,50)
+    ...     test2= string
+    ...     test3=integer
+    ...     test4=float(4.5)
+    ...     [section]
+    ...         test1=integer(30,50)
+    ...         test2=string
+    ...         test3=integer
+    ...         test4=float(4.5)
+    ...         [[sub section]]
+    ...             test1=integer(30,50)
+    ...             test2=string
+    ...             test3=integer
+    ...             test4=float(4.5)
+    ...     [section2]
+    ...         test1=integer(30,50)
+    ...         test2=string
+    ...         test3=integer
+    ...         test4=float(4.5)
+    ...     '''.split('\\n')
+    >>> c = ConfigObj('temp', configspec=configspec)
+    >>> c.configspec['test1'] = 'integer(50,60)'
+    >>> backup = ConfigObj('temp')
+    >>> del c['section']
+    >>> del c['test1']
+    >>> c['extra'] = '3'
+    >>> c['section2']['extra'] = '3'
+    >>> c.reload()
+    >>> c == backup
+    True
+    >>> c.validate(Validator())
+    True
+    >>> os.remove('temp')
+    """
+
+
+def _doctest():
+    """
+    Dummy function to hold some of the doctests.
+    
+    >>> a.depth
+    0
+    >>> a == {
+    ...     'key2': 'val',
+    ...     'key1': 'val',
+    ...     'lev1c': {
+    ...         'lev2c': {
+    ...             'lev3c': {
+    ...                 'key1': 'val',
+    ...             },
+    ...         },
+    ...     },
+    ...     'lev1b': {
+    ...         'key2': 'val',
+    ...         'key1': 'val',
+    ...         'lev2ba': {
+    ...             'key1': 'val',
+    ...         },
+    ...         'lev2bb': {
+    ...             'key1': 'val',
+    ...         },
+    ...     },
+    ...     'lev1a': {
+    ...         'key2': 'val',
+    ...         'key1': 'val',
+    ...     },
+    ... }
+    1
+    >>> b.depth
+    0
+    >>> b == {
+    ...     'key3': 'val3',
+    ...     'key2': 'val2',
+    ...     'key1': 'val1',
+    ...     'section 1': {
+    ...         'keys11': 'val1',
+    ...         'keys13': 'val3',
+    ...         'keys12': 'val2',
+    ...     },
+    ...     'section 2': {
+    ...         'section 2 sub 1': {
+    ...             'fish': '3',
+    ...     },
+    ...     'keys21': 'val1',
+    ...     'keys22': 'val2',
+    ...     'keys23': 'val3',
+    ...     },
+    ... }
+    1
+    >>> t = '''
+    ... 'a' = b # !"$%^&*(),::;'@~#= 33
+    ... "b" = b #= 6, 33
+    ... ''' .split('\\n')
+    >>> t2 = ConfigObj(t)
+    >>> assert t2 == {'a': 'b', 'b': 'b'}
+    >>> t2.inline_comments['b'] = ''
+    >>> del t2['a']
+    >>> assert t2.write() == ['','b = b', '']
+    
+    # Test ``list_values=False`` stuff
+    >>> c = '''
+    ...     key1 = no quotes
+    ...     key2 = 'single quotes'
+    ...     key3 = "double quotes"
+    ...     key4 = "list", 'with', several, "quotes"
+    ...     '''
+    >>> cfg = ConfigObj(c.splitlines(), list_values=False)
+    >>> cfg == {'key1': 'no quotes', 'key2': "'single quotes'", 
+    ... 'key3': '"double quotes"', 
+    ... 'key4': '"list", \\'with\\', several, "quotes"'
+    ... }
+    1
+    >>> cfg = ConfigObj(list_values=False)
+    >>> cfg['key1'] = 'Multiline\\nValue'
+    >>> cfg['key2'] = '''"Value" with 'quotes' !'''
+    >>> cfg.write()
+    ["key1 = '''Multiline\\nValue'''", 'key2 = "Value" with \\'quotes\\' !']
+    >>> cfg.list_values = True
+    >>> cfg.write() == ["key1 = '''Multiline\\nValue'''",
+    ... 'key2 = \\'\\'\\'"Value" with \\'quotes\\' !\\'\\'\\'']
+    1
+    
+    Test flatten_errors:
+    
+    >>> config = '''
+    ...     test1=40
+    ...     test2=hello
+    ...     test3=3
+    ...     test4=5.0
+    ...     [section]
+    ...         test1=40
+    ...         test2=hello
+    ...         test3=3
+    ...         test4=5.0
+    ...         [[sub section]]
+    ...             test1=40
+    ...             test2=hello
+    ...             test3=3
+    ...             test4=5.0
+    ... '''.split('\\n')
+    >>> configspec = '''
+    ...     test1= integer(30,50)
+    ...     test2= string
+    ...     test3=integer
+    ...     test4=float(6.0)
+    ...     [section]
+    ...         test1=integer(30,50)
+    ...         test2=string
+    ...         test3=integer
+    ...         test4=float(6.0)
+    ...         [[sub section]]
+    ...             test1=integer(30,50)
+    ...             test2=string
+    ...             test3=integer
+    ...             test4=float(6.0)
+    ...     '''.split('\\n')
+    >>> val = Validator()
+    >>> c1 = ConfigObj(config, configspec=configspec)
+    >>> res = c1.validate(val)
+    >>> flatten_errors(c1, res) == [([], 'test4', False), (['section', 
+    ...     'sub section'], 'test4', False), (['section'], 'test4', False)]
+    True
+    >>> res = c1.validate(val, preserve_errors=True)
+    >>> check = flatten_errors(c1, res)
+    >>> check[0][:2]
+    ([], 'test4')
+    >>> check[1][:2]
+    (['section', 'sub section'], 'test4')
+    >>> check[2][:2]
+    (['section'], 'test4')
+    >>> for entry in check:
+    ...     isinstance(entry[2], VdtValueTooSmallError)
+    ...     print str(entry[2])
+    True
+    the value "5.0" is too small.
+    True
+    the value "5.0" is too small.
+    True
+    the value "5.0" is too small.
+    
+    Test unicode handling, BOM, write witha file like object and line endings :
+    >>> u_base = '''
+    ... # initial comment
+    ...     # inital comment 2
+    ... 
+    ... test1 = some value
+    ... # comment
+    ... test2 = another value    # inline comment
+    ... # section comment
+    ... [section]    # inline comment
+    ...     test = test    # another inline comment
+    ...     test2 = test2
+    ... 
+    ... # final comment
+    ... # final comment2
+    ... '''
+    >>> u = u_base.encode('utf_8').splitlines(True)
+    >>> u[0] = BOM_UTF8 + u[0]
+    >>> uc = ConfigObj(u)
+    >>> uc.encoding = None
+    >>> uc.BOM == True
+    1
+    >>> uc == {'test1': 'some value', 'test2': 'another value',
+    ... 'section': {'test': 'test', 'test2': 'test2'}}
+    1
+    >>> uc = ConfigObj(u, encoding='utf_8', default_encoding='latin-1')
+    >>> uc.BOM
+    1
+    >>> isinstance(uc['test1'], unicode)
+    1
+    >>> uc.encoding
+    'utf_8'
+    >>> uc.newlines
+    '\\n'
+    >>> uc['latin1'] = "This costs lot's of "
+    >>> a_list = uc.write()
+    >>> len(a_list)
+    15
+    >>> isinstance(a_list[0], str)
+    1
+    >>> a_list[0].startswith(BOM_UTF8)
+    1
+    >>> u = u_base.replace('\\n', '\\r\\n').encode('utf_8').splitlines(True)
+    >>> uc = ConfigObj(u)
+    >>> uc.newlines
+    '\\r\\n'
+    >>> uc.newlines = '\\r'
+    >>> file_like = StringIO()
+    >>> uc.write(file_like)
+    >>> file_like.seek(0)
+    >>> uc2 = ConfigObj(file_like)
+    >>> uc2 == uc
+    1
+    >>> uc2.filename == None
+    1
+    >>> uc2.newlines == '\\r'
+    1
+    
+    Test validate in copy mode
+    >>> a = '''
+    ... # Initial Comment
+    ... 
+    ... key1 = string(default=Hello)
+    ... 
+    ... # section comment
+    ... [section] # inline comment
+    ... # key1 comment
+    ... key1 = integer(default=6)
+    ... # key2 comment
+    ... key2 = boolean(default=True)
+    ... 
+    ...     # subsection comment
+    ...     [[sub-section]] # inline comment
+    ...     # another key1 comment
+    ...     key1 = float(default=3.0)'''.splitlines()
+    >>> b = ConfigObj(configspec=a)
+    >>> b.validate(val, copy=True)
+    1
+    >>> b.write() == ['',
+    ... '# Initial Comment',
+    ... '',
+    ... 'key1 = Hello',
+    ... '',
+    ... '# section comment',
+    ... '[section]    # inline comment',
+    ... '    # key1 comment',
+    ... '    key1 = 6',
+    ... '    # key2 comment',
+    ... '    key2 = True',
+    ... '    ',
+    ... '    # subsection comment',
+    ... '    [[sub-section]]    # inline comment',
+    ... '        # another key1 comment',
+    ... '        key1 = 3.0']
+    1
+    
+    Test Writing Empty Values
+    >>> a = '''
+    ...     key1 =
+    ...     key2 =# a comment''' 
+    >>> b = ConfigObj(a.splitlines())
+    >>> b.write()
+    ['', 'key1 = ""', 'key2 = ""    # a comment']
+    >>> b.write_empty_values = True
+    >>> b.write()
+    ['', 'key1 = ', 'key2 =     # a comment']
+    
+    Test unrepr when reading
+    >>> a = '''
+    ...     key1 = (1, 2, 3)    # comment
+    ...     key2 = True
+    ...     key3 = 'a string'
+    ...     key4 = [1, 2, 3, 'a mixed list']
+    ... '''.splitlines()
+    >>> b = ConfigObj(a, unrepr=True)
+    >>> b == {'key1': (1, 2, 3),
+    ... 'key2': True,
+    ... 'key3': 'a string',
+    ... 'key4': [1, 2, 3, 'a mixed list']}
+    1
+    
+    Test unrepr when writing
+    >>> c = ConfigObj(b.write(), unrepr=True)
+    >>> c == b
+    1
+    
+    Test unrepr with multiline values
+    >>> a = '''k = \"""{
+    ... 'k1': 3,
+    ... 'k2': 6.0}\"""
+    ... '''.splitlines()
+    >>> c = ConfigObj(a, unrepr=True)
+    >>> c == {'k': {'k1': 3, 'k2': 6.0}}
+    1
+    
+    Test unrepr with a dictionary
+    >>> a = 'k = {"a": 1}'.splitlines()
+    >>> c = ConfigObj(a, unrepr=True)
+    >>> type(c['k']) == dict
+    1
+        
+    >>> a = ConfigObj()
+    >>> a['a'] = 'fish'
+    >>> a.as_bool('a')
+    Traceback (most recent call last):
+    ValueError: Value "fish" is neither True nor False
+    >>> a['b'] = 'True'
+    >>> a.as_bool('b')
+    1
+    >>> a['b'] = 'off'
+    >>> a.as_bool('b')
+    0
+        
+    >>> a = ConfigObj()
+    >>> a['a'] = 'fish'
+    >>> try:
+    ...     a.as_int('a') #doctest: +ELLIPSIS
+    ... except ValueError, e:
+    ...     err_mess = str(e)
+    >>> err_mess.startswith('invalid literal for int()')
+    1
+    >>> a['b'] = '1'
+    >>> a.as_int('b')
+    1
+    >>> a['b'] = '3.2'
+    >>> try:
+    ...     a.as_int('b') #doctest: +ELLIPSIS
+    ... except ValueError, e:
+    ...     err_mess = str(e)
+    >>> err_mess.startswith('invalid literal for int()')
+    1
+        
+    >>> a = ConfigObj()
+    >>> a['a'] = 'fish'
+    >>> a.as_float('a')
+    Traceback (most recent call last):
+    ValueError: invalid literal for float(): fish
+    >>> a['b'] = '1'
+    >>> a.as_float('b')
+    1.0
+    >>> a['b'] = '3.2'
+    >>> a.as_float('b')
+    3.2000000000000002
+    
+     Test # with unrepr
+     >>> a = '''
+     ...     key1 = (1, 2, 3)    # comment
+     ...     key2 = True
+     ...     key3 = 'a string'
+     ...     key4 = [1, 2, 3, 'a mixed list#']
+     ... '''.splitlines()
+     >>> b = ConfigObj(a, unrepr=True)
+     >>> b == {'key1': (1, 2, 3),
+     ... 'key2': True,
+     ... 'key3': 'a string',
+     ... 'key4': [1, 2, 3, 'a mixed list#']}
+     1
+    """
+    
+    # Comments are no longer parsed from values in configspecs 
+    # so the following test fails and is disabled
+    untested = """
+    Test validate in copy mode
+    >>> a = '''
+    ... # Initial Comment
+    ... 
+    ... key1 = string(default=Hello)    # comment 1
+    ... 
+    ... # section comment
+    ... [section] # inline comment
+    ... # key1 comment
+    ... key1 = integer(default=6) # an integer value
+    ... # key2 comment
+    ... key2 = boolean(default=True) # a boolean
+    ... 
+    ...     # subsection comment
+    ...     [[sub-section]] # inline comment
+    ...     # another key1 comment
+    ...     key1 = float(default=3.0) # a float'''.splitlines()
+    >>> b = ConfigObj(configspec=a)
+    >>> b.validate(val, copy=True)
+    1
+    >>> b.write()
+    >>> b.write() == ['',
+    ... '# Initial Comment',
+    ... '',
+    ... 'key1 = Hello    # comment 1',
+    ... '',
+    ... '# section comment',
+    ... '[section]    # inline comment',
+    ... '    # key1 comment',
+    ... '    key1 = 6    # an integer value',
+    ... '    # key2 comment',
+    ... '    key2 = True    # a boolean',
+    ... '    ',
+    ... '    # subsection comment',
+    ... '    [[sub-section]]    # inline comment',
+    ... '        # another key1 comment',
+    ... '        key1 = 3.0    # a float']
+    1
+    """
+
+
+def _test_configobj():
+    """
+    Testing ConfigObj
+    Testing with duplicate keys and sections.
+    
+    >>> c = '''
+    ... [hello]
+    ... member = value
+    ... [hello again]
+    ... member = value
+    ... [ "hello" ]
+    ... member = value
+    ... '''
+    >>> ConfigObj(c.split('\\n'), raise_errors = True)
+    Traceback (most recent call last):
+    DuplicateError: Duplicate section name at line 6.
+    
+    >>> d = '''
+    ... [hello]
+    ... member = value
+    ... [hello again]
+    ... member1 = value
+    ... member2 = value
+    ... 'member1' = value
+    ... [ "and again" ]
+    ... member = value
+    ... '''
+    >>> ConfigObj(d.split('\\n'), raise_errors = True)
+    Traceback (most recent call last):
+    DuplicateError: Duplicate keyword name at line 7.
+
+    Testing ConfigParser-style interpolation
+    
+    >>> c = ConfigObj()
+    >>> c['DEFAULT'] = {
+    ...     'b': 'goodbye',
+    ...     'userdir': 'c:\\\\home',
+    ...     'c': '%(d)s',
+    ...     'd': '%(c)s'
+    ... }
+    >>> c['section'] = {
+    ...     'a': '%(datadir)s\\\\some path\\\\file.py',
+    ...     'b': '%(userdir)s\\\\some path\\\\file.py',
+    ...     'c': 'Yo %(a)s',
+    ...     'd': '%(not_here)s',
+    ...     'e': '%(e)s',
+    ... }
+    >>> c['section']['DEFAULT'] = {
+    ...     'datadir': 'c:\\\\silly_test',
+    ...     'a': 'hello - %(b)s',
+    ... }
+    >>> c['section']['a'] == 'c:\\\\silly_test\\\\some path\\\\file.py'
+    1
+    >>> c['section']['b'] == 'c:\\\\home\\\\some path\\\\file.py'
+    1
+    >>> c['section']['c'] == 'Yo c:\\\\silly_test\\\\some path\\\\file.py'
+    1
+    
+    Switching Interpolation Off
+    
+    >>> c.interpolation = False
+    >>> c['section']['a'] == '%(datadir)s\\\\some path\\\\file.py'
+    1
+    >>> c['section']['b'] == '%(userdir)s\\\\some path\\\\file.py'
+    1
+    >>> c['section']['c'] == 'Yo %(a)s'
+    1
+    
+    Testing the interpolation errors.
+    
+    >>> c.interpolation = True
+    >>> c['section']['d']
+    Traceback (most recent call last):
+    MissingInterpolationOption: missing option "not_here" in interpolation.
+    >>> c['section']['e']
+    Traceback (most recent call last):
+    InterpolationLoopError: interpolation loop detected in value "e".
+    
+    Testing Template-style interpolation
+    
+    >>> interp_cfg = '''
+    ... [DEFAULT]
+    ... keyword1 = value1
+    ... 'keyword 2' = 'value 2'
+    ... reference = ${keyword1}
+    ... foo = 123
+    ... 
+    ... [ section ]
+    ... templatebare = $keyword1/foo
+    ... bar = $$foo
+    ... dollar = $$300.00
+    ... stophere = $$notinterpolated
+    ... with_braces = ${keyword1}s (plural)
+    ... with_spaces = ${keyword 2}!!!
+    ... with_several = $keyword1/$reference/$keyword1
+    ... configparsersample = %(keyword 2)sconfig
+    ... deep = ${reference}
+    ... 
+    ...     [[DEFAULT]]
+    ...     baz = $foo
+    ... 
+    ...     [[ sub-section ]]
+    ...     quux = '$baz + $bar + $foo'
+    ... 
+    ...         [[[ sub-sub-section ]]]
+    ...         convoluted = "$bar + $baz + $quux + $bar"
+    ... '''
+    >>> c = ConfigObj(interp_cfg.split('\\n'), interpolation='Template')
+    >>> c['section']['templatebare']
+    'value1/foo'
+    >>> c['section']['dollar']
+    '$300.00'
+    >>> c['section']['stophere']
+    '$notinterpolated'
+    >>> c['section']['with_braces']
+    'value1s (plural)'
+    >>> c['section']['with_spaces']
+    'value 2!!!'
+    >>> c['section']['with_several']
+    'value1/value1/value1'
+    >>> c['section']['configparsersample']
+    '%(keyword 2)sconfig'
+    >>> c['section']['deep']
+    'value1'
+    >>> c['section']['sub-section']['quux']
+    '123 + $foo + 123'
+    >>> c['section']['sub-section']['sub-sub-section']['convoluted']
+    '$foo + 123 + 123 + $foo + 123 + $foo'
+    
+    Testing our quoting.
+    
+    >>> i._quote('\"""\\'\\'\\'')
+    Traceback (most recent call last):
+    ConfigObjError: Value \"\"""'''" cannot be safely quoted.
+    >>> try:
+    ...     i._quote('\\n', multiline=False)
+    ... except ConfigObjError, e:
+    ...    e.msg
+    'Value "\\n" cannot be safely quoted.'
+    >>> i._quote(' "\\' ', multiline=False)
+    Traceback (most recent call last):
+    ConfigObjError: Value " "' " cannot be safely quoted.
+    
+    Testing with "stringify" off.
+    >>> c.stringify = False
+    >>> c['test'] = 1
+    Traceback (most recent call last):
+    TypeError: Value is not a string "1".
+    
+    Testing Empty values.
+    >>> cfg_with_empty = '''
+    ... k =
+    ... k2 =# comment test
+    ... val = test
+    ... val2 = ,
+    ... val3 = 1,
+    ... val4 = 1, 2
+    ... val5 = 1, 2, \'''.splitlines()
+    >>> cwe = ConfigObj(cfg_with_empty)
+    >>> cwe == {'k': '', 'k2': '', 'val': 'test', 'val2': [],
+    ...  'val3': ['1'], 'val4': ['1', '2'], 'val5': ['1', '2']}
+    1
+    >>> cwe = ConfigObj(cfg_with_empty, list_values=False)
+    >>> cwe == {'k': '', 'k2': '', 'val': 'test', 'val2': ',',
+    ...  'val3': '1,', 'val4': '1, 2', 'val5': '1, 2,'}
+    1
+    
+    Testing list values.
+    >>> testconfig3 = \'''
+    ... a = ,
+    ... b = test,
+    ... c = test1, test2   , test3
+    ... d = test1, test2, test3,
+    ... \'''
+    >>> d = ConfigObj(testconfig3.split('\\n'), raise_errors=True)
+    >>> d['a'] == []
+    1
+    >>> d['b'] == ['test']
+    1
+    >>> d['c'] == ['test1', 'test2', 'test3']
+    1
+    >>> d['d'] == ['test1', 'test2', 'test3']
+    1
+    
+    Testing with list values off.
+    
+    >>> e = ConfigObj(
+    ...     testconfig3.split('\\n'),
+    ...     raise_errors=True,
+    ...     list_values=False)
+    >>> e['a'] == ','
+    1
+    >>> e['b'] == 'test,'
+    1
+    >>> e['c'] == 'test1, test2   , test3'
+    1
+    >>> e['d'] == 'test1, test2, test3,'
+    1
+    
+    Testing creating from a dictionary.
+    
+    >>> f = {
+    ...     'key1': 'val1',
+    ...     'key2': 'val2',
+    ...     'section 1': {
+    ...         'key1': 'val1',
+    ...         'key2': 'val2',
+    ...         'section 1b': {
+    ...             'key1': 'val1',
+    ...             'key2': 'val2',
+    ...         },
+    ...     },
+    ...     'section 2': {
+    ...         'key1': 'val1',
+    ...         'key2': 'val2',
+    ...         'section 2b': {
+    ...             'key1': 'val1',
+    ...             'key2': 'val2',
+    ...         },
+    ...     },
+    ...      'key3': 'val3',
+    ... }
+    >>> g = ConfigObj(f)
+    >>> f == g
+    1
+    
+    Testing we correctly detect badly built list values (4 of them).
+    
+    >>> testconfig4 = '''
+    ... config = 3,4,,
+    ... test = 3,,4
+    ... fish = ,,
+    ... dummy = ,,hello, goodbye
+    ... '''
+    >>> try:
+    ...     ConfigObj(testconfig4.split('\\n'))
+    ... except ConfigObjError, e:
+    ...     len(e.errors)
+    4
+    
+    Testing we correctly detect badly quoted values (4 of them).
+    
+    >>> testconfig5 = '''
+    ... config = "hello   # comment
+    ... test = 'goodbye
+    ... fish = 'goodbye   # comment
+    ... dummy = "hello again
+    ... '''
+    >>> try:
+    ...     ConfigObj(testconfig5.split('\\n'))
+    ... except ConfigObjError, e:
+    ...     len(e.errors)
+    4
+    
+    Test Multiline Comments
+    >>> i == {
+    ...     'name4': ' another single line value ',
+    ...     'multi section': {
+    ...         'name4': '\\n        Well, this is a\\n        multiline '
+    ...             'value\\n        ',
+    ...         'name2': '\\n        Well, this is a\\n        multiline '
+    ...             'value\\n        ',
+    ...         'name3': '\\n        Well, this is a\\n        multiline '
+    ...             'value\\n        ',
+    ...         'name1': '\\n        Well, this is a\\n        multiline '
+    ...             'value\\n        ',
+    ...     },
+    ...     'name2': ' another single line value ',
+    ...     'name3': ' a single line value ',
+    ...     'name1': ' a single line value ',
+    ... }
+    1
+     
+    >>> filename = a.filename
+    >>> a.filename = None
+    >>> values = a.write()
+    >>> index = 0
+    >>> while index < 23:
+    ...     index += 1
+    ...     line = values[index-1]
+    ...     assert line.endswith('# comment ' + str(index))
+    >>> a.filename = filename
+    
+    >>> start_comment = ['# Initial Comment', '', '#']
+    >>> end_comment = ['', '#', '# Final Comment']
+    >>> newconfig = start_comment + testconfig1.split('\\n') + end_comment
+    >>> nc = ConfigObj(newconfig)
+    >>> nc.initial_comment
+    ['# Initial Comment', '', '#']
+    >>> nc.final_comment
+    ['', '#', '# Final Comment']
+    >>> nc.initial_comment == start_comment
+    1
+    >>> nc.final_comment == end_comment
+    1
+    
+    Test the _handle_comment method
+    
+    >>> c = ConfigObj()
+    >>> c['foo'] = 'bar'
+    >>> c.inline_comments['foo'] = 'Nice bar'
+    >>> c.write()
+    ['foo = bar # Nice bar']
+    
+    tekNico: FIXME: use StringIO instead of real files
+    
+    >>> filename = a.filename
+    >>> a.filename = 'test.ini'
+    >>> a.write()
+    >>> a.filename = filename
+    >>> a == ConfigObj('test.ini', raise_errors=True)
+    1
+    >>> os.remove('test.ini')
+    >>> b.filename = 'test.ini'
+    >>> b.write()
+    >>> b == ConfigObj('test.ini', raise_errors=True)
+    1
+    >>> os.remove('test.ini')
+    >>> i.filename = 'test.ini'
+    >>> i.write()
+    >>> i == ConfigObj('test.ini', raise_errors=True)
+    1
+    >>> os.remove('test.ini')
+    >>> a = ConfigObj()
+    >>> a['DEFAULT'] = {'a' : 'fish'}
+    >>> a['a'] = '%(a)s'
+    >>> a.write()
+    ['a = %(a)s', '[DEFAULT]', 'a = fish']
+    
+    Test indentation handling
+    
+    >>> ConfigObj({'sect': {'sect': {'foo': 'bar'}}}).write()
+    ['[sect]', '    [[sect]]', '        foo = bar']
+    >>> cfg = ['[sect]', '[[sect]]', 'foo = bar']
+    >>> ConfigObj(cfg).write() == cfg
+    1
+    >>> cfg = ['[sect]', '  [[sect]]', '    foo = bar']
+    >>> ConfigObj(cfg).write() == cfg
+    1
+    >>> cfg = ['[sect]', '    [[sect]]', '        foo = bar']
+    >>> ConfigObj(cfg).write() == cfg
+    1
+    >>> ConfigObj(oneTabCfg).write() == oneTabCfg
+    1
+    >>> ConfigObj(twoTabsCfg).write() == twoTabsCfg
+    1
+    >>> ConfigObj(tabsAndSpacesCfg).write() == tabsAndSpacesCfg
+    1
+    >>> ConfigObj(cfg, indent_type=chr(9)).write() == oneTabCfg
+    1
+    >>> ConfigObj(oneTabCfg, indent_type='    ').write() == cfg
+    1
+    """
+
+
+def _test_validate():
+    """
+    >>> config = '''
+    ... test1=40
+    ... test2=hello
+    ... test3=3
+    ... test4=5.0
+    ... [section]
+    ...     test1=40
+    ...     test2=hello
+    ...     test3=3
+    ...     test4=5.0
+    ...     [[sub section]]
+    ...         test1=40
+    ...         test2=hello
+    ...         test3=3
+    ...         test4=5.0
+    ... '''.split('\\n')
+    >>> configspec = '''
+    ... test1= integer(30,50)
+    ... test2= string
+    ... test3=integer
+    ... test4=float(6.0)
+    ... [section ]
+    ...     test1=integer(30,50)
+    ...     test2=string
+    ...     test3=integer
+    ...     test4=float(6.0)
+    ...     [[sub section]]
+    ...         test1=integer(30,50)
+    ...         test2=string
+    ...         test3=integer
+    ...         test4=float(6.0)
+    ... '''.split('\\n')
+    >>> val = Validator()
+    >>> c1 = ConfigObj(config, configspec=configspec)
+    >>> test = c1.validate(val)
+    >>> test == {
+    ...         'test1': True,
+    ...         'test2': True,
+    ...         'test3': True,
+    ...         'test4': False,
+    ...         'section': {
+    ...             'test1': True,
+    ...             'test2': True,
+    ...             'test3': True,
+    ...             'test4': False,
+    ...             'sub section': {
+    ...                 'test1': True,
+    ...                 'test2': True,
+    ...                 'test3': True,
+    ...                 'test4': False,
+    ...             },
+    ...         },
+    ...     }
+    1
+    >>> val.check(c1.configspec['test4'], c1['test4'])
+    Traceback (most recent call last):
+    VdtValueTooSmallError: the value "5.0" is too small.
+    
+    >>> val_test_config = '''
+    ...     key = 0
+    ...     key2 = 1.1
+    ...     [section]
+    ...     key = some text
+    ...     key2 = 1.1, 3.0, 17, 6.8
+    ...         [[sub-section]]
+    ...         key = option1
+    ...         key2 = True'''.split('\\n')
+    >>> val_test_configspec = '''
+    ...     key = integer
+    ...     key2 = float
+    ...     [section]
+    ...     key = string
+    ...     key2 = float_list(4)
+    ...        [[sub-section]]
+    ...        key = option(option1, option2)
+    ...        key2 = boolean'''.split('\\n')
+    >>> val_test = ConfigObj(val_test_config, configspec=val_test_configspec)
+    >>> val_test.validate(val)
+    1
+    >>> val_test['key'] = 'text not a digit'
+    >>> val_res = val_test.validate(val)
+    >>> val_res == {'key2': True, 'section': True, 'key': False}
+    1
+    >>> configspec = '''
+    ...     test1=integer(30,50, default=40)
+    ...     test2=string(default="hello")
+    ...     test3=integer(default=3)
+    ...     test4=float(6.0, default=6.0)
+    ...     [section ]
+    ...         test1=integer(30,50, default=40)
+    ...         test2=string(default="hello")
+    ...         test3=integer(default=3)
+    ...         test4=float(6.0, default=6.0)
+    ...         [[sub section]]
+    ...             test1=integer(30,50, default=40)
+    ...             test2=string(default="hello")
+    ...             test3=integer(default=3)
+    ...             test4=float(6.0, default=6.0)
+    ...     '''.split('\\n')
+    >>> default_test = ConfigObj(['test1=30'], configspec=configspec)
+    >>> default_test
+    ConfigObj({'test1': '30'})
+    >>> default_test.defaults
+    []
+    >>> default_test.default_values
+    {}
+    >>> default_test.validate(val)
+    1
+    >>> default_test == {
+    ...     'test1': 30,
+    ...     'test2': 'hello',
+    ...     'test3': 3,
+    ...     'test4': 6.0,
+    ...     'section': {
+    ...         'test1': 40,
+    ...         'test2': 'hello',
+    ...         'test3': 3,
+    ...         'test4': 6.0,
+    ...         'sub section': {
+    ...             'test1': 40,
+    ...             'test3': 3,
+    ...             'test2': 'hello',
+    ...             'test4': 6.0,
+    ...         },
+    ...     },
+    ... }
+    1
+    >>> default_test.defaults
+    ['test2', 'test3', 'test4']
+    >>> default_test.default_values == {'test1': 40, 'test2': 'hello',
+    ... 'test3': 3, 'test4': 6.0}
+    1
+    >>> default_test.restore_default('test1')
+    40
+    >>> default_test['test1']
+    40
+    >>> 'test1' in default_test.defaults
+    1
+    >>> def change(section, key): 
+    ...     section[key] = 3
+    >>> _ = default_test.walk(change)
+    >>> default_test['section']['sub section']['test4']
+    3
+    >>> default_test.restore_defaults()
+    >>> default_test == {
+    ...     'test1': 40,
+    ...     'test2': "hello",
+    ...     'test3': 3,
+    ...     'test4': 6.0,
+    ...     'section': {
+    ...         'test1': 40,
+    ...         'test2': "hello",
+    ...         'test3': 3,
+    ...         'test4': 6.0,
+    ...         'sub section': {
+    ...             'test1': 40,
+    ...             'test2': "hello",
+    ...             'test3': 3,
+    ...             'test4': 6.0
+    ... }}}
+    1
+    >>> a = ['foo = fish']
+    >>> b = ['foo = integer(default=3)']
+    >>> c = ConfigObj(a, configspec=b)
+    >>> c
+    ConfigObj({'foo': 'fish'})
+    >>> from validate import Validator
+    >>> v = Validator()
+    >>> c.validate(v)
+    0
+    >>> c.default_values
+    {'foo': 3}
+    >>> c.restore_default('foo')
+    3
+
+    Now testing with repeated sections : BIG TEST
+    
+    >>> repeated_1 = '''
+    ... [dogs]
+    ...     [[__many__]] # spec for a dog
+    ...         fleas = boolean(default=True)
+    ...         tail = option(long, short, default=long)
+    ...         name = string(default=rover)
+    ...         [[[__many__]]]  # spec for a puppy
+    ...             name = string(default="son of rover")
+    ...             age = float(default=0.0)
+    ... [cats]
+    ...     [[__many__]] # spec for a cat
+    ...         fleas = boolean(default=True)
+    ...         tail = option(long, short, default=short)
+    ...         name = string(default=pussy)
+    ...         [[[__many__]]] # spec for a kitten
+    ...             name = string(default="son of pussy")
+    ...             age = float(default=0.0)
+    ...         '''.split('\\n')
+    >>> repeated_2 = '''
+    ... [dogs]
+    ... 
+    ...     # blank dogs with puppies
+    ...     # should be filled in by the configspec
+    ...     [[dog1]]
+    ...         [[[puppy1]]]
+    ...         [[[puppy2]]]
+    ...         [[[puppy3]]]
+    ...     [[dog2]]
+    ...         [[[puppy1]]]
+    ...         [[[puppy2]]]
+    ...         [[[puppy3]]]
+    ...     [[dog3]]
+    ...         [[[puppy1]]]
+    ...         [[[puppy2]]]
+    ...         [[[puppy3]]]
+    ... [cats]
+    ... 
+    ...     # blank cats with kittens
+    ...     # should be filled in by the configspec
+    ...     [[cat1]]
+    ...         [[[kitten1]]]
+    ...         [[[kitten2]]]
+    ...         [[[kitten3]]]
+    ...     [[cat2]]
+    ...         [[[kitten1]]]
+    ...         [[[kitten2]]]
+    ...         [[[kitten3]]]
+    ...     [[cat3]]
+    ...         [[[kitten1]]]
+    ...         [[[kitten2]]]
+    ...         [[[kitten3]]]
+    ... '''.split('\\n')
+    >>> repeated_3 = '''
+    ... [dogs]
+    ... 
+    ...     [[dog1]]
+    ...     [[dog2]]
+    ...     [[dog3]]
+    ... [cats]
+    ... 
+    ...     [[cat1]]
+    ...     [[cat2]]
+    ...     [[cat3]]
+    ... '''.split('\\n')
+    >>> repeated_4 = '''
+    ... [__many__]
+    ... 
+    ...     name = string(default=Michael)
+    ...     age = float(default=0.0)
+    ...     sex = option(m, f, default=m)
+    ... '''.split('\\n')
+    >>> repeated_5 = '''
+    ... [cats]
+    ... [[__many__]]
+    ...     fleas = boolean(default=True)
+    ...     tail = option(long, short, default=short)
+    ...     name = string(default=pussy)
+    ...     [[[description]]]
+    ...         height = float(default=3.3)
+    ...         weight = float(default=6)
+    ...         [[[[coat]]]]
+    ...             fur = option(black, grey, brown, "tortoise shell", default=black)
+    ...             condition = integer(0,10, default=5)
+    ... '''.split('\\n')
+    >>> val= Validator()
+    >>> repeater = ConfigObj(repeated_2, configspec=repeated_1)
+    >>> repeater.validate(val)
+    1
+    >>> repeater == {
+    ...     'dogs': {
+    ...         'dog1': {
+    ...             'fleas': True,
+    ...             'tail': 'long',
+    ...             'name': 'rover',
+    ...             'puppy1': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy2': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy3': {'name': 'son of rover', 'age': 0.0},
+    ...         },
+    ...         'dog2': {
+    ...             'fleas': True,
+    ...             'tail': 'long',
+    ...             'name': 'rover',
+    ...             'puppy1': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy2': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy3': {'name': 'son of rover', 'age': 0.0},
+    ...         },
+    ...         'dog3': {
+    ...             'fleas': True,
+    ...             'tail': 'long',
+    ...             'name': 'rover',
+    ...             'puppy1': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy2': {'name': 'son of rover', 'age': 0.0},
+    ...             'puppy3': {'name': 'son of rover', 'age': 0.0},
+    ...         },
+    ...     },
+    ...     'cats': {
+    ...         'cat1': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'kitten1': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten2': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten3': {'name': 'son of pussy', 'age': 0.0},
+    ...         },
+    ...         'cat2': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'kitten1': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten2': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten3': {'name': 'son of pussy', 'age': 0.0},
+    ...         },
+    ...         'cat3': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'kitten1': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten2': {'name': 'son of pussy', 'age': 0.0},
+    ...             'kitten3': {'name': 'son of pussy', 'age': 0.0},
+    ...         },
+    ...     },
+    ... }
+    1
+    >>> repeater = ConfigObj(repeated_3, configspec=repeated_1)
+    >>> repeater.validate(val)
+    1
+    >>> repeater == {
+    ...     'cats': {
+    ...         'cat1': {'fleas': True, 'tail': 'short', 'name': 'pussy'},
+    ...         'cat2': {'fleas': True, 'tail': 'short', 'name': 'pussy'},
+    ...         'cat3': {'fleas': True, 'tail': 'short', 'name': 'pussy'},
+    ...     },
+    ...     'dogs': {
+    ...         'dog1': {'fleas': True, 'tail': 'long', 'name': 'rover'},
+    ...         'dog2': {'fleas': True, 'tail': 'long', 'name': 'rover'},
+    ...         'dog3': {'fleas': True, 'tail': 'long', 'name': 'rover'},
+    ...     },
+    ... }
+    1
+    >>> repeater = ConfigObj(configspec=repeated_4)
+    >>> repeater['Michael'] = {}
+    >>> repeater.validate(val)
+    1
+    >>> repeater == {
+    ...     'Michael': {'age': 0.0, 'name': 'Michael', 'sex': 'm'},
+    ... }
+    1
+    >>> repeater = ConfigObj(repeated_3, configspec=repeated_5)
+    >>> repeater == {
+    ...     'dogs': {'dog1': {}, 'dog2': {}, 'dog3': {}},
+    ...     'cats': {'cat1': {}, 'cat2': {}, 'cat3': {}},
+    ... }
+    1
+    >>> repeater.validate(val)
+    1
+    >>> repeater == {
+    ...     'dogs': {'dog1': {}, 'dog2': {}, 'dog3': {}},
+    ...     'cats': {
+    ...         'cat1': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'description': {
+    ...                 'weight': 6.0,
+    ...                 'height': 3.2999999999999998,
+    ...                 'coat': {'fur': 'black', 'condition': 5},
+    ...             },
+    ...         },
+    ...         'cat2': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'description': {
+    ...                 'weight': 6.0,
+    ...                 'height': 3.2999999999999998,
+    ...                 'coat': {'fur': 'black', 'condition': 5},
+    ...             },
+    ...         },
+    ...         'cat3': {
+    ...             'fleas': True,
+    ...             'tail': 'short',
+    ...             'name': 'pussy',
+    ...             'description': {
+    ...                 'weight': 6.0,
+    ...                 'height': 3.2999999999999998,
+    ...                 'coat': {'fur': 'black', 'condition': 5},
+    ...             },
+    ...         },
+    ...     },
+    ... }
+    1
+    
+    Test that interpolation is preserved for validated string values.
+    Also check that interpolation works in configspecs.
+    >>> t = ConfigObj(configspec=['test = string'])
+    >>> t['DEFAULT'] = {}
+    >>> t['DEFAULT']['def_test'] = 'a'
+    >>> t['test'] = '%(def_test)s'
+    >>> t['test']
+    'a'
+    >>> v = Validator()
+    >>> t.validate(v)
+    1
+    >>> t.interpolation = False
+    >>> t
+    ConfigObj({'test': '%(def_test)s', 'DEFAULT': {'def_test': 'a'}})
+    >>> specs = [
+    ...    'interpolated string  = string(default="fuzzy-%(man)s")',
+    ...    '[DEFAULT]',
+    ...    'man = wuzzy',
+    ...    ]
+    >>> c = ConfigObj(configspec=specs)
+    >>> c.validate(v)
+    1
+    >>> c['interpolated string']
+    'fuzzy-wuzzy'
+
+    Test SimpleVal
+    >>> val = SimpleVal()
+    >>> config = '''
+    ... test1=40
+    ... test2=hello
+    ... test3=3
+    ... test4=5.0
+    ... [section]
+    ... test1=40
+    ... test2=hello
+    ... test3=3
+    ... test4=5.0
+    ...     [[sub section]]
+    ...     test1=40
+    ...     test2=hello
+    ...     test3=3
+    ...     test4=5.0
+    ... '''.split('\\n')
+    >>> configspec = '''
+    ... test1=''
+    ... test2=''
+    ... test3=''
+    ... test4=''
+    ... [section]
+    ... test1=''
+    ... test2=''
+    ... test3=''
+    ... test4=''
+    ...     [[sub section]]
+    ...     test1=''
+    ...     test2=''
+    ...     test3=''
+    ...     test4=''
+    ... '''.split('\\n')
+    >>> o = ConfigObj(config, configspec=configspec)
+    >>> o.validate(val)
+    1
+    >>> o = ConfigObj(configspec=configspec)
+    >>> o.validate(val)
+    0
+    
+    Test Flatten Errors
+    >>> vtor = Validator()
+    >>> my_ini = '''
+    ...     option1 = True
+    ...     [section1]
+    ...     option1 = True
+    ...     [section2]
+    ...     another_option = Probably
+    ...     [section3]
+    ...     another_option = True
+    ...     [[section3b]]
+    ...     value = 3
+    ...     value2 = a
+    ...     value3 = 11
+    ...     '''
+    >>> my_cfg = '''
+    ...     option1 = boolean()
+    ...     option2 = boolean()
+    ...     option3 = boolean(default=Bad_value)
+    ...     [section1]
+    ...     option1 = boolean()
+    ...     option2 = boolean()
+    ...     option3 = boolean(default=Bad_value)
+    ...     [section2]
+    ...     another_option = boolean()
+    ...     [section3]
+    ...     another_option = boolean()
+    ...     [[section3b]]
+    ...     value = integer
+    ...     value2 = integer
+    ...     value3 = integer(0, 10)
+    ...         [[[section3b-sub]]]
+    ...         value = string
+    ...     [section4]
+    ...     another_option = boolean()
+    ...     '''
+    >>> cs = my_cfg.split('\\n')
+    >>> ini = my_ini.split('\\n')
+    >>> cfg = ConfigObj(ini, configspec=cs)
+    >>> res = cfg.validate(vtor, preserve_errors=True)
+    >>> errors = []
+    >>> for entry in flatten_errors(cfg, res):
+    ...     section_list, key, error = entry
+    ...     section_list.insert(0, '[root]')
+    ...     if key is not None:
+    ...         section_list.append(key)
+    ...     section_string = ', '.join(section_list)
+    ...     errors.append('%s%s%s' % (section_string, ' = ', error or 'missing'))
+    >>> errors.sort()
+    >>> for entry in errors:
+    ...     print entry
+    [root], option2 = missing
+    [root], option3 = the value "Bad_value" is of the wrong type.
+    [root], section1, option2 = missing
+    [root], section1, option3 = the value "Bad_value" is of the wrong type.
+    [root], section2, another_option = the value "Probably" is of the wrong type.
+    [root], section3, section3b, section3b-sub = missing
+    [root], section3, section3b, value2 = the value "a" is of the wrong type.
+    [root], section3, section3b, value3 = the value "11" is too big.
+    [root], section4 = missing
+    """
+
+
+def _test_errors():
+    """
+    Test the error messages and objects, in normal mode and unrepr mode.
+    >>> bad_syntax = '''
+    ... key = "value"
+    ... key2 = "value
+    ... '''.splitlines()
+    >>> c = ConfigObj(bad_syntax)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 3.
+    >>> c = ConfigObj(bad_syntax, raise_errors=True)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 3.
+    >>> c = ConfigObj(bad_syntax, raise_errors=True, unrepr=True)
+    Traceback (most recent call last):
+    UnreprError: Parse error in value at line 3.
+    >>> try:
+    ...     c = ConfigObj(bad_syntax)
+    ... except Exception, e:
+    ...     pass
+    >>> assert(isinstance(e, ConfigObjError))
+    >>> print e
+    Parse error in value at line 3.
+    >>> len(e.errors) == 1
+    1
+    >>> try:
+    ...     c = ConfigObj(bad_syntax, unrepr=True)
+    ... except Exception, e:
+    ...     pass
+    >>> assert(isinstance(e, ConfigObjError))
+    >>> print e
+    Parse error in value at line 3.
+    >>> len(e.errors) == 1
+    1
+    >>> the_error = e.errors[0]
+    >>> assert(isinstance(the_error, UnreprError))
+    
+    >>> multiple_bad_syntax = '''
+    ... key = "value"
+    ... key2 = "value
+    ... key3 = "value2
+    ... '''.splitlines()
+    >>> try:
+    ...     c = ConfigObj(multiple_bad_syntax)
+    ... except ConfigObjError, e:
+    ...     str(e)
+    'Parsing failed with several errors.\\nFirst error at line 3.'
+    >>> c = ConfigObj(multiple_bad_syntax, raise_errors=True)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 3.
+    >>> c = ConfigObj(multiple_bad_syntax, raise_errors=True, unrepr=True)
+    Traceback (most recent call last):
+    UnreprError: Parse error in value at line 3.
+    >>> try:
+    ...     c = ConfigObj(multiple_bad_syntax)
+    ... except Exception, e:
+    ...     pass
+    >>> assert(isinstance(e, ConfigObjError))
+    >>> print e
+    Parsing failed with several errors.
+    First error at line 3.
+    >>> len(e.errors) == 2
+    1
+    >>> try:
+    ...     c = ConfigObj(multiple_bad_syntax, unrepr=True)
+    ... except Exception, e:
+    ...     pass
+    >>> assert(isinstance(e, ConfigObjError))
+    >>> print e
+    Parsing failed with several errors.
+    First error at line 3.
+    >>> len(e.errors) == 2
+    1
+    >>> the_error = e.errors[1]
+    >>> assert(isinstance(the_error, UnreprError))
+    
+    >>> unknown_name = '''
+    ... key = "value"
+    ... key2 = value
+    ... '''.splitlines()
+    >>> c = ConfigObj(unknown_name)
+    >>> c = ConfigObj(unknown_name, unrepr=True)
+    Traceback (most recent call last):
+    UnreprError: Unknown name or type in value at line 3.
+    >>> c = ConfigObj(unknown_name, raise_errors=True, unrepr=True)
+    Traceback (most recent call last):
+    UnreprError: Unknown name or type in value at line 3.
+    """
+
+
+def _test_unrepr_comments():
+    """
+    >>> config = '''
+    ... # initial comments
+    ... # with two lines
+    ... key = "value"
+    ... # section comment
+    ... [section] # inline section comment
+    ... # key comment
+    ... key = "value"
+    ... # final comment
+    ... # with two lines
+    ... '''.splitlines()
+    >>> c = ConfigObj(config, unrepr=True)
+    >>> c == { 'key': 'value',
+    ... 'section': { 'key': 'value'}}
+    1
+    >>> c.initial_comment == ['', '# initial comments', '# with two lines']
+    1
+    >>> c.comments == {'section': ['# section comment'], 'key': []}
+    1
+    >>> c.inline_comments == {'section': '# inline section comment', 'key': ''}
+    1
+    >>> c['section'].comments == { 'key': ['# key comment']}
+    1
+    >>> c.final_comment == ['# final comment', '# with two lines']
+    1
+    """
+
+
+def _test_newline_terminated():
+    """
+    >>> c = ConfigObj()
+    >>> c.newlines = '\\n'
+    >>> c['a'] = 'b'
+    >>> collector = StringIO()
+    >>> c.write(collector)
+    >>> collector.getvalue()
+    'a = b\\n'
+    """
+    
+    
+def _test_hash_escaping():
+    """
+    >>> c = ConfigObj()
+    >>> c.newlines = '\\n'
+    >>> c['#a'] = 'b # something'
+    >>> collector = StringIO()
+    >>> c.write(collector)
+    >>> collector.getvalue()
+    '"#a" = "b # something"\\n'
+    
+    >>> c = ConfigObj()
+    >>> c.newlines = '\\n'
+    >>> c['a'] = 'b # something', 'c # something'
+    >>> collector = StringIO()
+    >>> c.write(collector)
+    >>> collector.getvalue()
+    'a = "b # something", "c # something"\\n'
+    """
+
+
+def _test_lineendings():
+    """
+    NOTE: Need to use a real file because this code is only
+          exercised when reading from the filesystem.
+          
+    >>> h = open('temp', 'wb')
+    >>> h.write('\\r\\n')
+    >>> h.close()
+    >>> c = ConfigObj('temp')
+    >>> c.newlines
+    '\\r\\n'
+    >>> h = open('temp', 'wb')
+    >>> h.write('\\n')
+    >>> h.close()
+    >>> c = ConfigObj('temp')
+    >>> c.newlines
+    '\\n'
+    >>> os.remove('temp')
+    """
+
+
+def _test_validate_with_copy_and_many():
+    """
+    >>> spec = '''
+    ... [section]
+    ... [[__many__]]
+    ... value = string(default='nothing')
+    ... '''
+    >>> config = '''
+    ... [section]
+    ... [[something]]
+    ... '''
+    >>> c = ConfigObj(StringIO(config), configspec=StringIO(spec))
+    >>> v = Validator()
+    >>> r = c.validate(v, copy=True)
+    >>> c['section']['something']['value']
+    'nothing'
+    """
+    
+def _test_configspec_with_hash():
+    """
+    >>> spec = ['stuff = string(default="#ff00dd")']
+    >>> c = ConfigObj(spec, _inspec=True)
+    >>> c['stuff']
+    'string(default="#ff00dd")'
+    >>> c = ConfigObj(configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> c['stuff']
+    '#ff00dd'
+    
+    
+    >>> spec = ['stuff = string(default="fish") # wooble']
+    >>> c = ConfigObj(spec, _inspec=True)
+    >>> c['stuff']
+    'string(default="fish") # wooble'
+    """
+
+def _test_many_check():
+    """
+    >>> spec = ['__many__ = integer()']
+    >>> config = ['a = 6', 'b = 7']
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['a'])
+    <type 'int'>
+    >>> type(c['b'])
+    <type 'int'>
+    
+    
+    >>> spec = ['[name]', '__many__ = integer()']
+    >>> config = ['[name]', 'a = 6', 'b = 7']
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['name']['a'])
+    <type 'int'>
+    >>> type(c['name']['b'])
+    <type 'int'>
+    
+    
+    >>> spec = ['[__many__]', '__many__ = integer()']
+    >>> config = ['[name]', 'hello = 7', '[thing]', 'fish = 0']
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['name']['hello'])
+    <type 'int'>
+    >>> type(c['thing']['fish'])
+    <type 'int'>
+    
+    
+    >>> spec = '''
+    ... ___many___ = integer
+    ... [__many__]
+    ... ___many___ = boolean
+    ... [[__many__]]
+    ... __many__ = float
+    ... '''.splitlines()
+    >>> config = '''
+    ... fish = 8
+    ... buggle = 4
+    ... [hi]
+    ... one = true
+    ... two = false
+    ... [[bye]]
+    ... odd = 3
+    ... whoops = 9.0
+    ... [bye]
+    ... one = true
+    ... two = true
+    ... [[lots]]
+    ... odd = 3
+    ... whoops = 9.0
+    ... '''.splitlines()
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['fish'])
+    <type 'int'>
+    >>> type(c['buggle'])
+    <type 'int'>
+    >>> c['hi']['one']
+    1
+    >>> c['hi']['two']
+    0
+    >>> type(c['hi']['bye']['odd'])
+    <type 'float'>
+    >>> type(c['hi']['bye']['whoops'])
+    <type 'float'>
+    >>> c['bye']['one']
+    1
+    >>> c['bye']['two']
+    1
+    >>> type(c['bye']['lots']['odd'])
+    <type 'float'>
+    >>> type(c['bye']['lots']['whoops'])
+    <type 'float'>
+    
+    
+    >>> spec = ['___many___ = integer()']
+    >>> config = ['a = 6', 'b = 7']
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['a'])
+    <type 'int'>
+    >>> type(c['b'])
+    <type 'int'>
+
+    
+    >>> spec = '''
+    ... [__many__]
+    ... [[__many__]]
+    ... __many__ = float
+    ... '''.splitlines()
+    >>> config = '''
+    ... [hi]
+    ... [[bye]]
+    ... odd = 3
+    ... whoops = 9.0
+    ... [bye]
+    ... [[lots]]
+    ... odd = 3
+    ... whoops = 9.0
+    ... '''.splitlines()
+    >>> c = ConfigObj(config, configspec=spec)
+    >>> v = Validator()
+    >>> c.validate(v)
+    1
+    >>> type(c['hi']['bye']['odd'])
+    <type 'float'>
+    >>> type(c['hi']['bye']['whoops'])
+    <type 'float'>
+    >>> type(c['bye']['lots']['odd'])
+    <type 'float'>
+    >>> type(c['bye']['lots']['whoops'])
+    <type 'float'>
+    
+    >>> s = ['[dog]', '[[cow]]', 'something = boolean', '[[__many__]]', 
+    ...      'fish = integer']
+    >>> c = ['[dog]', '[[cow]]', 'something = true', '[[ob]]', 
+    ...      'fish = 3', '[[bo]]', 'fish = 6']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v)
+    1
+    >>> ini['dog']['cow']['something']
+    1
+    >>> ini['dog']['ob']['fish']
+    3
+    >>> ini['dog']['bo']['fish']
+    6
+    
+    
+    >>> s = ['[cow]', 'something = boolean', '[__many__]', 
+    ...      'fish = integer']
+    >>> c = ['[cow]', 'something = true', '[ob]', 
+    ...      'fish = 3', '[bo]', 'fish = 6']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v)
+    1
+    >>> ini['cow']['something']
+    1
+    >>> ini['ob']['fish']
+    3
+    >>> ini['bo']['fish']
+    6
+    """
+
+    
+def _unexpected_validation_errors():
+    """
+    Although the input is nonsensical we should not crash but correctly 
+    report the failure to validate
+    
+    # section specified, got scalar
+    >>> from validate import ValidateError 
+    >>> s = ['[cow]', 'something = boolean']
+    >>> c = ['cow = true']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v)
+    0
+
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> res = ini.validate(v, preserve_errors=True)
+    >>> check = flatten_errors(ini, res)
+    >>> for entry in check:
+    ...     isinstance(entry[2], ValidateError)
+    ...     print str(entry[2])
+    True
+    Section 'cow' was provided as a single value
+    
+
+    # scalar specified, got section
+    >>> s = ['something = boolean']
+    >>> c = ['[something]', 'cow = true']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v)
+    0
+    
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> res = ini.validate(v, preserve_errors=True)
+    >>> check = flatten_errors(ini, res)
+    >>> for entry in check:
+    ...     isinstance(entry[2], ValidateError)
+    ...     print str(entry[2])
+    True
+    Value 'something' was provided as a section
+    
+    # unexpected section
+    >>> s = []
+    >>> c = ['[cow]', 'dog = true']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v)
+    1
+    
+    
+    >>> s = ['[cow]', 'dog = boolean']
+    >>> c = ['[cow]', 'dog = true']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> ini.validate(v, preserve_errors=True)
+    1
+    """
+    
+def _test_pickle():
+    """
+    >>> import pickle
+    >>> s = ['[cow]', 'dog = boolean']
+    >>> c = ['[cow]', 'dog = true']
+    >>> ini = ConfigObj(c, configspec=s)
+    >>> v = Validator()
+    >>> string = pickle.dumps(ini)
+    >>> new = pickle.loads(string)
+    >>> new.validate(v)
+    1
+    """
+
+def _test_as_list():
+    """
+    >>> a = ConfigObj()
+    >>> a['a'] = 1
+    >>> a.as_list('a')
+    [1]
+    >>> a['a'] = (1,)
+    >>> a.as_list('a')
+    [1]
+    >>> a['a'] = [1]
+    >>> a.as_list('a')
+    [1]
+    """
+
+def _test_list_interpolation():
+    """
+    >>> c = ConfigObj()
+    >>> c['x'] = 'foo'
+    >>> c['list'] = ['%(x)s', 3]
+    >>> c['list']
+    ['foo', 3]
+    """
+
+def _test_extra_values():
+    """
+    >>> spec = ['[section]']
+    >>> infile = ['bar = 3', '[something]', 'foo = fish', '[section]', 'foo=boo']
+    >>> c = ConfigObj(infile, configspec=spec)
+    >>> c.extra_values
+    []
+    >>> c.extra_values = ['bar', 'gosh', 'what']
+    >>> c.validate(Validator())
+    1
+    >>> c.extra_values
+    ['bar', 'something']
+    >>> c['section'].extra_values
+    ['foo']
+    >>> c['something'].extra_values
+    []
+    """
+
+def _test_reset_and_clear_more():
+    """
+    >>> c = ConfigObj()
+    >>> c.extra_values = ['foo']
+    >>> c.defaults = ['bar']
+    >>> c.default_values = {'bar': 'baz'}
+    >>> c.clear()
+    >>> c.defaults
+    []
+    >>> c.extra_values
+    []
+    >>> c.default_values
+    {'bar': 'baz'}
+    >>> c.extra_values = ['foo']
+    >>> c.defaults = ['bar']
+    >>> c.reset()
+    >>> c.defaults
+    []
+    >>> c.extra_values
+    []
+    >>> c.default_values
+    {}
+    """
+
+def _test_invalid_lists():
+    """
+    >>> v = ['string = val, val2, , val3']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = val, val2,, val3']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = val, val2,,']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = val, ,']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = val, ,  ']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = ,,']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = ,, ']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = ,foo']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    >>> v = ['string = foo, ']
+    >>> c = ConfigObj(v)
+    >>> c['string']
+    ['foo']
+    >>> v = ['string = foo, "']
+    >>> c = ConfigObj(v)
+    Traceback (most recent call last):
+    ParseError: Parse error in value at line 1.
+    """
+
+def _test_validation_with_preserve_errors():
+    """
+    >>> v = Validator()
+    >>> spec = ['[section]', 'foo = integer']
+    >>> c = ConfigObj(configspec=spec)
+    >>> c.validate(v, preserve_errors=True)
+    {'section': False}
+    >>> c = ConfigObj(['[section]'], configspec=spec)
+    >>> c.validate(v)
+    False
+    >>> c.validate(v, preserve_errors=True)
+    {'section': {'foo': False}}
+    """
+
+
+# test _created on Section
+
+# TODO: Test BOM handling
+# TODO: Test error code for badly built multiline values
+# TODO: Test handling of StringIO
+# TODO: Test interpolation with writing
+
+
+if __name__ == '__main__':
+    # run the code tests in doctest format
+    #
+    testconfig1 = """\
+    key1= val    # comment 1
+    key2= val    # comment 2
+    # comment 3
+    [lev1a]     # comment 4
+    key1= val    # comment 5
+    key2= val    # comment 6
+    # comment 7
+    [lev1b]    # comment 8
+    key1= val    # comment 9
+    key2= val    # comment 10
+    # comment 11
+        [[lev2ba]]    # comment 12
+        key1= val    # comment 13
+        # comment 14
+        [[lev2bb]]    # comment 15
+        key1= val    # comment 16
+    # comment 17
+    [lev1c]    # comment 18
+    # comment 19
+        [[lev2c]]    # comment 20
+        # comment 21
+            [[[lev3c]]]    # comment 22
+            key1 = val    # comment 23"""
+    #
+    testconfig2 = """\
+                        key1 = 'val1'
+                        key2 =   "val2"
+                        key3 = val3
+                        ["section 1"] # comment
+                        keys11 = val1
+                        keys12 = val2
+                        keys13 = val3
+                        [section 2]
+                        keys21 = val1
+                        keys22 = val2
+                        keys23 = val3
+                        
+                            [['section 2 sub 1']]
+                            fish = 3
+    """
+    #
+    testconfig6 = '''
+    name1 = """ a single line value """ # comment
+    name2 = \''' another single line value \''' # comment
+    name3 = """ a single line value """
+    name4 = \''' another single line value \'''
+        [ "multi section" ]
+        name1 = """
+        Well, this is a
+        multiline value
+        """
+        name2 = \'''
+        Well, this is a
+        multiline value
+        \'''
+        name3 = """
+        Well, this is a
+        multiline value
+        """     # a comment
+        name4 = \'''
+        Well, this is a
+        multiline value
+        \'''  # I guess this is a comment too
+    '''
+    #
+    # these cannot be put among the doctests, because the doctest module
+    # does a string.expandtabs() on all of them, sigh
+    oneTabCfg = ['[sect]', '\t[[sect]]', '\t\tfoo = bar']
+    twoTabsCfg = ['[sect]', '\t\t[[sect]]', '\t\t\t\tfoo = bar']
+    tabsAndSpacesCfg = ['[sect]', '\t \t [[sect]]', '\t \t \t \t foo = bar']
+    #
+    import doctest
+    m = sys.modules.get('__main__')
+    globs = m.__dict__.copy()
+    a = ConfigObj(testconfig1.split('\n'), raise_errors=True)
+    b = ConfigObj(testconfig2.split('\n'), raise_errors=True)
+    i = ConfigObj(testconfig6.split('\n'), raise_errors=True)
+    globs.update({'INTP_VER': INTP_VER, 'a': a, 'b': b, 'i': i,
+        'oneTabCfg': oneTabCfg, 'twoTabsCfg': twoTabsCfg,
+        'tabsAndSpacesCfg': tabsAndSpacesCfg})
+    doctest.testmod(m, globs=globs)
+    
+    import configobj
+    doctest.testmod(configobj, globs=globs)
+
+
+# Man alive I prefer unittest ;-)

+ 7 - 22
desktop/core/ext-py/configobj/validate.py → desktop/core/ext-py/configobj-4.7.2/validate.py

@@ -1,6 +1,6 @@
 # validate.py
 # A Validator object
-# Copyright (C) 2005 Michael Foord, Mark Andrews, Nicola Larosa
+# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
 # E-mail: fuzzyman AT voidspace DOT org DOT uk
 #         mark AT la-la DOT com
 #         nico AT tekNico DOT net
@@ -128,11 +128,8 @@
     A badly formatted set of arguments will raise a ``VdtParamError``.
 """
 
-__docformat__ = "restructuredtext en"
+__version__ = '1.0.1'
 
-__version__ = '1.0.0'
-
-__revision__ = '$Id: validate.py 123 2005-09-08 08:54:28Z fuzzyman $'
 
 __all__ = (
     '__version__',
@@ -271,8 +268,6 @@ def dottedQuadToNum(ip):
     16908291
     >>> int(dottedQuadToNum('1.2.3.4'))
     16909060
-    >>> dottedQuadToNum('1.2.3. 4')
-    16909060
     >>> dottedQuadToNum('255.255.255.255')
     4294967295L
     >>> dottedQuadToNum('255.255.255.256')
@@ -287,7 +282,7 @@ def dottedQuadToNum(ip):
         return struct.unpack('!L',
             socket.inet_aton(ip.strip()))[0]
     except socket.error:
-        # bug in inet_aton, corrected in Python 2.3
+        # bug in inet_aton, corrected in Python 2.4
         if ip.strip() == '255.255.255.255':
             return 0xFFFFFFFFL
         else:
@@ -595,7 +590,7 @@ class Validator(object):
                 # no information needed here - to be handled by caller
                 raise VdtMissingValue()
             value = self._handle_none(default)
-                
+        
         if value is None:
             return None
         
@@ -604,7 +599,7 @@ class Validator(object):
 
     def _handle_none(self, value):
         if value == 'None':
-            value = None
+            return None
         elif value in ("'None'", '"None"'):
             # Special case a quoted None
             value = self._unquote(value)
@@ -620,7 +615,7 @@ class Validator(object):
             fun_kwargs = dict(fun_kwargs)
         else:
             fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
-            fun_kwargs = dict((str(key), value) for (key, value) in fun_kwargs.items())
+            fun_kwargs = dict([(str(key), value) for (key, value) in fun_kwargs.items()])
             self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default
         return fun_name, fun_args, fun_kwargs, default
         
@@ -670,17 +665,7 @@ class Validator(object):
 
         # Default must be deleted if the value is specified too,
         # otherwise the check function will get a spurious "default" keyword arg
-        try:
-            default = fun_kwargs.pop('default', None)
-        except AttributeError:
-            # Python 2.2 compatibility
-            default = None
-            try:
-                default = fun_kwargs['default']
-                del fun_kwargs['default']
-            except KeyError:
-                pass
-            
+        default = fun_kwargs.pop('default', None)
         return fun_name, fun_args, fun_kwargs, default
 
 

+ 0 - 10
desktop/core/ext-py/configobj/PKG-INFO

@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: configobj
-Version: 4.6.0
-Summary: Config file reading, writing, and validation.
-Home-page: http://www.voidspace.org.uk/python/configobj.html
-Author: Michael Foord & Nicola Larosa
-Author-email: fuzzyman@voidspace.org.uk
-License: BSD
-Description: UNKNOWN
-Platform: Platform Independent

+ 0 - 2473
desktop/core/ext-py/configobj/docs/configobj.html

@@ -1,2473 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
-<title>Reading and Writing Config Files</title>
-<meta name="authors" content="Michael Foord  Nicola Larosa" />
-<meta name="date" content="2009/04/13" />
-<meta content="ConfigObj - a Python module for easy reading and writing of config files." name="description" />
-<meta content="python, script, module, config, configuration, data, persistence, developer, configparser" name="keywords" />
-<link rel="stylesheet" href="stylesheets/voidspace_docutils.css" type="text/css" />
-</head>
-<body>
-<div class="document" id="reading-and-writing-config-files">
-<h1 class="title">Reading and Writing Config Files</h1>
-<h2 class="subtitle" id="configobj-4-introduction-and-reference">ConfigObj 4 Introduction and Reference</h2>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Authors:</th>
-<td>Michael Foord
-<br />Nicola Larosa</td></tr>
-<tr><th class="docinfo-name">Version:</th>
-<td>ConfigObj 4.6.0</td></tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>2009/04/13</td></tr>
-<tr class="field"><th class="docinfo-name">Homepage:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj Homepage</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">PyPI Entry:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/ConfigObj/">ConfigObj on PyPI</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">Development:</th><td class="field-body"><a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">License:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">Support:</th><td class="field-body"><a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a></td>
-</tr>
-</tbody>
-</table>
-<div class="contents topic" id="configobj-manual">
-<p class="topic-title first">ConfigObj Manual</p>
-<ul class="auto-toc simple">
-<li><a class="reference internal" href="#introduction" id="id26">1&nbsp;&nbsp;&nbsp;Introduction</a></li>
-<li><a class="reference internal" href="#downloading" id="id27">2&nbsp;&nbsp;&nbsp;Downloading</a><ul class="auto-toc">
-<li><a class="reference internal" href="#installing" id="id28">2.1&nbsp;&nbsp;&nbsp;Installing</a></li>
-<li><a class="reference internal" href="#documentation" id="id29">2.2&nbsp;&nbsp;&nbsp;Documentation</a></li>
-<li><a class="reference internal" href="#development-version" id="id30">2.3&nbsp;&nbsp;&nbsp;Development Version</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#configobj-in-the-real-world" id="id31">3&nbsp;&nbsp;&nbsp;ConfigObj in the Real World</a></li>
-<li><a class="reference internal" href="#getting-started" id="id32">4&nbsp;&nbsp;&nbsp;Getting Started</a><ul class="auto-toc">
-<li><a class="reference internal" href="#reading-a-config-file" id="id33">4.1&nbsp;&nbsp;&nbsp;Reading a Config File</a></li>
-<li><a class="reference internal" href="#writing-a-config-file" id="id34">4.2&nbsp;&nbsp;&nbsp;Writing a Config File</a></li>
-<li><a class="reference internal" href="#config-files" id="id35">4.3&nbsp;&nbsp;&nbsp;Config Files</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#configobj-specifications" id="id36">5&nbsp;&nbsp;&nbsp;ConfigObj specifications</a><ul class="auto-toc">
-<li><a class="reference internal" href="#infile" id="id37">5.1&nbsp;&nbsp;&nbsp;infile</a></li>
-<li><a class="reference internal" href="#options" id="id38">5.2&nbsp;&nbsp;&nbsp;options</a></li>
-<li><a class="reference internal" href="#methods" id="id39">5.3&nbsp;&nbsp;&nbsp;Methods</a><ul class="auto-toc">
-<li><a class="reference internal" href="#write" id="id40">5.3.1&nbsp;&nbsp;&nbsp;write</a></li>
-<li><a class="reference internal" href="#validate" id="id41">5.3.2&nbsp;&nbsp;&nbsp;validate</a><ul class="auto-toc">
-<li><a class="reference internal" href="#return-value" id="id42">5.3.2.1&nbsp;&nbsp;&nbsp;Return Value</a></li>
-<li><a class="reference internal" href="#mentioning-default-values" id="id43">5.3.2.2&nbsp;&nbsp;&nbsp;Mentioning Default Values</a></li>
-<li><a class="reference internal" href="#mentioning-repeated-sections-and-values" id="id44">5.3.2.3&nbsp;&nbsp;&nbsp;Mentioning Repeated Sections and Values</a></li>
-<li><a class="reference internal" href="#mentioning-simpleval" id="id45">5.3.2.4&nbsp;&nbsp;&nbsp;Mentioning SimpleVal</a></li>
-<li><a class="reference internal" href="#mentioning-copy-mode" id="id46">5.3.2.5&nbsp;&nbsp;&nbsp;Mentioning copy Mode</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#reload" id="id47">5.3.3&nbsp;&nbsp;&nbsp;reload</a></li>
-<li><a class="reference internal" href="#reset" id="id48">5.3.4&nbsp;&nbsp;&nbsp;reset</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#attributes" id="id49">5.4&nbsp;&nbsp;&nbsp;Attributes</a><ul class="auto-toc">
-<li><a class="reference internal" href="#interpolation" id="id50">5.4.1&nbsp;&nbsp;&nbsp;interpolation</a></li>
-<li><a class="reference internal" href="#stringify" id="id51">5.4.2&nbsp;&nbsp;&nbsp;stringify</a></li>
-<li><a class="reference internal" href="#bom" id="id52">5.4.3&nbsp;&nbsp;&nbsp;BOM</a></li>
-<li><a class="reference internal" href="#initial-comment" id="id53">5.4.4&nbsp;&nbsp;&nbsp;initial_comment</a></li>
-<li><a class="reference internal" href="#final-comment" id="id54">5.4.5&nbsp;&nbsp;&nbsp;final_comment</a></li>
-<li><a class="reference internal" href="#list-values" id="id55">5.4.6&nbsp;&nbsp;&nbsp;list_values</a></li>
-<li><a class="reference internal" href="#encoding" id="id56">5.4.7&nbsp;&nbsp;&nbsp;encoding</a></li>
-<li><a class="reference internal" href="#default-encoding" id="id57">5.4.8&nbsp;&nbsp;&nbsp;default_encoding</a></li>
-<li><a class="reference internal" href="#unrepr" id="id58">5.4.9&nbsp;&nbsp;&nbsp;unrepr</a></li>
-<li><a class="reference internal" href="#write-empty-values" id="id59">5.4.10&nbsp;&nbsp;&nbsp;write_empty_values</a></li>
-<li><a class="reference internal" href="#newlines" id="id60">5.4.11&nbsp;&nbsp;&nbsp;newlines</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><a class="reference internal" href="#the-config-file-format" id="id61">6&nbsp;&nbsp;&nbsp;The Config File Format</a></li>
-<li><a class="reference internal" href="#sections" id="id62">7&nbsp;&nbsp;&nbsp;Sections</a><ul class="auto-toc">
-<li><a class="reference internal" href="#section-attributes" id="id63">7.1&nbsp;&nbsp;&nbsp;Section Attributes</a></li>
-<li><a class="reference internal" href="#section-methods" id="id64">7.2&nbsp;&nbsp;&nbsp;Section Methods</a></li>
-<li><a class="reference internal" href="#walking-a-section" id="id65">7.3&nbsp;&nbsp;&nbsp;Walking a Section</a></li>
-<li><a class="reference internal" href="#examples" id="id66">7.4&nbsp;&nbsp;&nbsp;Examples</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#exceptions" id="id67">8&nbsp;&nbsp;&nbsp;Exceptions</a></li>
-<li><a class="reference internal" href="#validation" id="id68">9&nbsp;&nbsp;&nbsp;Validation</a><ul class="auto-toc">
-<li><a class="reference internal" href="#configspec" id="id69">9.1&nbsp;&nbsp;&nbsp;configspec</a></li>
-<li><a class="reference internal" href="#type-conversion" id="id70">9.2&nbsp;&nbsp;&nbsp;Type Conversion</a></li>
-<li><a class="reference internal" href="#default-values" id="id71">9.3&nbsp;&nbsp;&nbsp;Default Values</a><ul class="auto-toc">
-<li><a class="reference internal" href="#id13" id="id72">9.3.1&nbsp;&nbsp;&nbsp;List Values</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#repeated-sections" id="id73">9.4&nbsp;&nbsp;&nbsp;Repeated Sections</a></li>
-<li><a class="reference internal" href="#repeated-values" id="id74">9.5&nbsp;&nbsp;&nbsp;Repeated Values</a></li>
-<li><a class="reference internal" href="#copy-mode" id="id75">9.6&nbsp;&nbsp;&nbsp;Copy Mode</a></li>
-<li><a class="reference internal" href="#validation-and-interpolation" id="id76">9.7&nbsp;&nbsp;&nbsp;Validation and Interpolation</a></li>
-<li><a class="reference internal" href="#simpleval" id="id77">9.8&nbsp;&nbsp;&nbsp;SimpleVal</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#empty-values" id="id78">10&nbsp;&nbsp;&nbsp;Empty values</a></li>
-<li><a class="reference internal" href="#unrepr-mode" id="id79">11&nbsp;&nbsp;&nbsp;unrepr mode</a></li>
-<li><a class="reference internal" href="#string-interpolation" id="id80">12&nbsp;&nbsp;&nbsp;String Interpolation</a></li>
-<li><a class="reference internal" href="#comments" id="id81">13&nbsp;&nbsp;&nbsp;Comments</a></li>
-<li><a class="reference internal" href="#flatten-errors" id="id82">14&nbsp;&nbsp;&nbsp;flatten_errors</a><ul class="auto-toc">
-<li><a class="reference internal" href="#example-usage" id="id83">14.1&nbsp;&nbsp;&nbsp;Example Usage</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#credits" id="id84">15&nbsp;&nbsp;&nbsp;CREDITS</a></li>
-<li><a class="reference internal" href="#license" id="id85">16&nbsp;&nbsp;&nbsp;LICENSE</a></li>
-<li><a class="reference internal" href="#todo" id="id86">17&nbsp;&nbsp;&nbsp;TODO</a></li>
-<li><a class="reference internal" href="#issues" id="id87">18&nbsp;&nbsp;&nbsp;ISSUES</a></li>
-<li><a class="reference internal" href="#changelog" id="id88">19&nbsp;&nbsp;&nbsp;CHANGELOG</a><ul class="auto-toc">
-<li><a class="reference internal" href="#version-4-6-0" id="id89">19.1&nbsp;&nbsp;&nbsp;2009/04/13 - Version 4.6.0</a></li>
-<li><a class="reference internal" href="#version-4-5-3" id="id90">19.2&nbsp;&nbsp;&nbsp;2008/06/27 - Version 4.5.3</a></li>
-<li><a class="reference internal" href="#version-4-5-2" id="id91">19.3&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.2</a></li>
-<li><a class="reference internal" href="#version-4-5-1" id="id92">19.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.1</a></li>
-<li><a class="reference internal" href="#version-4-5-0" id="id93">19.5&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.0</a></li>
-<li><a class="reference internal" href="#version-4-4-0" id="id94">19.6&nbsp;&nbsp;&nbsp;2007/02/04 - Version 4.4.0</a></li>
-<li><a class="reference internal" href="#version-4-3-3-alpha4" id="id95">19.7&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha4</a></li>
-<li><a class="reference internal" href="#version-4-3-3-alpha3" id="id96">19.8&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha3</a></li>
-<li><a class="reference internal" href="#version-4-3-3-alpha2" id="id97">19.9&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha2</a></li>
-<li><a class="reference internal" href="#version-4-3-3-alpha1" id="id98">19.10&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha1</a></li>
-<li><a class="reference internal" href="#version-4-3-2" id="id99">19.11&nbsp;&nbsp;&nbsp;2006/06/04 - Version 4.3.2</a></li>
-<li><a class="reference internal" href="#version-4-3-1" id="id100">19.12&nbsp;&nbsp;&nbsp;2006/04/29 - Version 4.3.1</a></li>
-<li><a class="reference internal" href="#version-4-3-0" id="id101">19.13&nbsp;&nbsp;&nbsp;2006/03/24 - Version 4.3.0</a></li>
-<li><a class="reference internal" href="#version-4-2-0" id="id102">19.14&nbsp;&nbsp;&nbsp;2006/02/16 - Version 4.2.0</a></li>
-<li><a class="reference internal" href="#version-4-1-0" id="id103">19.15&nbsp;&nbsp;&nbsp;2005/12/14 - Version 4.1.0</a></li>
-<li><a class="reference internal" href="#version-4-0-2" id="id104">19.16&nbsp;&nbsp;&nbsp;2005/12/02 - Version 4.0.2</a></li>
-<li><a class="reference internal" href="#version-4-0-1" id="id105">19.17&nbsp;&nbsp;&nbsp;2005/11/05 - Version 4.0.1</a></li>
-<li><a class="reference internal" href="#version-4-0-0" id="id106">19.18&nbsp;&nbsp;&nbsp;2005/10/17 - Version 4.0.0</a></li>
-<li><a class="reference internal" href="#version-4-0-0-beta-5" id="id107">19.19&nbsp;&nbsp;&nbsp;2005/09/09 - Version 4.0.0 beta 5</a></li>
-<li><a class="reference internal" href="#version-4-0-0-beta-4" id="id108">19.20&nbsp;&nbsp;&nbsp;2005/09/07 - Version 4.0.0 beta 4</a></li>
-<li><a class="reference internal" href="#version-4-0-0-beta-3" id="id109">19.21&nbsp;&nbsp;&nbsp;2005/08/28 - Version 4.0.0 beta 3</a></li>
-<li><a class="reference internal" href="#version-4-0-0-beta-2" id="id110">19.22&nbsp;&nbsp;&nbsp;2005/08/25 - Version 4.0.0 beta 2</a></li>
-<li><a class="reference internal" href="#version-4-0-0-beta-1" id="id111">19.23&nbsp;&nbsp;&nbsp;2005/08/21 - Version 4.0.0 beta 1</a></li>
-<li><a class="reference internal" href="#version-3-0-0" id="id112">19.24&nbsp;&nbsp;&nbsp;2004/05/24 - Version 3.0.0</a></li>
-<li><a class="reference internal" href="#version-2-0-0-beta" id="id113">19.25&nbsp;&nbsp;&nbsp;2004/03/14 - Version 2.0.0 beta</a></li>
-<li><a class="reference internal" href="#version-1-0-5" id="id114">19.26&nbsp;&nbsp;&nbsp;2004/01/29 - Version 1.0.5</a></li>
-<li><a class="reference internal" href="#origins" id="id115">19.27&nbsp;&nbsp;&nbsp;Origins</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#footnotes" id="id116">20&nbsp;&nbsp;&nbsp;Footnotes</a></li>
-</ul>
-</div>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p>The best introduction to working with ConfigObj, including the powerful configuration validation system,
-is the article:</p>
-<ul class="last simple">
-<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
-</ul>
-</div>
-<div class="section" id="introduction">
-<h1><a class="toc-backref" href="#id26">1&nbsp;&nbsp;&nbsp;Introduction</a></h1>
-<p><strong>ConfigObj</strong> is a simple but powerful config file reader and writer: an <em>ini
-file round tripper</em>. Its main feature is that it is very easy to use, with a
-straightforward programmer's interface and a simple syntax for config files.
-It has lots of other features though :</p>
-<ul>
-<li><p class="first">Nested sections (subsections), to any level</p>
-</li>
-<li><p class="first">List values</p>
-</li>
-<li><p class="first">Multiple line values</p>
-</li>
-<li><p class="first">String interpolation (substitution)</p>
-</li>
-<li><p class="first">Integrated with a powerful validation system</p>
-<blockquote>
-<ul class="simple">
-<li>including automatic type checking/conversion</li>
-<li>repeated sections</li>
-<li>and allowing default values</li>
-</ul>
-</blockquote>
-</li>
-<li><p class="first">When writing out config files, ConfigObj preserves all comments and the order of members and sections</p>
-</li>
-<li><p class="first">Many useful methods and options for working with configuration files (like the 'reload' method)</p>
-</li>
-<li><p class="first">Full Unicode support</p>
-</li>
-</ul>
-<p>For support and bug reports please use the ConfigObj <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a> or the issue tracker on the
-<a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a>.</p>
-</div>
-<div class="section" id="downloading">
-<h1><a class="toc-backref" href="#id27">2&nbsp;&nbsp;&nbsp;Downloading</a></h1>
-<p>The current version is <strong>4.6.0</strong>, dated 13th April 2008. ConfigObj 4 is
-stable and mature. We still expect to pick up a few bugs along the way though <a class="footnote-reference" href="#id14" id="id1">[1]</a>.
- <img src="/smilies/smile.gif" alt="Smile" height="15" width="15" /> </p>
-<p>You can get ConfigObj in the following ways :</p>
-<ul>
-<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/configobj.py">configobj.py</a> from Voidspace</p>
-<blockquote>
-<p>ConfigObj has no external dependencies. This file is sufficient to access
-all the functionality except <a class="reference internal" href="#validation">Validation</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/configobj-4.6.0.zip">configobj.zip</a> from Voidspace</p>
-<blockquote>
-<p>This also contains <a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a>  and <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a> from Voidspace</p>
-</li>
-</ul>
-<div class="section" id="installing">
-<h2><a class="toc-backref" href="#id28">2.1&nbsp;&nbsp;&nbsp;Installing</a></h2>
-<p>ConfigObj has a source distribution <a class="reference external" href="http://pypi.python.org/pypi/ConfigObj/">on PyPI</a>. If you unzip
-the archive you can install it with:</p>
-<pre class="literal-block">
-setup.py install
-</pre>
-<p>Alternatively, you can install with easy install or pip:</p>
-<pre class="literal-block">
-easy_install configobj
-</pre>
-</div>
-<div class="section" id="documentation">
-<h2><a class="toc-backref" href="#id29">2.2&nbsp;&nbsp;&nbsp;Documentation</a></h2>
-<p><em>configobj.zip</em> also contains <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a>.</p>
-<ul class="simple">
-<li>You can view <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">this document</a> online at the <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj Homepage</a>.</li>
-</ul>
-</div>
-<div class="section" id="development-version">
-<h2><a class="toc-backref" href="#id30">2.3&nbsp;&nbsp;&nbsp;Development Version</a></h2>
-<p>It is sometimes possible to get the latest <em>development version</em> of ConfigObj
-from the Subversion Repository maintained on the <a class="reference external" href="http://code.google.com/p/configobj/">Google Code Homepage</a>.</p>
-</div>
-</div>
-<div class="section" id="configobj-in-the-real-world">
-<h1><a class="toc-backref" href="#id31">3&nbsp;&nbsp;&nbsp;ConfigObj in the Real World</a></h1>
-<p><strong>ConfigObj</strong> is widely used. Projects using it include:</p>
-<ul>
-<li><p class="first"><a class="reference external" href="http://bazaar-ng.org">Bazaar</a>.</p>
-<blockquote>
-<p>Bazaar is a Python distributed <acronym title="Version Control System">VCS</acronym>.
-ConfigObj is used to read <tt class="docutils literal"><span class="pre">bazaar.conf</span></tt> and <tt class="docutils literal"><span class="pre">branches.conf</span></tt>.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://chandler.osafoundation.org/">Chandler</a></p>
-<blockquote>
-<p>A Python and <a class="reference external" href="http://www.wxpython.org">wxPython</a>
-<acronym title="Personal Information Manager">PIM</acronym>, being developed by the
-<a class="reference external" href="http://www.osafoundation.org/">OSAFoundation</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://matplotlib.sourceforge.net/">matplotlib</a></p>
-<blockquote>
-<p>A 2D plotting library.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://ipython.scipy.org/moin/">IPython</a></p>
-<blockquote>
-<p>IPython is an enhanced interactive Python shell. IPython uses ConfigObj in a module called 'TConfig' that combines it with enthought <a class="reference external" href="http://code.enthought.com/traits/">Traits</a>: <a class="reference external" href="http://ipython.scipy.org/ipython/ipython/browser/ipython/branches/saw/sandbox/tconfig">tconfig</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><a class="reference external" href="http://elisa.fluendo.com/">Elisa - the Fluendo Mediacenter</a></p>
-<blockquote>
-<p>Elisa is an open source cross-platform media center solution designed to be simple for people not particularly familiar with computers.</p>
-</blockquote>
-</li>
-</ul>
-<p>Version 4.5.3 was downloaded over 25 000 times from PyPI alone.</p>
-</div>
-<div class="section" id="getting-started">
-<h1><a class="toc-backref" href="#id32">4&nbsp;&nbsp;&nbsp;Getting Started</a></h1>
-<p>The outstanding feature of using ConfigObj is simplicity. Most functions can be
-performed with single line commands.</p>
-<div class="section" id="reading-a-config-file">
-<h2><a class="toc-backref" href="#id33">4.1&nbsp;&nbsp;&nbsp;Reading a Config File</a></h2>
-<p>The normal way to read a config file, is to give ConfigObj the filename :</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>You can also pass the config file in as a list of lines, or a <tt class="docutils literal"><span class="pre">StringIO</span></tt>
-instance, so it doesn't matter where your config data comes from.</p>
-<p>You can then access members of your config file as a dictionary. Subsections
-will also be dictionaries.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">value1</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'keyword1'</span><span class="pyoperator">]</span><br />
-<span class="pytext">value2</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'keyword2'</span><span class="pyoperator">]</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">section1</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span><br />
-<span class="pytext">value3</span> <span class="pyoperator">=</span> <span class="pytext">section1</span><span class="pyoperator">[</span><span class="pystring">'keyword3'</span><span class="pyoperator">]</span><br />
-<span class="pytext">value4</span> <span class="pyoperator">=</span> <span class="pytext">section1</span><span class="pyoperator">[</span><span class="pystring">'keyword4'</span><span class="pyoperator">]</span><br />
-<span class="pycomment">#<br />
-</span><span class="pycomment"># you could also write<br />
-</span><span class="pytext">value3</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword3'</span><span class="pyoperator">]</span><br />
-<span class="pytext">value4</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword4'</span><span class="pyoperator">]</span><span class="pytext"></span></div></div>
-<div class="section" id="writing-a-config-file">
-<h2><a class="toc-backref" href="#id34">4.2&nbsp;&nbsp;&nbsp;Writing a Config File</a></h2>
-<p>Creating a new config file is just as easy as reading one. You can specify a
-filename when you create the ConfigObj, or do it later <a class="footnote-reference" href="#id15" id="id2">[2]</a>.</p>
-<p>If you <em>don't</em> set a filename, then the <tt class="docutils literal"><span class="pre">write</span></tt> method will return a list of
-lines instead of writing to file. See the <a class="reference internal" href="#write">write</a> method for more details.</p>
-<p>Here we show creating an empty ConfigObj, setting a filename and some values,
-and then writing to file :</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">filename</span> <span class="pyoperator">=</span> <span class="pytext">filename</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'keyword1'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">value1</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'keyword2'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">value2</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pyoperator">{</span><span class="pyoperator">}</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword3'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">value3</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section1'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword4'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">value4</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">section2</span> <span class="pyoperator">=</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword5'</span><span class="pyoperator">:</span> <span class="pytext">value5</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword6'</span><span class="pyoperator">:</span> <span class="pytext">value6</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'sub-section'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword7'</span><span class="pyoperator">:</span> <span class="pytext">value7</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><br />
-<span class="pyoperator">}</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section2'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">section2</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section3'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pyoperator">{</span><span class="pyoperator">}</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section3'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword 8'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pyoperator">[</span><span class="pytext">value8</span><span class="pyoperator">,</span> <span class="pytext">value9</span><span class="pyoperator">,</span> <span class="pytext">value10</span><span class="pyoperator">]</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'section3'</span><span class="pyoperator">]</span><span class="pyoperator">[</span><span class="pystring">'keyword 9'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pyoperator">[</span><span class="pytext">value11</span><span class="pyoperator">,</span> <span class="pytext">value12</span><span class="pyoperator">,</span> <span class="pytext">value13</span><span class="pyoperator">]</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">write</span><span class="pyoperator">(</span><span class="pyoperator">)</span><span class="pytext"></span></div><div class="caution">
-<p class="first admonition-title">Caution!</p>
-<p class="last">Keywords and section names can only be strings <a class="footnote-reference" href="#id16" id="id3">[3]</a>. Attempting to set
-anything else will raise a <tt class="docutils literal"><span class="pre">ValueError</span></tt>.</p>
-</div>
-</div>
-<div class="section" id="config-files">
-<h2><a class="toc-backref" href="#id35">4.3&nbsp;&nbsp;&nbsp;Config Files</a></h2>
-<p>The config files that ConfigObj will read and write are based on the 'INI'
-format. This means it will read and write files created for <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>
-<a class="footnote-reference" href="#id17" id="id4">[4]</a>.</p>
-<p>Keywords and values are separated by an <tt class="docutils literal"><span class="pre">'='</span></tt>, and section markers are
-between square brackets. Keywords, values, and section names can be surrounded
-by single or double quotes. Indentation is not significant, but can be
-preserved.</p>
-<p>Subsections are indicated by repeating the square brackets in the section
-marker. You nest levels by using more brackets.</p>
-<p>You can have list values by separating items with a comma, and values spanning
-multiple lines by using triple quotes (single or double).</p>
-<p>For full details on all these see <a class="reference internal" href="#the-config-file-format">the config file format</a>. Here's an example
-to illustrate :</p>
-<pre class="literal-block">
-# This is the 'initial_comment'
-# Which may be several lines
-keyword1 = value1
-'keyword 2' = 'value 2'
-
-[ &quot;section 1&quot; ]
-# This comment goes with keyword 3
-keyword 3 = value 3
-'keyword 4' = value4, value 5, 'value 6'
-
-    [[ sub-section ]]    # an inline comment
-    # sub-section is inside &quot;section 1&quot;
-    'keyword 5' = 'value 7'
-    'keyword 6' = '''A multiline value,
-that spans more than one line :-)
-The line breaks are included in the value.'''
-
-        [[[ sub-sub-section ]]]
-        # sub-sub-section is *in* 'sub-section'
-        # which is in 'section 1'
-        'keyword 7' = 'value 8'
-
-[section 2]    # an inline comment
-keyword8 = &quot;value 9&quot;
-keyword9 = value10     # an inline comment
-# The 'final_comment'
-# Which also may be several lines
-</pre>
-</div>
-</div>
-<div class="section" id="configobj-specifications">
-<h1><a class="toc-backref" href="#id36">5&nbsp;&nbsp;&nbsp;ConfigObj specifications</a></h1>
-<div class="pysrc"><span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">infile</span><span class="pyoperator">=</span><span class="pytext">None</span><span class="pyoperator">,</span> <span class="pytext">options</span><span class="pyoperator">=</span><span class="pytext">None</span><span class="pyoperator">,</span> <span class="pyoperator">**</span><span class="pytext">keywargs</span><span class="pyoperator">)</span><span class="pytext"></span></div><div class="section" id="infile">
-<h2><a class="toc-backref" href="#id37">5.1&nbsp;&nbsp;&nbsp;infile</a></h2>
-<p>You don't need to specify an infile. If you omit it, an empty ConfigObj will be
-created. <tt class="docutils literal"><span class="pre">infile</span></tt> <em>can</em> be :</p>
-<ul class="simple">
-<li>Nothing. In which case the <tt class="docutils literal"><span class="pre">filename</span></tt> attribute of your ConfigObj will be
-<tt class="docutils literal"><span class="pre">None</span></tt>. You can set a filename at any time.</li>
-<li>A filename. What happens if the file doesn't already exist is determined by
-the <a class="reference internal" href="#options">options</a> <tt class="docutils literal"><span class="pre">file_error</span></tt> and <tt class="docutils literal"><span class="pre">create_empty</span></tt>. The filename will be
-preserved as the <tt class="docutils literal"><span class="pre">filename</span></tt> attribute. This can be changed at any time.</li>
-<li>A list of lines. Any trailing newlines will be removed from the lines. The
-<tt class="docutils literal"><span class="pre">filename</span></tt> attribute of your ConfigObj will be <tt class="docutils literal"><span class="pre">None</span></tt>.</li>
-<li>A <tt class="docutils literal"><span class="pre">StringIO</span></tt> instance or file object, or any object with a <tt class="docutils literal"><span class="pre">read</span></tt> method.
-The <tt class="docutils literal"><span class="pre">filename</span></tt> attribute of your ConfigObj will be <tt class="docutils literal"><span class="pre">None</span></tt> <a class="footnote-reference" href="#id18" id="id5">[5]</a>.</li>
-<li>A dictionary. You can initialise a ConfigObj from a dictionary <a class="footnote-reference" href="#id19" id="id6">[6]</a>. The
-<tt class="docutils literal"><span class="pre">filename</span></tt> attribute of your ConfigObj will be <tt class="docutils literal"><span class="pre">None</span></tt>. All keys must be
-strings. In this case, the order of values and sections is arbitrary.</li>
-</ul>
-</div>
-<div class="section" id="options">
-<h2><a class="toc-backref" href="#id38">5.2&nbsp;&nbsp;&nbsp;options</a></h2>
-<p>There are various options that control the way ConfigObj behaves. They can be
-passed in as a dictionary of options, or as keyword arguments. Explicit keyword
-arguments override the dictionary.</p>
-<p>All of the options are available as attributes after the config file has been
-parsed.</p>
-<p>ConfigObj has the following options (with the default values shown) :</p>
-<ul>
-<li><p class="first">'raise_errors': <tt class="docutils literal"><span class="pre">False</span></tt></p>
-<blockquote>
-<p>When parsing, it is possible that the config file will be badly formed. The
-default is to parse the whole file and raise a single error at the end. You
-can set <tt class="docutils literal"><span class="pre">raise_errors</span> <span class="pre">=</span> <span class="pre">True</span></tt> to have errors raised immediately. See the
-<a class="reference internal" href="#exceptions">exceptions</a> section for more details.</p>
-<p>Altering this value after initial parsing has no effect.</p>
-</blockquote>
-</li>
-<li><p class="first">'list_values': <tt class="docutils literal"><span class="pre">True</span></tt></p>
-<blockquote>
-<p>If <tt class="docutils literal"><span class="pre">True</span></tt> (the default) then list values are possible. If <tt class="docutils literal"><span class="pre">False</span></tt>, the
-values are not parsed for lists.</p>
-<blockquote>
-<p>If <tt class="docutils literal"><span class="pre">list_values</span> <span class="pre">=</span> <span class="pre">False</span></tt> then single line values are not quoted or
-unquoted when reading and writing.</p>
-</blockquote>
-<p>Changing this value affects whether single line values will be quoted or
-not when writing.</p>
-</blockquote>
-</li>
-<li><p class="first">'create_empty': <tt class="docutils literal"><span class="pre">False</span></tt></p>
-<blockquote>
-<p>If this value is <tt class="docutils literal"><span class="pre">True</span></tt> and the file specified by <tt class="docutils literal"><span class="pre">infile</span></tt> doesn't
-exist, ConfigObj will create an empty file. This can be a useful test that
-the filename makes sense: an impossible filename will cause an error.</p>
-<p>Altering this value after initial parsing has no effect.</p>
-</blockquote>
-</li>
-<li><p class="first">'file_error': <tt class="docutils literal"><span class="pre">False</span></tt></p>
-<blockquote>
-<p>If this value is <tt class="docutils literal"><span class="pre">True</span></tt> and the file specified by <tt class="docutils literal"><span class="pre">infile</span></tt> doesn't
-exist, ConfigObj will raise an <tt class="docutils literal"><span class="pre">IOError</span></tt>.</p>
-<p>Altering this value after initial parsing has no effect.</p>
-</blockquote>
-</li>
-<li><p class="first">'interpolation': <tt class="docutils literal"><span class="pre">True</span></tt></p>
-<blockquote>
-<p>Whether string interpolation is switched on or not. It is on (<tt class="docutils literal"><span class="pre">True</span></tt>) by
-default.</p>
-<p>You can set this attribute to change whether string interpolation is done
-when values are fetched. See the <a class="reference internal" href="#string-interpolation">String Interpolation</a> section for more details.</p>
-</blockquote>
-</li>
-<li><p class="first">'configspec': <tt class="docutils literal"><span class="pre">None</span></tt></p>
-<blockquote>
-<p>If you want to use the validation system, you supply a configspec. This is
-effectively a type of config file that specifies a check for each member.
-This check can be used to do type conversion as well as check that the
-value is within your required parameters.</p>
-<p>You provide a configspec in the same way as you do the initial file: a
-filename, or list of lines, etc. See the <a class="reference internal" href="#validation">validation</a> section for full
-details on how to use the system.</p>
-<p>When parsed, every section has a <tt class="docutils literal"><span class="pre">configspec</span></tt> with a dictionary of
-configspec checks for <em>that section</em>.</p>
-</blockquote>
-</li>
-<li><p class="first">'stringify': <tt class="docutils literal"><span class="pre">True</span></tt></p>
-<blockquote>
-<p>If you use the validation scheme, it can do type checking <em>and</em> conversion
-for you. This means you may want to set members to integers, or other
-non-string values.</p>
-<p>If 'stringify' is set to <tt class="docutils literal"><span class="pre">True</span></tt> (default) then non-string values will
-be converted to strings when you write the config file. The <a class="reference internal" href="#validation">validation</a>
-process converts values from strings to the required type.</p>
-<p>If 'stringify' is set to <tt class="docutils literal"><span class="pre">False</span></tt>, attempting to set a member to a
-non-string value <a class="footnote-reference" href="#id20" id="id7">[7]</a> will raise a <tt class="docutils literal"><span class="pre">TypeError</span></tt> (no type conversion is
-done by validation).</p>
-</blockquote>
-</li>
-<li><p class="first">'indent_type': <tt class="docutils literal"><span class="pre">'</span>&nbsp;&nbsp;&nbsp; <span class="pre">'</span></tt></p>
-<blockquote>
-<p>Indentation is not significant; it can however be present in the input and
-output config. Any combination of tabs and spaces may be used: the string
-will be repeated for each level of indentation. Typical values are: <tt class="docutils literal"><span class="pre">''</span></tt>
-(no indentation), <tt class="docutils literal"><span class="pre">'</span>&nbsp;&nbsp;&nbsp; <span class="pre">'</span></tt> (indentation with four spaces, the default),
-<tt class="docutils literal"><span class="pre">'\t'</span></tt> (indentation with one tab).</p>
-<p>If this option is not specified, and the ConfigObj is initialised with a
-dictionary, the indentation used in the output is the default one, that is,
-four spaces.</p>
-<p>If this option is not specified, and the ConfigObj is initialised with a
-list of lines or a file, the indentation used in the first indented line is
-selected and used in all output lines. If no input line is indented, no
-output line will be either.</p>
-<p>If this option <em>is</em> specified, the option value is used in the output
-config, overriding the type of indentation in the input config (if any).</p>
-</blockquote>
-</li>
-<li><p class="first">'encoding': <tt class="docutils literal"><span class="pre">None</span></tt></p>
-<blockquote>
-<p>By default <strong>ConfigObj</strong> does not decode the file/strings you pass it into
-Unicode <a class="footnote-reference" href="#id21" id="id8">[8]</a>. If you want your config file as Unicode (keys and members)
-you need to provide an encoding to decode the file with. This encoding will
-also be used to encode the config file when writing.</p>
-<p>You can change the encoding attribute at any time.</p>
-<p>Any characters in your strings that can't be encoded with the specified
-encoding will raise a <tt class="docutils literal"><span class="pre">UnicodeEncodeError</span></tt>.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p><tt class="docutils literal"><span class="pre">UTF16</span></tt> encoded files will automatically be detected and decoded,
-even if <tt class="docutils literal"><span class="pre">encoding</span></tt> is <tt class="docutils literal"><span class="pre">None</span></tt>.</p>
-<p class="last">This is because it is a 16-bit encoding, and ConfigObj will mangle it
-(split characters on byte boundaries) if it parses it without decoding.</p>
-</div>
-</blockquote>
-</li>
-<li><p class="first">'default_encoding': <tt class="docutils literal"><span class="pre">None</span></tt></p>
-<blockquote>
-<p>When using the <tt class="docutils literal"><span class="pre">write</span></tt> method, <strong>ConfigObj</strong> uses the <tt class="docutils literal"><span class="pre">encoding</span></tt>
-attribute to encode the Unicode strings. If any members (or keys) have
-been set as byte strings instead of Unicode, these must first be decoded
-to Unicode before outputting in the specified encoding.</p>
-<p><tt class="docutils literal"><span class="pre">default_encoding</span></tt>, if specified, is the encoding used to decode byte
-strings in the <strong>ConfigObj</strong> before writing. If this is <tt class="docutils literal"><span class="pre">None</span></tt>, then
-the Python default encoding (<tt class="docutils literal"><span class="pre">sys.defaultencoding</span></tt> - usually ASCII) is
-used.</p>
-<p>For most Western European users, a value of <tt class="docutils literal"><span class="pre">latin-1</span></tt> is sensible.</p>
-<p><tt class="docutils literal"><span class="pre">default_encoding</span></tt> is <em>only</em> used if an <tt class="docutils literal"><span class="pre">encoding</span></tt> is specified.</p>
-<p>Any characters in byte-strings that can't be decoded using the
-<tt class="docutils literal"><span class="pre">default_encoding</span></tt> will raise a <tt class="docutils literal"><span class="pre">UnicodeDecodeError</span></tt>.</p>
-</blockquote>
-</li>
-<li><p class="first">'unrepr': <tt class="docutils literal"><span class="pre">False</span></tt></p>
-<blockquote>
-<p>The <tt class="docutils literal"><span class="pre">unrepr</span></tt> option reads and writes files in a different mode. This
-allows you to store and retrieve the basic Python data-types using config
-files.</p>
-<p>This uses Python syntax for lists and quoting. See <a class="reference internal" href="#unrepr-mode">unrepr mode</a> for the
-full details.</p>
-</blockquote>
-</li>
-<li><p class="first">'write_empty_values': <tt class="docutils literal"><span class="pre">False</span></tt></p>
-<blockquote>
-<p>If <tt class="docutils literal"><span class="pre">write_empty_values</span></tt> is <tt class="docutils literal"><span class="pre">True</span></tt>, empty strings are written as
-empty values. See <a class="reference internal" href="#empty-values">Empty Values</a> for more details.</p>
-</blockquote>
-</li>
-</ul>
-</div>
-<div class="section" id="methods">
-<h2><a class="toc-backref" href="#id39">5.3&nbsp;&nbsp;&nbsp;Methods</a></h2>
-<p>The ConfigObj is a subclass of an object called <tt class="docutils literal"><span class="pre">Section</span></tt>, which is itself a
-subclass of <tt class="docutils literal"><span class="pre">dict</span></tt>, the builtin dictionary type. This means it also has
-<strong>all</strong> the normal dictionary methods.</p>
-<p>In addition, the following <a class="reference internal" href="#section-methods">Section Methods</a> may be useful :</p>
-<ul class="simple">
-<li>'restore_default'</li>
-<li>'restore_defaults'</li>
-<li>'walk'</li>
-<li>'merge'</li>
-<li>'dict'</li>
-<li>'as_bool'</li>
-<li>'as_float'</li>
-<li>'as_int'</li>
-<li>'as_list'</li>
-</ul>
-<p>Read about <a class="reference internal" href="#sections">Sections</a> for details of all the methods.</p>
-<div class="hint">
-<p class="first admonition-title">Hint</p>
-<p>The <em>merge</em> method of sections is a recursive update.</p>
-<p>You can use this to merge sections, or even whole ConfigObjs, into each
-other.</p>
-<p class="last">You would typically use this to create a default ConfigObj and then merge
-in user settings. This way users only need to specify values that are
-different from the default. You can use configspecs and validation to
-achieve the same thing of course.</p>
-</div>
-<p>The public methods available on ConfigObj are :</p>
-<ul class="simple">
-<li>'write'</li>
-<li>'validate'</li>
-<li>'reset'</li>
-<li>'reload'</li>
-</ul>
-<div class="section" id="write">
-<h3><a class="toc-backref" href="#id40">5.3.1&nbsp;&nbsp;&nbsp;write</a></h3>
-<pre class="literal-block">
-write(file_object=None)
-</pre>
-<p>This method writes the current ConfigObj and takes a single, optional argument
-<a class="footnote-reference" href="#id22" id="id9">[9]</a>.</p>
-<p>If you pass in a file like object to the <tt class="docutils literal"><span class="pre">write</span></tt> method, the config file will
-be written to this. (The only method of this object that is used is its
-<tt class="docutils literal"><span class="pre">write</span></tt> method, so a <tt class="docutils literal"><span class="pre">StringIO</span></tt> instance, or any other file like object
-will work.)</p>
-<p>Otherwise, the behaviour of this method depends on the <tt class="docutils literal"><span class="pre">filename</span></tt> attribute
-of the ConfigObj.</p>
-<dl class="docutils">
-<dt><tt class="docutils literal"><span class="pre">filename</span></tt></dt>
-<dd>ConfigObj will write the configuration to the file specified.</dd>
-<dt><tt class="docutils literal"><span class="pre">None</span></tt></dt>
-<dd><tt class="docutils literal"><span class="pre">write</span></tt> returns a list of lines. (Not <tt class="docutils literal"><span class="pre">'\n'</span></tt> terminated)</dd>
-</dl>
-<p>First the 'initial_comment' is written, then the config file, followed by the
-'final_comment'. Comment lines and inline comments are written with each
-key/value.</p>
-</div>
-<div class="section" id="validate">
-<h3><a class="toc-backref" href="#id41">5.3.2&nbsp;&nbsp;&nbsp;validate</a></h3>
-<pre class="literal-block">
-validate(validator, preserve_errors=False, copy=False)
-</pre>
-<div class="pysrc"><span class="pycomment"># filename is the config file<br />
-</span><span class="pycomment"># filename2 is the configspec<br />
-</span><span class="pycomment"># (which could also be hardcoded into your program)<br />
-</span><span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">,</span> <span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pytext">filename2</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">test</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">validate</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">if</span> <span class="pytext">test</span> <span class="pyoperator">==</span> <span class="pytext">True</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'Succeeded.'</span><span class="pytext"></span></div><p>The validate method uses the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">validate</a> module to do the
-validation.</p>
-<p>This method validates the ConfigObj against the configspec. By doing type
-conversion as well it can abstract away the config file altogether and present
-the config <em>data</em> to your application (in the types it expects it to be).</p>
-<p>If the <tt class="docutils literal"><span class="pre">configspec</span></tt> attribute of the ConfigObj is <tt class="docutils literal"><span class="pre">None</span></tt>, it raises a
-<tt class="docutils literal"><span class="pre">ValueError</span></tt>.</p>
-<p>If the <a class="reference internal" href="#stringify">stringify</a> attribute is set, this process will convert values to the
-type defined in the configspec.</p>
-<p>The validate method uses checks specified in the configspec and defined in the
-<tt class="docutils literal"><span class="pre">Validator</span></tt> object. It is very easy to extend.</p>
-<p>The configspec looks like the config file, but instead of the value, you
-specify the check (and any default value). See the <a class="reference internal" href="#validation">validation</a> section for
-details.</p>
-<div class="hint">
-<p class="first admonition-title">Hint</p>
-<p>The system of configspecs can seem confusing at first, but is actually
-quite simple and powerful. The best guide to them is this article on
-ConfigObj:</p>
-<ul class="last simple">
-<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
-</ul>
-</div>
-<p>The <tt class="docutils literal"><span class="pre">copy</span></tt> parameter fills in missing values from the configspec (default
-values), <em>without</em> marking the values as defaults. It also causes comments to
-be copied from the configspec into the config file. This allows you to use a
-configspec to create default config files. (Normally default values aren't
-written out by the <tt class="docutils literal"><span class="pre">write</span></tt> method.)</p>
-<p>As of ConfigObj 4.3.0 you can also pass in a ConfigObj instance as your
-configspec. This is especially useful if you need to specify the encoding of
-your configspec file. When you read your configspec file, you <em>must</em> specify
-<tt class="docutils literal"><span class="pre">list_values=False</span></tt>. If you need to support hashes inside the configspec
-values then you must also pass in <tt class="docutils literal"><span class="pre">_inspec=True</span></tt>. This is because configspec
-files actually use a different syntax to config files and inline comment support
-must be switched off to correctly read configspec files with hashes in the values.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">configspec</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">configspecfilename</span><span class="pyoperator">,</span> <span class="pytext">encoding</span><span class="pyoperator">=</span><span class="pystring">'UTF8'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pytext">list_values</span><span class="pyoperator">=</span><span class="pytext">False</span><span class="pyoperator">,</span> <span class="pytext">_inspec</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">,</span> <span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pytext">configspec</span><span class="pyoperator">)</span><span class="pytext"></span></div><div class="section" id="return-value">
-<h4><a class="toc-backref" href="#id42">5.3.2.1&nbsp;&nbsp;&nbsp;Return Value</a></h4>
-<p>By default, the validate method either returns <tt class="docutils literal"><span class="pre">True</span></tt> (everything passed)
-or a dictionary of <tt class="docutils literal"><span class="pre">True</span></tt> / <tt class="docutils literal"><span class="pre">False</span></tt> representing pass/fail. The dictionary
-follows the structure of the ConfigObj.</p>
-<p>If a whole section passes then it is replaced with the value <tt class="docutils literal"><span class="pre">True</span></tt>. If a
-whole section fails, then it is replaced with the value <tt class="docutils literal"><span class="pre">False</span></tt>.</p>
-<p>If a value is missing, and there is no default in the check, then the check
-automatically fails.</p>
-<p>The <tt class="docutils literal"><span class="pre">validate</span></tt> method takes an optional keyword argument <tt class="docutils literal"><span class="pre">preserve_errors</span></tt>.
-If you set this to <tt class="docutils literal"><span class="pre">True</span></tt>, instead of getting <tt class="docutils literal"><span class="pre">False</span></tt> for failed checks you
-get the actual error object from the <strong>validate</strong> module. This usually contains
-useful information about why the check failed.</p>
-<p>See the <a class="reference internal" href="#flatten-errors">flatten_errors</a> function for how to turn your results dictionary into
-a useful list of error messages.</p>
-<p>Even if <tt class="docutils literal"><span class="pre">preserve_errors</span></tt> is <tt class="docutils literal"><span class="pre">True</span></tt>, missing keys or sections will still be
-represented by a <tt class="docutils literal"><span class="pre">False</span></tt> in the results dictionary.</p>
-</div>
-<div class="section" id="mentioning-default-values">
-<h4><a class="toc-backref" href="#id43">5.3.2.2&nbsp;&nbsp;&nbsp;Mentioning Default Values</a></h4>
-<p>In the check in your configspec, you can specify a default to be used - by
-using the <tt class="docutils literal"><span class="pre">default</span></tt> keyword. E.g.</p>
-<pre class="literal-block">
-key1 = integer(0, 30, default=15)
-key2 = integer(default=15)
-key3 = boolean(default=True)
-key4 = option('Hello', 'Goodbye', 'Not Today', default='Not Today')
-</pre>
-<p>If the configspec check supplies a default and the value is missing in the
-config, then the default will be set in your ConfigObj. (It is still passed to
-the <tt class="docutils literal"><span class="pre">Validator</span></tt> so that type conversion can be done: this means the default
-value must still pass the check.)</p>
-<p>ConfigObj keeps a record of which values come from defaults, using the
-<tt class="docutils literal"><span class="pre">defaults</span></tt> attribute of <a class="reference internal" href="#sections">sections</a>. Any key in this list isn't written out by
-the <tt class="docutils literal"><span class="pre">write</span></tt> method. If a key is set from outside (even to the same value)
-then it is removed from the <tt class="docutils literal"><span class="pre">defaults</span></tt> list.</p>
-<!-- note:
-
-Even if all the keys in a section are in the defaults list, the section
-marker is still written out. -->
-<p>There is additionally a special case default value of <tt class="docutils literal"><span class="pre">None</span></tt>. If you set the
-default value to <tt class="docutils literal"><span class="pre">None</span></tt> and the value is missing, the value will always be
-set to <tt class="docutils literal"><span class="pre">None</span></tt>. As the other checks don't return <tt class="docutils literal"><span class="pre">None</span></tt> (unless you
-implement your own that do), you can tell that this value came from a default
-value (and was missing from the config file). It allows an easy way of
-implementing optional values. Simply check (and ignore) members that are set
-to <tt class="docutils literal"><span class="pre">None</span></tt>.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">If <a class="reference internal" href="#stringify">stringify</a> is <tt class="docutils literal"><span class="pre">False</span></tt> then <tt class="docutils literal"><span class="pre">default=None</span></tt> returns <tt class="docutils literal"><span class="pre">''</span></tt> instead of
-<tt class="docutils literal"><span class="pre">None</span></tt>. This is because setting a value to a non-string raises an error
-if stringify is unset.</p>
-</div>
-<p>The default value can be a list. See <a class="reference internal" href="#id13">List Values</a> for the way to do this.</p>
-<p>Writing invalid default values is a <em>guaranteed</em> way of confusing your users.
-Default values <strong>must</strong> pass the check.</p>
-</div>
-<div class="section" id="mentioning-repeated-sections-and-values">
-<h4><a class="toc-backref" href="#id44">5.3.2.3&nbsp;&nbsp;&nbsp;Mentioning Repeated Sections and Values</a></h4>
-<p>In the configspec it is possible to cause <em>every</em> sub-section in a section to
-be validated using the same configspec. You do this with a section in the
-configspec  called <tt class="docutils literal"><span class="pre">__many__</span></tt>. Every sub-section in that section has the
-<tt class="docutils literal"><span class="pre">__many__</span></tt> configspec applied to it (without you having to explicitly name
-them in advance).</p>
-<p>Your <tt class="docutils literal"><span class="pre">__many__</span></tt> section can have nested subsections, which can also include
-<tt class="docutils literal"><span class="pre">__many__</span></tt> type sections.</p>
-<p>You can also specify that all values should be validated using the same configspec,
-by having a member with the name <tt class="docutils literal"><span class="pre">__many__</span></tt>. If you want to use repeated values
-along with repeated sections then you can call one of them <tt class="docutils literal"><span class="pre">___many___</span></tt> (triple
-underscores).</p>
-<p>Sections with repeated sections or values can also have specifically named sub-sections
-or values. The <tt class="docutils literal"><span class="pre">__many__</span></tt> configspec will only be used to validate entries that don't
-have an explicit configspec.</p>
-<p>See <a class="reference internal" href="#repeated-sections">Repeated Sections</a> for examples.</p>
-</div>
-<div class="section" id="mentioning-simpleval">
-<h4><a class="toc-backref" href="#id45">5.3.2.4&nbsp;&nbsp;&nbsp;Mentioning SimpleVal</a></h4>
-<p>If you just want to check if all members are present, then you can use the
-<tt class="docutils literal"><span class="pre">SimpleVal</span></tt> object that comes with ConfigObj. It only fails members if they
-are missing.</p>
-<p>Write a configspec that has all the members you want to check for, but set
-every section to <tt class="docutils literal"><span class="pre">''</span></tt>.</p>
-<div class="pysrc"><span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">SimpleVal</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">test</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">validate</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">if</span> <span class="pytext">test</span> <span class="pykeyword">is</span> <span class="pytext">True</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'Succeeded.'</span><span class="pytext"></span></div></div>
-<div class="section" id="mentioning-copy-mode">
-<h4><a class="toc-backref" href="#id46">5.3.2.5&nbsp;&nbsp;&nbsp;Mentioning copy Mode</a></h4>
-<p>As discussed in <a class="reference internal" href="#mentioning-default-values">Mentioning Default Values</a>, you can use a configspec to
-supply default values. These are marked in the ConfigObj instance as defaults,
-and <em>not</em> written out by the <tt class="docutils literal"><span class="pre">write</span></tt> mode. This means that your users only
-need to supply values that are different from the defaults.</p>
-<p>This can be inconvenient if you <em>do</em> want to write out the default values,
-for example to write out a default config file.</p>
-<p>If you set <tt class="docutils literal"><span class="pre">copy=True</span></tt> when you call validate, then no values are marked as
-defaults. In addition, all comments from the configspec are copied into
-your ConfigObj instance. You can then call <tt class="docutils literal"><span class="pre">write</span></tt> to create your config
-file.</p>
-<p>There is a limitation with this. In order to allow <a class="reference internal" href="#string-interpolation">String Interpolation</a> to work
-within configspecs, <tt class="docutils literal"><span class="pre">DEFAULT</span></tt> sections are not processed by
-validation; even in copy mode.</p>
-</div>
-</div>
-<div class="section" id="reload">
-<h3><a class="toc-backref" href="#id47">5.3.3&nbsp;&nbsp;&nbsp;reload</a></h3>
-<p>If a ConfigObj instance was loaded from the filesystem, then this method will reload it. It
-will also reuse any configspec you supplied at instantiation (including reloading it from
-the filesystem if you passed it in as a filename).</p>
-<p>If the ConfigObj does not have a filename attribute pointing to a file, then a <tt class="docutils literal"><span class="pre">ReloadError</span></tt>
-will be raised.</p>
-</div>
-<div class="section" id="reset">
-<h3><a class="toc-backref" href="#id48">5.3.4&nbsp;&nbsp;&nbsp;reset</a></h3>
-<p>This method takes no arguments and doesn't return anything. It restores a ConfigObj
-instance to a freshly created state.</p>
-</div>
-</div>
-<div class="section" id="attributes">
-<h2><a class="toc-backref" href="#id49">5.4&nbsp;&nbsp;&nbsp;Attributes</a></h2>
-<p>A ConfigObj has the following attributes :</p>
-<ul class="simple">
-<li>indent_type</li>
-<li>interpolate</li>
-<li>stringify</li>
-<li>BOM</li>
-<li>initial_comment</li>
-<li>final_comment</li>
-<li>list_values</li>
-<li>encoding</li>
-<li>default_encoding</li>
-<li>unrepr</li>
-<li>write_empty_values</li>
-<li>newlines</li>
-</ul>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">This doesn't include <em>comments</em>, <em>inline_comments</em>, <em>defaults</em>, or
-<em>configspec</em>. These are actually attributes of <a class="reference internal" href="#sections">Sections</a>.</p>
-</div>
-<p>It also has the following attributes as a result of parsing. They correspond to
-<a class="reference internal" href="#options">options</a> when the ConfigObj was created, but changing them has no effect.</p>
-<ul class="simple">
-<li>raise_errors</li>
-<li>create_empty</li>
-<li>file_error</li>
-</ul>
-<div class="section" id="interpolation">
-<h3><a class="toc-backref" href="#id50">5.4.1&nbsp;&nbsp;&nbsp;interpolation</a></h3>
-<p>ConfigObj can perform string interpolation in a <em>similar</em> way to
-<tt class="docutils literal"><span class="pre">ConfigParser</span></tt>. See the <a class="reference internal" href="#string-interpolation">String Interpolation</a> section for full details.</p>
-<p>If <tt class="docutils literal"><span class="pre">interpolation</span></tt> is set to <tt class="docutils literal"><span class="pre">False</span></tt>, then interpolation is <em>not</em> done when
-you fetch values.</p>
-</div>
-<div class="section" id="stringify">
-<h3><a class="toc-backref" href="#id51">5.4.2&nbsp;&nbsp;&nbsp;stringify</a></h3>
-<p>If this attribute is set (<tt class="docutils literal"><span class="pre">True</span></tt>) then the <a class="reference internal" href="#validate">validate</a> method changes the
-values in the ConfigObj. These are turned back into strings when <a class="reference internal" href="#write">write</a> is
-called.</p>
-<p>If stringify is unset (<tt class="docutils literal"><span class="pre">False</span></tt>) then attempting to set a value to a non
-string (or a list of strings) will raise a <tt class="docutils literal"><span class="pre">TypeError</span></tt>.</p>
-</div>
-<div class="section" id="bom">
-<h3><a class="toc-backref" href="#id52">5.4.3&nbsp;&nbsp;&nbsp;BOM</a></h3>
-<p>If the initial config file <em>started</em> with the UTF8 Unicode signature (known
-slightly incorrectly as the <acronym title="Byte Order Mark">BOM</acronym>), or the UTF16 BOM, then
-this attribute is set to <tt class="docutils literal"><span class="pre">True</span></tt>. Otherwise it is <tt class="docutils literal"><span class="pre">False</span></tt>.</p>
-<p>If it is set to <tt class="docutils literal"><span class="pre">True</span></tt> when <tt class="docutils literal"><span class="pre">write</span></tt> is called then, if <tt class="docutils literal"><span class="pre">encoding</span></tt> is set
-to <tt class="docutils literal"><span class="pre">None</span></tt> <em>or</em> to <tt class="docutils literal"><span class="pre">utf_8</span></tt> (and variants) a UTF BOM will be written.</p>
-<p>For UTF16 encodings, a BOM is <em>always</em> written.</p>
-</div>
-<div class="section" id="initial-comment">
-<h3><a class="toc-backref" href="#id53">5.4.4&nbsp;&nbsp;&nbsp;initial_comment</a></h3>
-<p>This is a list of lines. If the ConfigObj is created from an existing file, it
-will contain any lines of comments before the start of the members.</p>
-<p>If you create a new ConfigObj, this will be an empty list.</p>
-<p>The write method puts these lines before it starts writing out the members.</p>
-</div>
-<div class="section" id="final-comment">
-<h3><a class="toc-backref" href="#id54">5.4.5&nbsp;&nbsp;&nbsp;final_comment</a></h3>
-<p>This is a list of lines. If the ConfigObj is created from an existing file, it
-will contain any lines of comments after the last member.</p>
-<p>If you create a new ConfigObj, this will be an empty list.</p>
-<p>The <tt class="docutils literal"><span class="pre">write</span></tt> method puts these lines after it finishes writing out the
-members.</p>
-</div>
-<div class="section" id="list-values">
-<h3><a class="toc-backref" href="#id55">5.4.6&nbsp;&nbsp;&nbsp;list_values</a></h3>
-<p>This attribute is <tt class="docutils literal"><span class="pre">True</span></tt> or <tt class="docutils literal"><span class="pre">False</span></tt>. If set to <tt class="docutils literal"><span class="pre">False</span></tt> then values are
-not parsed for list values. In addition single line values are not unquoted.</p>
-<p>This allows you to do your own parsing of values. It exists primarily to
-support the reading of the <a class="reference internal" href="#configspec">configspec</a> - but has other use cases.</p>
-<p>For example you could use the <tt class="docutils literal"><span class="pre">LineParser</span></tt> from the
-<a class="reference external" href="http://www.voidspace.org.uk/python/listquote.html#lineparser">listquote module</a>
-to read values for nested lists.</p>
-<p>Single line values aren't quoted when writing - but multiline values are
-handled as normal.</p>
-<div class="caution">
-<p class="first admonition-title">Caution!</p>
-<dl class="docutils">
-<dt>Because values aren't quoted, leading or trailing whitespace can be</dt>
-<dd>lost.</dd>
-</dl>
-<p>This behaviour was changed in version 4.0.1.</p>
-<blockquote class="last">
-Prior to this, single line values might have been quoted; even with
-<tt class="docutils literal"><span class="pre">list_values=False</span></tt>. This means that files written by <strong>ConfigObj</strong>
-<em>could</em> now be incompatible - and need the quotes removing by hand.</blockquote>
-</div>
-</div>
-<div class="section" id="encoding">
-<h3><a class="toc-backref" href="#id56">5.4.7&nbsp;&nbsp;&nbsp;encoding</a></h3>
-<p>This is the encoding used to encode the output, when you call <tt class="docutils literal"><span class="pre">write</span></tt>. It
-must be a valid encoding <a class="reference external" href="http://docs.python.org/lib/standard-encodings.html">recognised by Python</a>.</p>
-<p>If this value is <tt class="docutils literal"><span class="pre">None</span></tt> then no encoding is done when <tt class="docutils literal"><span class="pre">write</span></tt> is called.</p>
-</div>
-<div class="section" id="default-encoding">
-<h3><a class="toc-backref" href="#id57">5.4.8&nbsp;&nbsp;&nbsp;default_encoding</a></h3>
-<p>If encoding is set, any byte-strings in your ConfigObj instance (keys or
-members) will first be decoded to Unicode using the encoding specified by the
-<tt class="docutils literal"><span class="pre">default_encoding</span></tt> attribute. This ensures that the output is in the encoding
-specified.</p>
-<p>If this value is <tt class="docutils literal"><span class="pre">None</span></tt> then <tt class="docutils literal"><span class="pre">sys.defaultencoding</span></tt> is used instead.</p>
-</div>
-<div class="section" id="unrepr">
-<h3><a class="toc-backref" href="#id58">5.4.9&nbsp;&nbsp;&nbsp;unrepr</a></h3>
-<p>Another boolean value. If this is set, then <tt class="docutils literal"><span class="pre">repr(value)</span></tt> is used to write
-values. This writes values in a slightly different way to the normal ConfigObj
-file syntax.</p>
-<p>This preserves basic Python data-types when read back in. See <a class="reference internal" href="#unrepr-mode">unrepr mode</a>
-for more details.</p>
-</div>
-<div class="section" id="write-empty-values">
-<h3><a class="toc-backref" href="#id59">5.4.10&nbsp;&nbsp;&nbsp;write_empty_values</a></h3>
-<p>Also boolean. If set, values that are an empty string (<tt class="docutils literal"><span class="pre">''</span></tt>) are written as
-empty values. See <a class="reference internal" href="#empty-values">Empty Values</a> for more details.</p>
-</div>
-<div class="section" id="newlines">
-<h3><a class="toc-backref" href="#id60">5.4.11&nbsp;&nbsp;&nbsp;newlines</a></h3>
-<p>When a config file is read, ConfigObj records the type of newline separators in the
-file and uses this separator when writing. It defaults to <tt class="docutils literal"><span class="pre">None</span></tt>, and ConfigObj
-uses the system default (<tt class="docutils literal"><span class="pre">os.sep</span></tt>) if write is called without newlines having
-been set.</p>
-</div>
-</div>
-</div>
-<div class="section" id="the-config-file-format">
-<h1><a class="toc-backref" href="#id61">6&nbsp;&nbsp;&nbsp;The Config File Format</a></h1>
-<p>You saw an example config file in the <a class="reference internal" href="#config-files">Config Files</a> section. Here is a fuller
-specification of the config files used and created by ConfigObj.</p>
-<p>The basic pattern for keywords is :</p>
-<pre class="literal-block">
-# comment line
-# comment line
-keyword = value # inline comment
-</pre>
-<p>Both keyword and value can optionally be surrounded in quotes. The equals sign
-is the only valid divider.</p>
-<p>Values can have comments on the lines above them, and an inline comment after
-them. This, of course, is optional. See the <a class="reference internal" href="#comments">comments</a> section for details.</p>
-<p>If a keyword or value starts or ends with whitespace, or contains a quote mark
-or comma, then it should be surrounded by quotes. Quotes are not necessary if
-whitespace is surrounded by non-whitespace.</p>
-<p>Values can also be lists. Lists are comma separated. You indicate a single
-member list by a trailing comma. An empty list is shown by a single comma :</p>
-<pre class="literal-block">
-keyword1 = value1, value2, value3
-keyword2 = value1, # a single member list
-keyword3 = , # an empty list
-</pre>
-<p>Values that contain line breaks (multi-line values) can be surrounded by triple
-quotes. These can also be used if a value contains both types of quotes. List
-members cannot be surrounded by triple quotes :</p>
-<pre class="literal-block">
-keyword1 = ''' A multi line value
-on several
-lines'''     # with a comment
-keyword2 = '''I won't be &quot;afraid&quot;.'''
-#
-keyword3 = &quot;&quot;&quot; A multi line value
-on several
-lines&quot;&quot;&quot;     # with a comment
-keyword4 = &quot;&quot;&quot;I won't be &quot;afraid&quot;.&quot;&quot;&quot;
-</pre>
-<div class="warning">
-<p class="first admonition-title">Warning</p>
-<p class="last">There is no way of safely quoting values that contain both types of triple
-quotes.</p>
-</div>
-<p>A line that starts with a '#', possibly preceded by whitespace, is a comment.</p>
-<p>New sections are indicated by a section marker line. That is the section name
-in square brackets. Whitespace around the section name is ignored. The name can
-be quoted with single or double quotes. The marker can have comments before it
-and an inline comment after it :</p>
-<pre class="literal-block">
-# The First Section
-[ section name 1 ] # first section
-keyword1 = value1
-
-# The Second Section
-[ &quot;section name 2&quot; ] # second section
-keyword2 = value2
-</pre>
-<p>Any subsections (sections that are <em>inside</em> the current section) are
-designated by repeating the square brackets before and after the section name.
-The number of square brackets represents the nesting level of the sub-section.
-Square brackets may be separated by whitespace; such whitespace, however, will
-not be present in the output config written by the <tt class="docutils literal"><span class="pre">write</span></tt> method.</p>
-<p>Indentation is not significant, but can be preserved. See the description of
-the <tt class="docutils literal"><span class="pre">indent_type</span></tt> option, in the <a class="reference internal" href="#configobj-specifications">ConfigObj specifications</a> chapter, for the
-details.</p>
-<p>A <em>NestingError</em> will be raised if the number of the opening and the closing
-brackets in a section marker is not the same, or if a sub-section's nesting
-level is greater than the nesting level of it parent plus one.</p>
-<p>In the outer section, single values can only appear before any sub-section.
-Otherwise they will belong to the sub-section immediately before them.</p>
-<pre class="literal-block">
-# initial comment
-keyword1 = value1
-keyword2 = value2
-
-[section 1]
-keyword1 = value1
-keyword2 = value2
-
-    [[sub-section]]
-    # this is in section 1
-    keyword1 = value1
-    keyword2 = value2
-
-        [[[nested section]]]
-        # this is in sub section
-        keyword1 = value1
-        keyword2 = value2
-
-    [[sub-section2]]
-    # this is in section 1 again
-    keyword1 = value1
-    keyword2 = value2
-
-[[sub-section3]]
-# this is also in section 1, indentation is misleading here
-keyword1 = value1
-keyword2 = value2
-
-# final comment
-</pre>
-<p>When parsed, the above config file produces the following data structure :</p>
-<div class="pysrc"><span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'section 1'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'sub-section'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'nested section'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'sub-section2'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'sub-section3'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword1'</span><span class="pyoperator">:</span> <span class="pystring">'value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'keyword2'</span><span class="pyoperator">:</span> <span class="pystring">'value2'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-<span class="pyoperator">}</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>Sections are ordered: note how the structure of the resulting ConfigObj is in
-the same order as the original file.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p>In ConfigObj 4.3.0 <em>empty values</em> became valid syntax. They are read as the
-empty string. There is also an option/attribute (<tt class="docutils literal"><span class="pre">write_empty_values</span></tt>) to
-allow the writing of these.</p>
-<p>This is mainly to support 'legacy' config files, written from other
-applications. This is documented under <a class="reference internal" href="#empty-values">Empty Values</a>.</p>
-<p class="last"><a class="reference internal" href="#unrepr-mode">unrepr mode</a> introduces <em>another</em> syntax variation, used for storing
-basic Python datatypes in config files.  <img src="/smilies/smile.gif" alt="Smile" height="15" width="15" /> </p>
-</div>
-</div>
-<div class="section" id="sections">
-<h1><a class="toc-backref" href="#id62">7&nbsp;&nbsp;&nbsp;Sections</a></h1>
-<p>Every section in a ConfigObj has certain properties. The ConfigObj itself also
-has these properties, because it too is a section (sometimes called the <em>root
-section</em>).</p>
-<p><tt class="docutils literal"><span class="pre">Section</span></tt> is a subclass of the standard new-class dictionary, therefore it
-has <strong>all</strong> the methods of a normal dictionary. This means you can <tt class="docutils literal"><span class="pre">update</span></tt>
-and <tt class="docutils literal"><span class="pre">clear</span></tt> sections.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p>You create a new section by assigning a member to be a dictionary.</p>
-<p>The new <tt class="docutils literal"><span class="pre">Section</span></tt> is created <em>from</em> the dictionary, but isn't the same
-thing as the dictionary. (So references to the dictionary you use to create
-the section <em>aren't</em> references to the new section).</p>
-<p>Note the following.</p>
-<div class="pysrc"><span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">vals</span> <span class="pyoperator">=</span> <span class="pyoperator">{</span><span class="pystring">'key1'</span><span class="pyoperator">:</span> <span class="pystring">'value 1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'key2'</span><span class="pyoperator">:</span> <span class="pystring">'value 2'</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pyoperator">}</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'vals'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">vals</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'vals'</span><span class="pyoperator">]</span> <span class="pyoperator">==</span> <span class="pytext">vals</span><br />
-<span class="pytext">True</span><br />
-<span class="pytext">config</span><span class="pyoperator">[</span><span class="pystring">'vals'</span><span class="pyoperator">]</span> <span class="pykeyword">is</span> <span class="pytext">vals</span><br />
-<span class="pytext">False</span><span class="pytext"></span></div><p class="last">If you now change <tt class="docutils literal"><span class="pre">vals</span></tt>, the changes won't be reflected in <tt class="docutils literal"><span class="pre">config['vals']</span></tt>.</p>
-</div>
-<p>A section is ordered, following its <tt class="docutils literal"><span class="pre">scalars</span></tt> and <tt class="docutils literal"><span class="pre">sections</span></tt>
-attributes documented below. This means that the following dictionary
-attributes return their results in order.</p>
-<ul>
-<li><p class="first">'__iter__'</p>
-<blockquote>
-<p>More commonly known as <tt class="docutils literal"><span class="pre">for</span> <span class="pre">member</span> <span class="pre">in</span> <span class="pre">section:</span></tt>.</p>
-</blockquote>
-</li>
-<li><p class="first">'__repr__' and '__str__'</p>
-<blockquote>
-<p>Any time you print or display the ConfigObj.</p>
-</blockquote>
-</li>
-<li><p class="first">'items'</p>
-</li>
-<li><p class="first">'iteritems'</p>
-</li>
-<li><p class="first">'iterkeys'</p>
-</li>
-<li><p class="first">'itervalues'</p>
-</li>
-<li><p class="first">'keys'</p>
-</li>
-<li><p class="first">'popitem'</p>
-</li>
-<li><p class="first">'values'</p>
-</li>
-</ul>
-<div class="section" id="section-attributes">
-<h2><a class="toc-backref" href="#id63">7.1&nbsp;&nbsp;&nbsp;Section Attributes</a></h2>
-<ul>
-<li><p class="first">main</p>
-<blockquote>
-<p>A reference to the main ConfigObj.</p>
-</blockquote>
-</li>
-<li><p class="first">parent</p>
-<blockquote>
-<p>A reference to the 'parent' section, the section that this section is a
-member of.</p>
-<p>On the ConfigObj this attribute is a reference to itself. You can use this
-to walk up the sections, stopping when <tt class="docutils literal"><span class="pre">section.parent</span> <span class="pre">is</span> <span class="pre">section</span></tt>.</p>
-</blockquote>
-</li>
-<li><p class="first">depth</p>
-<blockquote>
-<p>The nesting level of the current section.</p>
-<p>If you create a new ConfigObj and add sections, 1 will be added to the
-depth level between sections.</p>
-</blockquote>
-</li>
-<li><p class="first">defaults</p>
-<blockquote>
-<p>This attribute is a list of scalars that came from default values. Values
-that came from defaults aren't written out by the <tt class="docutils literal"><span class="pre">write</span></tt> method.
-Setting any of these values in the section removes them from the defaults
-list.</p>
-</blockquote>
-</li>
-<li><p class="first">default_values</p>
-<blockquote>
-<p>This attribute is a dictionary mapping keys to the default values for the
-keys. By default it is an empty dictionary and is populated when you
-validate the ConfigObj.</p>
-</blockquote>
-</li>
-<li><p class="first">scalars, sections</p>
-<blockquote>
-<p>These attributes are normal lists, representing the order that members,
-single values and subsections appear in the section. The order will either
-be the order of the original config file, <em>or</em> the order that you added
-members.</p>
-<p>The order of members in this lists is the order that <tt class="docutils literal"><span class="pre">write</span></tt> creates in
-the config file. The <tt class="docutils literal"><span class="pre">scalars</span></tt> list is output before the <tt class="docutils literal"><span class="pre">sections</span></tt>
-list.</p>
-<p>Adding or removing members also alters these lists. You can manipulate the
-lists directly to alter the order of members.</p>
-<div class="warning">
-<p class="first admonition-title">Warning</p>
-<p class="last">If you alter the <tt class="docutils literal"><span class="pre">scalars</span></tt>, <tt class="docutils literal"><span class="pre">sections</span></tt>, or <tt class="docutils literal"><span class="pre">defaults</span></tt> attributes
-so that they no longer reflect the contents of the section, you will
-break your ConfigObj.</p>
-</div>
-<p>See also the <tt class="docutils literal"><span class="pre">rename</span></tt> method.</p>
-</blockquote>
-</li>
-<li><p class="first">comments</p>
-<blockquote>
-<p>This is a dictionary of comments associated with each member. Each entry is
-a list of lines. These lines are written out before the member.</p>
-</blockquote>
-</li>
-<li><p class="first">inline_comments</p>
-<blockquote>
-<p>This is <em>another</em> dictionary of comments associated with each member. Each
-entry is a string that is put inline with the member.</p>
-</blockquote>
-</li>
-<li><p class="first">configspec</p>
-<blockquote>
-<p>The configspec attribute is a dictionary mapping scalars to <em>checks</em>. A
-check defines the expected type and possibly the allowed values for a
-member.</p>
-<p>The configspec has the same format as a config file, but instead of values
-it has a specification for the value (which may include a default value).
-The <a class="reference internal" href="#validate">validate</a> method uses it to check the config file makes sense. If a
-configspec is passed in when the ConfigObj is created, then it is parsed
-and broken up to become the <tt class="docutils literal"><span class="pre">configspec</span></tt> attribute of each section.</p>
-<p>If you didn't pass in a configspec, this attribute will be <tt class="docutils literal"><span class="pre">None</span></tt> on the
-root section (the main ConfigObj).</p>
-<p>You can set the configspec attribute directly on a section.</p>
-<p>See the <a class="reference internal" href="#validation">validation</a> section for full details of how to write configspecs.</p>
-</blockquote>
-</li>
-</ul>
-</div>
-<div class="section" id="section-methods">
-<h2><a class="toc-backref" href="#id64">7.2&nbsp;&nbsp;&nbsp;Section Methods</a></h2>
-<ul>
-<li><p class="first"><strong>dict</strong></p>
-<blockquote>
-<p>This method takes no arguments. It returns a deep copy of the section as a
-dictionary. All subsections will also be dictionaries, and list values will
-be copies, rather than references to the original <a class="footnote-reference" href="#id23" id="id10">[10]</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>rename</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">rename(oldkey,</span> <span class="pre">newkey)</span></tt></p>
-<p>This method renames a key, without affecting its position in the sequence.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>merge</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">merge(indict)</span></tt></p>
-<p>This method is a <em>recursive update</em> method. It allows you to merge two
-config files together.</p>
-<p>You would typically use this to create a default ConfigObj and then merge
-in user settings. This way users only need to specify values that are
-different from the default.</p>
-<p>For example :</p>
-<div class="pysrc"><span class="pycomment"># def_cfg contains your default config settings<br />
-</span><span class="pycomment"># user_cfg contains the user settings<br />
-</span><span class="pytext">cfg</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">def_cfg</span><span class="pyoperator">)</span><br />
-<span class="pytext">usr</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">user_cfg</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">cfg</span><span class="pyoperator">.</span><span class="pytext">merge</span><span class="pyoperator">(</span><span class="pytext">usr</span><span class="pyoperator">)</span><br />
-<br />
-<span class="pystring">"""<br />
-cfg now contains a combination of the default settings and the user<br />
-settings.<br />
-<br />
-The user settings will have overwritten any of the default ones.<br />
-"""</span><span class="pytext"></span></div></blockquote>
-</li>
-<li><p class="first"><strong>walk</strong></p>
-<blockquote>
-<p>This method can be used to transform values and names. See <a class="reference internal" href="#walking-a-section">walking a
-section</a> for examples and explanation.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>as_bool</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">as_bool(key)</span></tt></p>
-<p>Returns <tt class="docutils literal"><span class="pre">True</span></tt> if the key contains a string that represents <tt class="docutils literal"><span class="pre">True</span></tt>, or
-is the <tt class="docutils literal"><span class="pre">True</span></tt> object.</p>
-<p>Returns <tt class="docutils literal"><span class="pre">False</span></tt> if the key contains a string that represents <tt class="docutils literal"><span class="pre">False</span></tt>,
-or is the <tt class="docutils literal"><span class="pre">False</span></tt> object.</p>
-<p>Raises a <tt class="docutils literal"><span class="pre">ValueError</span></tt> if the key contains anything else.</p>
-<p>Strings that represent <tt class="docutils literal"><span class="pre">True</span></tt> are (not case sensitive) :</p>
-<pre class="literal-block">
-true, yes, on, 1
-</pre>
-<p>Strings that represent <tt class="docutils literal"><span class="pre">False</span></tt> are :</p>
-<pre class="literal-block">
-false, no, off, 0
-</pre>
-</blockquote>
-</li>
-<li><p class="first"><strong>as_int</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">as_int(key)</span></tt></p>
-<p>This returns the value contained in the specified key as an integer.</p>
-<p>It raises a <tt class="docutils literal"><span class="pre">ValueError</span></tt> if the conversion can't be done.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>as_float</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">as_float(key)</span></tt></p>
-<p>This returns the value contained in the specified key as a float.</p>
-<p>It raises a <tt class="docutils literal"><span class="pre">ValueError</span></tt> if the conversion can't be done.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>as_list</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">as_list(key)</span></tt></p>
-<p>This returns the value contained in the specified key as a list.</p>
-<p>If it isn't a list it will be wrapped as a list so that you can
-guarantee the returned value will be a list.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>restore_default</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">restore_default(key)</span></tt></p>
-<p>Restore (and return) the default value for the specified key.</p>
-<p>This method will only work for a ConfigObj that was created
-with a configspec and has been validated.</p>
-<p>If there is no default value for this key, <tt class="docutils literal"><span class="pre">KeyError</span></tt> is raised.</p>
-</blockquote>
-</li>
-<li><p class="first"><strong>restore_defaults</strong></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">restore_defaults()</span></tt></p>
-<p>Recursively restore default values to all members
-that have them.</p>
-<p>This method will only work for a ConfigObj that was created
-with a configspec and has been validated.</p>
-<p>It doesn't delete or modify entries without default values.</p>
-</blockquote>
-</li>
-</ul>
-</div>
-<div class="section" id="walking-a-section">
-<h2><a class="toc-backref" href="#id65">7.3&nbsp;&nbsp;&nbsp;Walking a Section</a></h2>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">The walk method allows you to call a function on every member/name.</p>
-</div>
-<div class="pysrc"><span class="pytext">walk</span><span class="pyoperator">(</span><span class="pytext">function</span><span class="pyoperator">,</span> <span class="pytext">raise_errors</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pytext">call_on_sections</span><span class="pyoperator">=</span><span class="pytext">False</span><span class="pyoperator">,</span> <span class="pyoperator">**</span><span class="pytext">keywargs</span><span class="pyoperator">)</span><span class="pyoperator">:</span><span class="pytext"></span></div><p><tt class="docutils literal"><span class="pre">walk</span></tt> is a method of the <tt class="docutils literal"><span class="pre">Section</span></tt> object. This means it is also a method
-of ConfigObj.</p>
-<p>It walks through every member and calls a function on the keyword and value. It
-walks recursively through subsections.</p>
-<p>It returns a dictionary of all the computed values.</p>
-<p>If the function raises an exception, the default is to propagate the error, and
-stop. If <tt class="docutils literal"><span class="pre">raise_errors=False</span></tt> then it sets the return value for that keyword
-to <tt class="docutils literal"><span class="pre">False</span></tt> instead, and continues. This is similar to the way <a class="reference internal" href="#validation">validation</a>
-works.</p>
-<p>Your function receives the arguments <tt class="docutils literal"><span class="pre">(section,</span> <span class="pre">key)</span></tt>. The current value is
-then <tt class="docutils literal"><span class="pre">section[key]</span></tt> <a class="footnote-reference" href="#id24" id="id11">[11]</a>. Any unrecognised keyword arguments you pass to
-walk, are passed on to the function.</p>
-<p>Normally <tt class="docutils literal"><span class="pre">walk</span></tt> just recurses into subsections. If you are transforming (or
-checking) names as well as values, then you want to be able to change the names
-of sections. In this case set <tt class="docutils literal"><span class="pre">call_on_sections</span></tt> to <tt class="docutils literal"><span class="pre">True</span></tt>. Now, on
-encountering a sub-section, <em>first</em> the function is called for the <em>whole</em>
-sub-section, and <em>then</em> it recurses into it's members. This means your function
-must be able to handle receiving dictionaries as well as strings and lists.</p>
-<p>If you are using the return value from <tt class="docutils literal"><span class="pre">walk</span></tt> <em>and</em> <tt class="docutils literal"><span class="pre">call_on_sections</span></tt>,
-note that walk discards the return value when it calls your function.</p>
-<div class="caution">
-<p class="first admonition-title">Caution!</p>
-<p class="last">You can use <tt class="docutils literal"><span class="pre">walk</span></tt> to transform the names of members of a section
-but you mustn't add or delete members.</p>
-</div>
-</div>
-<div class="section" id="examples">
-<h2><a class="toc-backref" href="#id66">7.4&nbsp;&nbsp;&nbsp;Examples</a></h2>
-<p>You can use this for transforming all values in your ConfigObj. For example
-you might like the nested lists from ConfigObj 3. This was provided by the
-<a class="reference external" href="http://www.voidspace.org.uk/python/modules.shtml#listquote">listquote</a> module. You could switch off the parsing for list values
-(<tt class="docutils literal"><span class="pre">list_values=False</span></tt>) and use listquote to parse every value.</p>
-<p>Another thing you might want to do is use the Python escape codes in your
-values. You might be <em>used</em> to using <tt class="docutils literal"><span class="pre">\n</span></tt> for line feed and <tt class="docutils literal"><span class="pre">\t</span></tt> for tab.
-Obviously we'd need to decode strings that come from the config file (using the
-escape codes). Before writing out we'll need to put the escape codes back in
-encode.</p>
-<p>As an example we'll write a function to use with walk, that encodes or decodes
-values using the <tt class="docutils literal"><span class="pre">string-escape</span></tt> codec.</p>
-<p>The function has to take each value and set the new value. As a bonus we'll
-create one function that will do decode <em>or</em> encode depending on a keyword
-argument.</p>
-<p>We don't want to work with section names, we're only transforming values, so
-we can leave <tt class="docutils literal"><span class="pre">call_on_sections</span></tt> as <tt class="docutils literal"><span class="pre">False</span></tt>. This means the two datatypes we
-have to handle are strings and lists, we can ignore everything else. (We'll
-treat tuples as lists as well).</p>
-<p>We're not using the return values, so it doesn't need to return anything, just
-change the values if appropriate.</p>
-<div class="pysrc"><span class="pykeyword">def</span> <span class="pytext">string_escape</span><span class="pyoperator">(</span><span class="pytext">section</span><span class="pyoperator">,</span> <span class="pytext">key</span><span class="pyoperator">,</span> <span class="pytext">encode</span><span class="pyoperator">=</span><span class="pytext">False</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">"""<br />
-&nbsp;&nbsp;&nbsp;&nbsp;A function to encode or decode using the 'string-escape' codec.<br />
-&nbsp;&nbsp;&nbsp;&nbsp;To be passed to the walk method of a ConfigObj.<br />
-&nbsp;&nbsp;&nbsp;&nbsp;By default it decodes.<br />
-&nbsp;&nbsp;&nbsp;&nbsp;To encode, pass in the keyword argument ``encode=True``.<br />
-&nbsp;&nbsp;&nbsp;&nbsp;"""</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">key</span><span class="pyoperator">]</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># is it a type we can work with<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># NOTE: for platforms where Python &gt; 2.2<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># you can use basestring instead of (str, unicode)<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">str</span><span class="pyoperator">,</span> <span class="pytext">unicode</span><span class="pyoperator">,</span> <span class="pytext">list</span><span class="pyoperator">,</span> <span class="pytext">tuple</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># no !<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">return</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">elif</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">str</span><span class="pyoperator">,</span> <span class="pytext">unicode</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># it's a string !<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">encode</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">key</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">val</span><span class="pyoperator">.</span><span class="pytext">decode</span><span class="pyoperator">(</span><span class="pystring">'string-escape'</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">key</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">val</span><span class="pyoperator">.</span><span class="pytext">encode</span><span class="pyoperator">(</span><span class="pystring">'string-escape'</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># it must be a list or tuple!<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># we'll be lazy and create a new list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">newval</span> <span class="pyoperator">=</span> <span class="pyoperator">[</span><span class="pyoperator">]</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># we'll check every member of the list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">for</span> <span class="pytext">entry</span> <span class="pykeyword">in</span> <span class="pytext">val</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">str</span><span class="pyoperator">,</span> <span class="pytext">unicode</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">encode</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">newval</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">.</span><span class="pytext">decode</span><span class="pyoperator">(</span><span class="pystring">'string-escape'</span><span class="pyoperator">)</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pytext">newval</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">.</span><span class="pytext">encode</span><span class="pyoperator">(</span><span class="pystring">'string-escape'</span><span class="pyoperator">)</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">newval</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># done !<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">key</span><span class="pyoperator">]</span> <span class="pyoperator">=</span>&nbsp;&nbsp;<span class="pytext">newval</span><br />
-<br />
-<span class="pycomment"># assume we have a ConfigObj called ``config``<br />
-</span><span class="pycomment">#<br />
-</span><span class="pycomment"># To decode<br />
-</span><span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">walk</span><span class="pyoperator">(</span><span class="pytext">string_escape</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pycomment"># To encode.<br />
-</span><span class="pycomment"># Because ``walk`` doesn't recognise the ``encode`` argument<br />
-</span><span class="pycomment"># it passes it to our function.<br />
-</span><span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">walk</span><span class="pyoperator">(</span><span class="pytext">string_escape</span><span class="pyoperator">,</span> <span class="pytext">encode</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>Here's a simple example of using <tt class="docutils literal"><span class="pre">walk</span></tt> to transform names and values. One
-usecase of this would be to create a <em>standard</em> config file with placeholders
-for section and keynames. You can then use walk to create new config files
-and change values and member names :</p>
-<div class="pysrc"><span class="pycomment"># We use 'XXXX' as a placeholder<br />
-</span><span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pystring">'''<br />
-XXXXkey1 = XXXXvalue1<br />
-XXXXkey2 = XXXXvalue2<br />
-XXXXkey3 = XXXXvalue3<br />
-[XXXXsection1]<br />
-XXXXkey1 = XXXXvalue1<br />
-XXXXkey2 = XXXXvalue2<br />
-XXXXkey3 = XXXXvalue3<br />
-[XXXXsection2]<br />
-XXXXkey1 = XXXXvalue1<br />
-XXXXkey2 = XXXXvalue2<br />
-XXXXkey3 = XXXXvalue3<br />
-&nbsp;&nbsp;&nbsp;&nbsp;[[XXXXsection1]]<br />
-&nbsp;&nbsp;&nbsp;&nbsp;XXXXkey1 = XXXXvalue1<br />
-&nbsp;&nbsp;&nbsp;&nbsp;XXXXkey2 = XXXXvalue2<br />
-&nbsp;&nbsp;&nbsp;&nbsp;XXXXkey3 = XXXXvalue3<br />
-'''</span><span class="pyoperator">.</span><span class="pytext">splitlines</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">cfg</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">config</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pykeyword">def</span> <span class="pytext">transform</span><span class="pyoperator">(</span><span class="pytext">section</span><span class="pyoperator">,</span> <span class="pytext">key</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">key</span><span class="pyoperator">]</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">newkey</span> <span class="pyoperator">=</span> <span class="pytext">key</span><span class="pyoperator">.</span><span class="pytext">replace</span><span class="pyoperator">(</span><span class="pystring">'XXXX'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1'</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section</span><span class="pyoperator">.</span><span class="pytext">rename</span><span class="pyoperator">(</span><span class="pytext">key</span><span class="pyoperator">,</span> <span class="pytext">newkey</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">tuple</span><span class="pyoperator">,</span> <span class="pytext">list</span><span class="pyoperator">,</span> <span class="pytext">dict</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">pass</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">val</span><span class="pyoperator">.</span><span class="pytext">replace</span><span class="pyoperator">(</span><span class="pystring">'XXXX'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1'</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section</span><span class="pyoperator">[</span><span class="pytext">newkey</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">val</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">cfg</span><span class="pyoperator">.</span><span class="pytext">walk</span><span class="pyoperator">(</span><span class="pytext">transform</span><span class="pyoperator">,</span> <span class="pytext">call_on_sections</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">print</span> <span class="pytext">cfg</span><br />
-<span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pyoperator">{</span><span class="pystring">'CLIENT1key1'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value1'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1key2'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value2'</span><span class="pyoperator">,</span><br />
-<span class="pystring">'CLIENT1key3'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value3'</span><span class="pyoperator">,</span><br />
-<span class="pystring">'CLIENT1section1'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><span class="pystring">'CLIENT1key1'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'CLIENT1key2'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value2'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1key3'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value3'</span><span class="pyoperator">}</span><span class="pyoperator">,</span><br />
-<span class="pystring">'CLIENT1section2'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><span class="pystring">'CLIENT1key1'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'CLIENT1key2'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value2'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1key3'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value3'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'CLIENT1section1'</span><span class="pyoperator">:</span> <span class="pyoperator">{</span><span class="pystring">'CLIENT1key1'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value1'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'CLIENT1key2'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value2'</span><span class="pyoperator">,</span> <span class="pystring">'CLIENT1key3'</span><span class="pyoperator">:</span> <span class="pystring">'CLIENT1value3'</span><span class="pyoperator">}</span><span class="pyoperator">}</span><span class="pyoperator">}</span><span class="pyoperator">)</span><span class="pytext"></span></div></div>
-</div>
-<div class="section" id="exceptions">
-<h1><a class="toc-backref" href="#id67">8&nbsp;&nbsp;&nbsp;Exceptions</a></h1>
-<p>There are several places where ConfigObj may raise exceptions (other than
-because of bugs).</p>
-<ol class="arabic">
-<li><dl class="first docutils">
-<dt>If a configspec filename you pass in doesn't exist, or a config file</dt>
-<dd><p class="first last">filename doesn't exist <em>and</em> <tt class="docutils literal"><span class="pre">file_error=True</span></tt>, an <tt class="docutils literal"><span class="pre">IOError</span></tt> will be
-raised.</p>
-</dd>
-</dl>
-</li>
-<li><dl class="first docutils">
-<dt>If you try to set a non-string key, or a non string value when</dt>
-<dd><p class="first last"><tt class="docutils literal"><span class="pre">stringify=False</span></tt>, a <tt class="docutils literal"><span class="pre">TypeError</span></tt> will be raised.</p>
-</dd>
-</dl>
-</li>
-<li><p class="first">A badly built config file will cause parsing errors.</p>
-</li>
-<li><p class="first">A parsing error can also occur when reading a configspec.</p>
-</li>
-<li><dl class="first docutils">
-<dt>In string interpolation you can specify a value that doesn't exist, or</dt>
-<dd><p class="first last">create circular references (recursion).</p>
-</dd>
-</dl>
-</li>
-</ol>
-<p>Number 5 (which is actually two different types of exceptions) is documented
-in <a class="reference internal" href="#string-interpolation">String Interpolation</a>.</p>
-<p><em>This</em> section is about errors raised during parsing.</p>
-<p>The base error class is <tt class="docutils literal"><span class="pre">ConfigObjError</span></tt>. This is a subclass of
-<tt class="docutils literal"><span class="pre">SyntaxError</span></tt>, so you can trap for <tt class="docutils literal"><span class="pre">SyntaxError</span></tt> without needing to
-directly import any of the ConfigObj exceptions.</p>
-<p>The following other exceptions are defined (all deriving from
-<tt class="docutils literal"><span class="pre">ConfigObjError</span></tt>) :</p>
-<ul>
-<li><p class="first"><tt class="docutils literal"><span class="pre">NestingError</span></tt></p>
-<blockquote>
-<p>This error indicates either a mismatch in the brackets in a section marker,
-or an excessive level of nesting.</p>
-</blockquote>
-</li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">ParseError</span></tt></p>
-<blockquote>
-<p>This error indicates that a line is badly written. It is neither a valid
-<tt class="docutils literal"><span class="pre">key</span> <span class="pre">=</span> <span class="pre">value</span></tt> line, nor a valid section marker line, nor a comment line.</p>
-</blockquote>
-</li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">DuplicateError</span></tt></p>
-<blockquote>
-<p>The keyword or section specified already exists.</p>
-</blockquote>
-</li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">ConfigspecError</span></tt></p>
-<blockquote>
-<p>An error occurred whilst parsing a configspec.</p>
-</blockquote>
-</li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">UnreprError</span></tt></p>
-<blockquote>
-<p>An error occurred when parsing a value in <a class="reference internal" href="#unrepr-mode">unrepr mode</a>.</p>
-</blockquote>
-</li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">ReloadError</span></tt></p>
-<blockquote>
-<p><tt class="docutils literal"><span class="pre">reload</span></tt> was called on a ConfigObj instance that doesn't have a valid
-filename attribute.</p>
-</blockquote>
-</li>
-</ul>
-<p>When parsing a configspec, ConfigObj will stop on the first error it
-encounters.  It will raise a <tt class="docutils literal"><span class="pre">ConfigspecError</span></tt>. This will have an <tt class="docutils literal"><span class="pre">error</span></tt>
-attribute, which is the actual error that was raised.</p>
-<p>Behaviour when parsing a config file depends on the option <tt class="docutils literal"><span class="pre">raise_errors</span></tt>.
-If ConfigObj encounters an error while parsing a config file:</p>
-<blockquote>
-<p>If <tt class="docutils literal"><span class="pre">raise_errors=True</span></tt> then ConfigObj will raise the appropriate error
-and parsing will stop.</p>
-<p>If <tt class="docutils literal"><span class="pre">raise_errors=False</span></tt> (the default) then parsing will continue to the
-end and <em>all</em> errors will be collected.</p>
-</blockquote>
-<p>If <tt class="docutils literal"><span class="pre">raise_errors</span></tt> is False and multiple errors are found a <tt class="docutils literal"><span class="pre">ConfigObjError</span></tt>
-is raised. The error raised has a <tt class="docutils literal"><span class="pre">config</span></tt> attribute, which is the parts of
-the ConfigObj that parsed successfully. It also has an attribute <tt class="docutils literal"><span class="pre">errors</span></tt>,
-which is a list of <em>all</em> the errors raised. Each entry in the list is an
-instance of the appropriate error type. Each one has the following attributes
-(useful for delivering a sensible error message to your user) :</p>
-<ul class="simple">
-<li><tt class="docutils literal"><span class="pre">line</span></tt>: the original line that caused the error.</li>
-<li><tt class="docutils literal"><span class="pre">line_number</span></tt>: its number in the config file.</li>
-<li><tt class="docutils literal"><span class="pre">message</span></tt>: the error message that accompanied the error.</li>
-</ul>
-<p>If only one error is found, then that error is re-raised. The error still has
-the <tt class="docutils literal"><span class="pre">config</span></tt> and <tt class="docutils literal"><span class="pre">errors</span></tt> attributes. This means that your error handling
-code can be the same whether one error is raised in parsing , or several.</p>
-<p>It also means that in the most common case (a single error) a useful error
-message will be raised.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">One wrongly written line could break the basic structure of your config
-file. This could cause every line after it to flag an error, so having a
-list of all the lines that caused errors may not be as useful as it sounds.
- <img src="/smilies/sad.gif" alt="Sad" height="15" width="15" /> .</p>
-</div>
-</div>
-<div class="section" id="validation">
-<h1><a class="toc-backref" href="#id68">9&nbsp;&nbsp;&nbsp;Validation</a></h1>
-<div class="hint">
-<p class="first admonition-title">Hint</p>
-<p>The system of configspecs can seem confusing at first, but is actually
-quite simple and powerful. The best reference is my article on ConfigObj:</p>
-<ul class="last simple">
-<li><a class="reference external" href="http://www.voidspace.org.uk/python/articles/configobj.shtml">An Introduction to ConfigObj</a></li>
-</ul>
-</div>
-<p>Validation is done through a combination of the <a class="reference internal" href="#configspec">configspec</a> and a <tt class="docutils literal"><span class="pre">Validator</span></tt>
-object. For this you need <em>validate.py</em> <a class="footnote-reference" href="#id25" id="id12">[12]</a>. See <a class="reference internal" href="#downloading">downloading</a> if you don't
-have a copy.</p>
-<p>Validation can perform two different operations :</p>
-<ol class="arabic">
-<li><dl class="first docutils">
-<dt>Check that a value meets a specification. For example, check that a value</dt>
-<dd><p class="first last">is an integer between one and six, or is a choice from a specific set of
-options.</p>
-</dd>
-</dl>
-</li>
-<li><dl class="first docutils">
-<dt>It can convert the value into the type required. For example, if one of</dt>
-<dd><p class="first last">your values is a port number, validation will turn it into an integer for
-you.</p>
-</dd>
-</dl>
-</li>
-</ol>
-<p>So validation can act as a transparent layer between the datatypes of your
-application configuration (boolean, integers, floats, etc) and the text format
-of your config file.</p>
-<div class="section" id="configspec">
-<h2><a class="toc-backref" href="#id69">9.1&nbsp;&nbsp;&nbsp;configspec</a></h2>
-<p>The <tt class="docutils literal"><span class="pre">validate</span></tt> method checks members against an entry in the configspec. Your
-configspec therefore resembles your config file, with a check for every member.</p>
-<p>In order to perform validation you need a <tt class="docutils literal"><span class="pre">Validator</span></tt> object. This has
-several useful built-in check functions. You can also create your own custom
-functions and register them with your Validator object.</p>
-<p>Each check is the name of one of these functions, including any parameters and
-keyword arguments. The configspecs look like function calls, and they map to
-function calls.</p>
-<p>The basic datatypes that an un-extended Validator can test for are :</p>
-<ul class="simple">
-<li>boolean values (True and False)</li>
-<li>integers (including minimum and maximum values)</li>
-<li>floats (including min and max)</li>
-<li>strings (including min and max length)</li>
-<li>IP addresses (v4 only)</li>
-</ul>
-<p>It can also handle lists of these types and restrict a value to being one from
-a set of options.</p>
-<p>An example configspec is going to look something like:</p>
-<pre class="literal-block">
-port = integer(0, 100)
-user = string(max=25)
-mode = option('quiet', 'loud', 'silent')
-</pre>
-<p>You can specify default values, and also have the same configspec applied to
-several sections. This is called <a class="reference internal" href="#repeated-sections">repeated sections</a>.</p>
-<p>For full details on writing configspecs, please refer to the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">validate.py
-documentation</a>.</p>
-<div class="important">
-<p class="first admonition-title">Important</p>
-<p>Your configspec is read by ConfigObj in the same way as a config file.</p>
-<p>That means you can do interpolation <em>within</em> your configspec.</p>
-<p class="last">In order to allow this, checks in the 'DEFAULT' section (of the root level
-of your configspec) are <em>not</em> used.</p>
-</div>
-<p>If you need to specify the encoding of your configspec, then you can pass in a
-ConfigObj instance as your configspec. When you read your configspec file, you
-<em>must</em> specify <tt class="docutils literal"><span class="pre">list_values=False</span></tt>. If you need to support hashes in
-configspec values then you must also pass in <tt class="docutils literal"><span class="pre">_inspec=True</span></tt>.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">configspec</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">configspecfilename</span><span class="pyoperator">,</span> <span class="pytext">encoding</span><span class="pyoperator">=</span><span class="pystring">'UTF8'</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pytext">list_values</span><span class="pyoperator">=</span><span class="pytext">False</span><span class="pyoperator">,</span> <span class="pytext">_inspec</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">,</span> <span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pytext">configspec</span><span class="pyoperator">)</span><span class="pytext"></span></div></div>
-<div class="section" id="type-conversion">
-<h2><a class="toc-backref" href="#id70">9.2&nbsp;&nbsp;&nbsp;Type Conversion</a></h2>
-<p>By default, validation does type conversion. This means that if you specify
-<tt class="docutils literal"><span class="pre">integer</span></tt> as the check, then calling <a class="reference internal" href="#validate">validate</a> will actually change the value
-to an integer (so long as the check succeeds).</p>
-<p>It also means that when you call the <a class="reference internal" href="#write">write</a> method, the value will be converted
-back into a string using the <tt class="docutils literal"><span class="pre">str</span></tt> function.</p>
-<p>To switch this off, and leave values as strings after validation, you need to
-set the <a class="reference internal" href="#stringify">stringify</a> attribute to <tt class="docutils literal"><span class="pre">False</span></tt>. If this is the case, attempting to
-set a value to a non-string will raise an error.</p>
-</div>
-<div class="section" id="default-values">
-<h2><a class="toc-backref" href="#id71">9.3&nbsp;&nbsp;&nbsp;Default Values</a></h2>
-<p>You can set a default value in your check. If the value is missing from the
-config file then this value will be used instead. This means that your user
-only has to supply values that differ from the defaults.</p>
-<p>If you <em>don't</em> supply a default then for a value to be missing is an error,
-and this will show in the <a class="reference internal" href="#return-value">return value</a> from validate.</p>
-<p>Additionally you can set the default to be <tt class="docutils literal"><span class="pre">None</span></tt>. This means the value will
-be set to <tt class="docutils literal"><span class="pre">None</span></tt> (the object) <em>whichever check is used</em>. (It will be set to
-<tt class="docutils literal"><span class="pre">''</span></tt> rather than <tt class="docutils literal"><span class="pre">None</span></tt> if <a class="reference internal" href="#stringify">stringify</a> is <tt class="docutils literal"><span class="pre">False</span></tt>). You can use this
-to easily implement optional values in your config files.</p>
-<pre class="literal-block">
-port = integer(0, 100, default=80)
-user = string(max=25, default=0)
-mode = option('quiet', 'loud', 'silent', default='loud')
-nick = string(default=None)
-</pre>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p>Because the default goes through type conversion, it also has to pass the
-check.</p>
-<p class="last">Note that <tt class="docutils literal"><span class="pre">default=None</span></tt> is case sensitive.</p>
-</div>
-<div class="section" id="id13">
-<h3><a class="toc-backref" href="#id72">9.3.1&nbsp;&nbsp;&nbsp;List Values</a></h3>
-<p>It's possible that you will want to specify a list as a default value. To avoid
-confusing syntax with commas and quotes you use a list constructor to specify
-that keyword arguments are lists. This includes the <tt class="docutils literal"><span class="pre">default</span></tt> value. This
-makes checks look something like :</p>
-<pre class="literal-block">
-checkname(default=list('val1', 'val2', 'val3'))
-</pre>
-<p>This works with all keyword arguments, but is most useful for default values.</p>
-</div>
-</div>
-<div class="section" id="repeated-sections">
-<h2><a class="toc-backref" href="#id73">9.4&nbsp;&nbsp;&nbsp;Repeated Sections</a></h2>
-<p>Repeated sections are a way of specifying a configspec for a section that
-should be applied to all unspecified subsections in the same section.</p>
-<p>The easiest way of explaining this is to give an example. Suppose you have a
-config file that describes a dog. That dog has various attributes, but it can
-also have many fleas. You don't know in advance how many fleas there will be,
-or what they will be called, but you want each flea validated against the same
-configspec.</p>
-<p>We can define a section called <em>fleas</em>. We want every flea in that section
-(every sub-section) to have the same configspec applied to it. We do this by
-defining a single section called <tt class="docutils literal"><span class="pre">__many__</span></tt>.</p>
-<pre class="literal-block">
-[dog]
-name = string(default=Rover)
-age = float(0, 99, default=0)
-
-    [[fleas]]
-
-        [[[__many__]]]
-        bloodsucker = boolean(default=True)
-        children = integer(default=10000)
-        size = option(small, tiny, micro, default=tiny)
-</pre>
-<p>Every flea on our dog will now be validated using the <tt class="docutils literal"><span class="pre">__many__</span></tt> configspec.</p>
-<p><tt class="docutils literal"><span class="pre">__many__</span></tt> sections can have sub-sections, including their own <tt class="docutils literal"><span class="pre">__many__</span></tt>
-sub-sections. Defaults work in the normal way in repeated sections.</p>
-</div>
-<div class="section" id="repeated-values">
-<h2><a class="toc-backref" href="#id74">9.5&nbsp;&nbsp;&nbsp;Repeated Values</a></h2>
-<p>As well as using <tt class="docutils literal"><span class="pre">__many__</span></tt> to validate unspecified sections you can use it to validate values. For
-example, to specify that all values in a section should be integers:</p>
-<pre class="literal-block">
-[section]
-    __many__ = integer
-</pre>
-<p>If you want to use repeated values alongside repeated sections you can call one <tt class="docutils literal"><span class="pre">__many__</span></tt> and the
-other <tt class="docutils literal"><span class="pre">___many___</span></tt> (with three underscores).</p>
-</div>
-<div class="section" id="copy-mode">
-<h2><a class="toc-backref" href="#id75">9.6&nbsp;&nbsp;&nbsp;Copy Mode</a></h2>
-<p>Because you can specify default values in your configspec, you can use
-ConfigObj to write out default config files for your application.</p>
-<p>However, normally values supplied from a default in a configspec are <em>not</em>
-written out by the <tt class="docutils literal"><span class="pre">write</span></tt> method.</p>
-<p>To do this, you need to specify <tt class="docutils literal"><span class="pre">copy=True</span></tt> when you call validate. As well
-as not marking values as default, all the comments in the configspec file
-will be copied into your ConfigObj instance.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pytext">vdt</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pystring">'default.ini'</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">filename</span> <span class="pyoperator">=</span> <span class="pystring">'new_default.ini'</span><br />
-<span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">validate</span><span class="pyoperator">(</span><span class="pytext">vdt</span><span class="pyoperator">,</span> <span class="pytext">copy</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">write</span><span class="pyoperator">(</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>If you need to support hashes in the configspec values then you must create
-it with <tt class="docutils literal"><span class="pre">_inspec=True</span></tt>. This has the side effect of switching off the parsing
-of inline comments, meaning that they won't be copied into the new config file.
-(ConfigObj syntax is slightly different from configspec syntax and the parser
-can't support both inline comments and hashes in configspec values.)</p>
-</div>
-<div class="section" id="validation-and-interpolation">
-<h2><a class="toc-backref" href="#id76">9.7&nbsp;&nbsp;&nbsp;Validation and Interpolation</a></h2>
-<p>String interpolation and validation don't play well together. When validation
-changes type it sets the value. If the value uses interpolation, then the
-interpolation reference would normally be overwritten. Calling <tt class="docutils literal"><span class="pre">write</span></tt> would
-then use the absolute value and the interpolation reference would be lost.</p>
-<p>As a compromise - if the value is unchanged by validation then it is not reset.
-This means strings that pass through validation unmodified will not be
-overwritten. If validation changes type - the value has to be overwritten, and
-any interpolation references are lost  <img src="/smilies/sad.gif" alt="Sad" height="15" width="15" /> .</p>
-</div>
-<div class="section" id="simpleval">
-<h2><a class="toc-backref" href="#id77">9.8&nbsp;&nbsp;&nbsp;SimpleVal</a></h2>
-<p>You may not need a full validation process, but still want to check if all the
-expected values are present.</p>
-<p>Provided as part of the ConfigObj module is the <tt class="docutils literal"><span class="pre">SimpleVal</span></tt> object. This has
-a dummy <tt class="docutils literal"><span class="pre">test</span></tt> method that always passes.</p>
-<p>The only reason a test will fail is if the value is missing. The return value
-from <tt class="docutils literal"><span class="pre">validate</span></tt> will either be <tt class="docutils literal"><span class="pre">True</span></tt>, meaning all present, or a dictionary
-with <tt class="docutils literal"><span class="pre">False</span></tt> for all missing values/sections.</p>
-<p>To use it, you still need to pass in a valid configspec when you create the
-ConfigObj, but just set all the values to <tt class="docutils literal"><span class="pre">''</span></tt>. Then create an instance of
-<tt class="docutils literal"><span class="pre">SimpleVal</span></tt> and pass it to the <tt class="docutils literal"><span class="pre">validate</span></tt> method.</p>
-<p>As a trivial example if you had the following config file :</p>
-<pre class="literal-block">
-# config file for an application
-port = 80
-protocol = http
-domain = voidspace
-top_level_domain = org.uk
-</pre>
-<p>You would write the following configspec :</p>
-<pre class="literal-block">
-port = ''
-protocol = ''
-domain = ''
-top_level_domain = ''
-</pre>
-<div class="pysrc"><span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">Configobj</span><span class="pyoperator">(</span><span class="pytext">filename</span><span class="pyoperator">,</span> <span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pytext">configspec</span><span class="pyoperator">)</span><br />
-<span class="pytext">val</span> <span class="pyoperator">=</span> <span class="pytext">SimpleVal</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">test</span> <span class="pyoperator">=</span> <span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">validate</span><span class="pyoperator">(</span><span class="pytext">val</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">if</span> <span class="pytext">test</span> <span class="pyoperator">==</span> <span class="pytext">True</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'All values present.'</span><br />
-<span class="pykeyword">elif</span> <span class="pytext">test</span> <span class="pyoperator">==</span> <span class="pytext">False</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'No values present!'</span><br />
-<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">for</span> <span class="pytext">entry</span> <span class="pykeyword">in</span> <span class="pytext">test</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">test</span><span class="pyoperator">[</span><span class="pytext">entry</span><span class="pyoperator">]</span> <span class="pyoperator">==</span> <span class="pytext">False</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'"%s" missing.'</span> <span class="pyoperator">%</span> <span class="pytext">entry</span><span class="pytext"></span></div></div>
-</div>
-<div class="section" id="empty-values">
-<h1><a class="toc-backref" href="#id78">10&nbsp;&nbsp;&nbsp;Empty values</a></h1>
-<p>Many config files from other applications allow empty values. As of version
-4.3.0, ConfigObj will read these as an empty string.</p>
-<p>A new option/attribute has been added (<tt class="docutils literal"><span class="pre">write_empty_values</span></tt>) to allow
-ConfigObj to write empty strings as empty values.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">configobj</span> <span class="pykeyword">import</span> <span class="pytext">ConfigObj</span><br />
-<span class="pytext">cfg</span> <span class="pyoperator">=</span> <span class="pystring">'''<br />
-&nbsp;&nbsp;&nbsp;&nbsp;key =<br />
-&nbsp;&nbsp;&nbsp;&nbsp;key2 = # a comment<br />
-'''</span><span class="pyoperator">.</span><span class="pytext">splitlines</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">config</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">cfg</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">print</span> <span class="pytext">config</span><br />
-<span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pyoperator">{</span><span class="pystring">'key'</span><span class="pyoperator">:</span> <span class="pystring">''</span><span class="pyoperator">,</span> <span class="pystring">'key2'</span><span class="pyoperator">:</span> <span class="pystring">''</span><span class="pyoperator">}</span><span class="pyoperator">)</span><br />
-<br />
-<span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">write_empty_values</span> <span class="pyoperator">=</span> <span class="pytext">True</span><br />
-<span class="pykeyword">for</span> <span class="pytext">line</span> <span class="pykeyword">in</span> <span class="pytext">config</span><span class="pyoperator">.</span><span class="pytext">write</span><span class="pyoperator">(</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pytext">line</span><br />
-<br />
-<span class="pytext">key</span> <span class="pyoperator">=</span><br />
-<span class="pytext">key2</span> <span class="pyoperator">=</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="pycomment"># a comment</span><span class="pytext"></span></div></div>
-<div class="section" id="unrepr-mode">
-<h1><a class="toc-backref" href="#id79">11&nbsp;&nbsp;&nbsp;unrepr mode</a></h1>
-<p>The <tt class="docutils literal"><span class="pre">unrepr</span></tt> option allows you to store and retrieve the basic Python
-data-types using config files. It has to use a slightly different syntax to
-normal ConfigObj files. Unsurprisingly it uses Python syntax.</p>
-<p>This means that lists are different (they are surrounded by square brackets),
-and strings <em>must</em> be quoted.</p>
-<p>The types that <tt class="docutils literal"><span class="pre">unrepr</span></tt> can work with are :</p>
-<blockquote>
-<div class="line-block">
-<div class="line">strings, lists tuples</div>
-<div class="line">None, True, False</div>
-<div class="line">dictionaries, integers, floats</div>
-<div class="line">longs and complex numbers</div>
-</div>
-</blockquote>
-<p>You can't store classes, types or instances.</p>
-<p><tt class="docutils literal"><span class="pre">unrepr</span></tt> uses <tt class="docutils literal"><span class="pre">repr(object)</span></tt> to write out values, so it currently <em>doesn't</em>
-check that you are writing valid objects. If you attempt to read an unsupported
-value, ConfigObj will raise a <tt class="docutils literal"><span class="pre">configobj.UnknownType</span></tt> exception.</p>
-<p>Values that are triple quoted cased. The triple quotes are removed <em>before</em>
-converting. This means that you can use triple quotes to write dictionaries
-over several lines in your config files. They won't be written like this
-though.</p>
-<p>If you are writing config files by hand, for use with <tt class="docutils literal"><span class="pre">unrepr</span></tt>, you should
-be aware of the following differences from normal ConfigObj syntax :</p>
-<blockquote>
-<div class="line-block">
-<div class="line">List : <tt class="docutils literal"><span class="pre">['A</span> <span class="pre">List',</span> <span class="pre">'With',</span> <span class="pre">'Strings']</span></tt></div>
-<div class="line">Strings : <tt class="docutils literal"><span class="pre">&quot;Must</span> <span class="pre">be</span> <span class="pre">quoted.&quot;</span></tt></div>
-<div class="line">Backslash : <tt class="docutils literal"><span class="pre">&quot;The</span> <span class="pre">backslash</span> <span class="pre">must</span> <span class="pre">be</span> <span class="pre">escaped</span> <span class="pre">\\&quot;</span></tt></div>
-</div>
-</blockquote>
-<p>These all follow normal Python syntax.</p>
-<p>In unrepr mode <em>inline comments</em> are not saved. This is because lines are
-parsed using the <a class="reference external" href="http://docs.python.org/lib/compiler.html">compiler package</a>
-which discards comments.</p>
-</div>
-<div class="section" id="string-interpolation">
-<h1><a class="toc-backref" href="#id80">12&nbsp;&nbsp;&nbsp;String Interpolation</a></h1>
-<p>ConfigObj allows string interpolation <em>similar</em> to the way <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>
-or <tt class="docutils literal"><span class="pre">string.Template</span></tt> work. The value of the <tt class="docutils literal"><span class="pre">interpolation</span></tt> attribute
-determines which style of interpolation you want to use. Valid values are
-&quot;ConfigParser&quot; or &quot;Template&quot; (case-insensitive, so &quot;configparser&quot; and
-&quot;template&quot; will also work). For backwards compatibility reasons, the value
-<tt class="docutils literal"><span class="pre">True</span></tt> is also a valid value for the <tt class="docutils literal"><span class="pre">interpolation</span></tt> attribute, and
-will select <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>-style interpolation. At some undetermined point
-in the future, that default <em>may</em> change to <tt class="docutils literal"><span class="pre">Template</span></tt>-style interpolation.</p>
-<p>For <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>-style interpolation, you specify a value to be
-substituted by including <tt class="docutils literal"><span class="pre">%(name)s</span></tt> in the value.</p>
-<p>For <tt class="docutils literal"><span class="pre">Template</span></tt>-style interpolation, you specify a value to be substituted
-by including <tt class="docutils literal"><span class="pre">${name}</span></tt> in the value. Alternately, if 'name' is a valid
-Python identifier (i.e., is composed of nothing but alphanumeric characters,
-plus the underscore character), then the braces are optional and the value
-can be written as <tt class="docutils literal"><span class="pre">$name</span></tt>.</p>
-<p>Note that <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>-style interpolation and <tt class="docutils literal"><span class="pre">Template</span></tt>-style
-interpolation are mutually exclusive; you cannot have a configuration file
-that's a mix of one or the other. Pick one and stick to it. <tt class="docutils literal"><span class="pre">Template</span></tt>-style
-interpolation is simpler to read and write by hand, and is recommended if
-you don't have a particular reason to use <tt class="docutils literal"><span class="pre">ConfigParser</span></tt>-style.</p>
-<p>Interpolation checks first the current section to see if <tt class="docutils literal"><span class="pre">name</span></tt> is the key
-to a value. ('name' is case sensitive).</p>
-<p>If it doesn't find it, next it checks the 'DEFAULT' sub-section of the current
-section.</p>
-<p>If it still doesn't find it, it moves on to check the parent section and the
-parent section's 'DEFAULT' subsection, and so on all the way up to the main
-section.</p>
-<p>If the value specified isn't found in any of these locations, then a
-<tt class="docutils literal"><span class="pre">MissingInterpolationOption</span></tt> error is raised (a subclass of
-<tt class="docutils literal"><span class="pre">ConfigObjError</span></tt>).</p>
-<p>If it is found then the returned value is also checked for substitutions. This
-allows you to make up compound values (for example directory paths) that use
-more than one default value. It also means it's possible to create circular
-references. If there are any circular references which would cause an infinite
-interpolation loop, an <tt class="docutils literal"><span class="pre">InterpolationLoopError</span></tt> is raised.</p>
-<p>Both of these errors are subclasses of <tt class="docutils literal"><span class="pre">InterpolationError</span></tt>, which is a
-subclass of <tt class="docutils literal"><span class="pre">ConfigObjError</span></tt>.</p>
-<p>String interpolation and validation don't play well together. This is because
-validation overwrites values - and so may erase the interpolation references.
-See <a class="reference internal" href="#validation-and-interpolation">Validation and Interpolation</a>. (This can only happen if validation
-has to <em>change</em> the value).</p>
-</div>
-<div class="section" id="comments">
-<h1><a class="toc-backref" href="#id81">13&nbsp;&nbsp;&nbsp;Comments</a></h1>
-<p>Any line that starts with a '#', possibly preceded by whitespace, is a comment.</p>
-<p>If a config file starts with comments then these are preserved as the
-<a class="reference internal" href="#initial-comment">initial_comment</a>.</p>
-<p>If a config file ends with comments then these are preserved as the
-<a class="reference internal" href="#final-comment">final_comment</a>.</p>
-<p>Every key or section marker may have lines of comments immediately above it.
-These are saved as the <tt class="docutils literal"><span class="pre">comments</span></tt> attribute of the section. Each member is a
-list of lines.</p>
-<p>You can also have a comment inline with a value. These are saved as the
-<tt class="docutils literal"><span class="pre">inline_comments</span></tt> attribute of the section, with one entry per member of the
-section.</p>
-<p>Subsections (section markers in the config file) can also have comments.</p>
-<p>See <a class="reference internal" href="#section-attributes">Section Attributes</a> for more on these attributes.</p>
-<p>These comments are all written back out by the <tt class="docutils literal"><span class="pre">write</span></tt> method.</p>
-</div>
-<div class="section" id="flatten-errors">
-<h1><a class="toc-backref" href="#id82">14&nbsp;&nbsp;&nbsp;flatten_errors</a></h1>
-<pre class="literal-block">
-flatten_errors(cfg, res)
-</pre>
-<p><a class="reference internal" href="#validation">Validation</a> is a powerful way of checking that the values supplied by the user
-make sense.</p>
-<p>The <a class="reference internal" href="#validate">validate</a> method returns a results dictionary that represents pass or fail
-for each value. This doesn't give you any information about <em>why</em> the check
-failed.</p>
-<p><tt class="docutils literal"><span class="pre">flatten_errors</span></tt> is an example function that turns a results dictionary into
-a flat list, that only contains values that <em>failed</em>.</p>
-<p><tt class="docutils literal"><span class="pre">cfg</span></tt> is the ConfigObj instance being checked, <tt class="docutils literal"><span class="pre">res</span></tt> is the results
-dictionary returned by <tt class="docutils literal"><span class="pre">validate</span></tt>.</p>
-<p>It returns a list of keys that failed. Each member of the list is a tuple :</p>
-<pre class="literal-block">
-([list of sections...], key, result)
-</pre>
-<p>If <tt class="docutils literal"><span class="pre">validate</span></tt> was called with <tt class="docutils literal"><span class="pre">preserve_errors=False</span></tt> (the default)
-then <tt class="docutils literal"><span class="pre">result</span></tt> will always be <tt class="docutils literal"><span class="pre">False</span></tt>.</p>
-<p><em>list of sections</em> is a flattened list of sections that the key was found
-in.</p>
-<p>If the section was missing then key will be <tt class="docutils literal"><span class="pre">None</span></tt>.</p>
-<p>If the value (or section) was missing then <tt class="docutils literal"><span class="pre">result</span></tt> will be <tt class="docutils literal"><span class="pre">False</span></tt>.</p>
-<p>If <tt class="docutils literal"><span class="pre">validate</span></tt> was called with <tt class="docutils literal"><span class="pre">preserve_errors=True</span></tt> and a value
-was present, but failed the check, then <tt class="docutils literal"><span class="pre">result</span></tt> will be the exception
-object returned. You can use this as a string that describes the failure.</p>
-<p>For example :</p>
-<blockquote>
-<em>The value &quot;3&quot; is of the wrong type</em>.</blockquote>
-<div class="section" id="example-usage">
-<h2><a class="toc-backref" href="#id83">14.1&nbsp;&nbsp;&nbsp;Example Usage</a></h2>
-<p>The output from <tt class="docutils literal"><span class="pre">flatten_errors</span></tt> is a list of tuples.</p>
-<p>Here is an example of how you could present this information to the user.</p>
-<div class="pysrc"><span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">validate</span><span class="pyoperator">.</span><span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pycomment"># ini is your config file - cs is the configspec<br />
-</span><span class="pytext">cfg</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">ini</span><span class="pyoperator">,</span> <span class="pytext">configspec</span><span class="pyoperator">=</span><span class="pytext">cs</span><span class="pyoperator">)</span><br />
-<span class="pytext">res</span> <span class="pyoperator">=</span> <span class="pytext">cfg</span><span class="pyoperator">.</span><span class="pytext">validate</span><span class="pyoperator">(</span><span class="pytext">vtor</span><span class="pyoperator">,</span> <span class="pytext">preserve_errors</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">for</span> <span class="pytext">entry</span> <span class="pykeyword">in</span> <span class="pytext">flatten_errors</span><span class="pyoperator">(</span><span class="pytext">cfg</span><span class="pyoperator">,</span> <span class="pytext">res</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># each entry is a tuple<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section_list</span><span class="pyoperator">,</span> <span class="pytext">key</span><span class="pyoperator">,</span> <span class="pytext">error</span> <span class="pyoperator">=</span> <span class="pytext">entry</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">key</span> <span class="pykeyword">is</span> <span class="pykeyword">not</span> <span class="pytext">None</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="pytext">section_list</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pytext">key</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section_list</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pystring">'[missing section]'</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">section_string</span> <span class="pyoperator">=</span> <span class="pystring">', '</span><span class="pyoperator">.</span><span class="pytext">join</span><span class="pyoperator">(</span><span class="pytext">section_list</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">error</span> <span class="pyoperator">==</span> <span class="pytext">False</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">error</span> <span class="pyoperator">=</span> <span class="pystring">'Missing value or section.'</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pytext">section_string</span><span class="pyoperator">,</span> <span class="pystring">' = '</span><span class="pyoperator">,</span> <span class="pytext">error</span><span class="pytext"></span></div></div>
-</div>
-<div class="section" id="credits">
-<h1><a class="toc-backref" href="#id84">15&nbsp;&nbsp;&nbsp;CREDITS</a></h1>
-<p>ConfigObj 4 is written by (and copyright) <a class="reference external" href="http://www.voidspace.org.uk/python/weblog/index.shtml">Michael Foord</a> and
-<a class="reference external" href="http://www.teknico.net">Nicola Larosa</a>.</p>
-<p>Particularly thanks to Nicola Larosa for help on the config file spec, the
-validation system and the doctests.</p>
-<p><em>validate.py</em> was originally written by Michael Foord and Mark Andrews.</p>
-<p>Thanks to many others for input, patches and bugfixes.</p>
-</div>
-<div class="section" id="license">
-<h1><a class="toc-backref" href="#id85">16&nbsp;&nbsp;&nbsp;LICENSE</a></h1>
-<p>ConfigObj, and related files, are licensed under the BSD license. This is a
-very unrestrictive license, but it comes with the usual disclaimer. This is
-free software: test it, break it, just don't blame us if it eats your data !
-Of course if it does, let us know and we'll fix the problem so it doesn't
-happen to anyone else  <img src="/smilies/smile.gif" alt="Smile" height="15" width="15" /> .</p>
-<pre class="literal-block">
-Copyright (c) 2004 - 2009, Michael Foord &amp; Nicola Larosa
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of Michael Foord nor Nicola Larosa
-      may be used to endorse or promote products derived from this
-      software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-&quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-</pre>
-<p>You should also be able to find a copy of this license at : <a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></p>
-</div>
-<div class="section" id="todo">
-<h1><a class="toc-backref" href="#id86">17&nbsp;&nbsp;&nbsp;TODO</a></h1>
-<p>Better support for configuration from multiple files, including tracking
-<em>where</em> the original file came from and writing changes to the correct
-file.</p>
-<p>Make <tt class="docutils literal"><span class="pre">newline</span></tt> a keyword argument (as well as an attribute) ?</p>
-<p><tt class="docutils literal"><span class="pre">UTF16</span></tt> encoded files, when returned as a list of lines, will have the
-BOM at the start of every line. Should this be removed from all but the
-first line ?</p>
-<p>Option to set warning type for unicode decode ? (Defaults to strict).</p>
-<p>A method to optionally remove uniform indentation from multiline values.
-(do as an example of using <tt class="docutils literal"><span class="pre">walk</span></tt> - along with string-escape)</p>
-<p>Should the results dictionary from validate be an ordered dictionary if
-<a class="reference external" href="http://www.voidspace.org.uk/python/odict.html">odict</a> is available ?</p>
-<p>Implement some of the sequence methods (which include slicing) from the
-newer <tt class="docutils literal"><span class="pre">odict</span></tt> ?</p>
-<p>Preserve line numbers of values (and possibly the original text of each value).</p>
-</div>
-<div class="section" id="issues">
-<h1><a class="toc-backref" href="#id87">18&nbsp;&nbsp;&nbsp;ISSUES</a></h1>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">Please file any bug reports to <a class="reference external" href="http://www.voidspace.org.uk/python/weblog/index.shtml">Michael Foord</a> or the <strong>ConfigObj</strong>
-<a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
-</div>
-<p>There is currently no way to specify the encoding of a configspec file.</p>
-<p>As a consequence of the changes to configspec handling in version 4.6.0, when you create a ConfigObj instance and provide a configspec, the configspec attribute is only set on the ConfigObj instance - it isn't set on the sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't documented but did work previously.</p>
-<p>In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments in configspecs. This will only affect you if you are using <tt class="docutils literal"><span class="pre">copy=True</span></tt> when validating and expecting inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be copied as usual).</p>
-<p>If you <em>create</em> the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or list of lines) then you should pass in <tt class="docutils literal"><span class="pre">_inspec=True</span></tt> to the constructor to allow hashes in values. This is the magic that switches off inline comment parsing.</p>
-<p>When using <tt class="docutils literal"><span class="pre">copy</span></tt> mode for validation, it won't copy <tt class="docutils literal"><span class="pre">DEFAULT</span></tt>
-sections. This is so that you <em>can</em> use interpolation in configspec
-files.</p>
-<p><tt class="docutils literal"><span class="pre">validate</span></tt> doesn't report <em>extra</em> values or sections.</p>
-<p>You can't have a keyword with the same name as a section (in the same
-section). They are both dictionary keys - so they would overlap.</p>
-<p>ConfigObj doesn't quote and unquote values if <tt class="docutils literal"><span class="pre">list_values=False</span></tt>.
-This means that leading or trailing whitespace in values will be lost when
-writing. (Unless you manually quote).</p>
-<p>Interpolation checks first the current section, then the 'DEFAULT' subsection
-of the current section, before moving on to the current section's parent and
-so on up the tree.</p>
-<p>Does it matter that we don't support the ':' divider, which is supported
-by <tt class="docutils literal"><span class="pre">ConfigParser</span></tt> ?</p>
-<p>String interpolation and validation don't play well together. When
-validation changes type it sets the value. This will correctly fetch the
-value using interpolation - but then overwrite the interpolation reference.
-If the value is unchanged by validation (it's a string) - but other types
-will be.</p>
-</div>
-<div class="section" id="changelog">
-<h1><a class="toc-backref" href="#id88">19&nbsp;&nbsp;&nbsp;CHANGELOG</a></h1>
-<p>This is an abbreviated changelog showing the major releases up to version 4.
-From version 4 it lists all releases and changes.</p>
-<div class="section" id="version-4-6-0">
-<h2><a class="toc-backref" href="#id89">19.1&nbsp;&nbsp;&nbsp;2009/04/13 - Version 4.6.0</a></h2>
-<ul class="simple">
-<li>Pickling of ConfigObj instances now supported (thanks to Christian Heimes)</li>
-<li>Hashes in confgspecs are now allowed (see note below)</li>
-<li>Replaced use of hasattr (which can swallow exceptions) with getattr</li>
-<li>__many__ in configspecs can refer to scalars (ordinary values) as well as sections</li>
-<li>You can use ___many___ (three underscores!) where you want to use __many__ as well</li>
-<li>You can now have normal sections inside configspec sections that use __many__</li>
-<li>You can now create an empty ConfigObj with a configspec, programmatically set values and then validate</li>
-<li>A section that was supplied as a value (or vice-versa) in the actual config file would cause an exception during validation (the config file is still broken of course, but it is now handled gracefully)</li>
-<li>Added <tt class="docutils literal"><span class="pre">as_list</span></tt> method</li>
-<li>Removed the deprecated <tt class="docutils literal"><span class="pre">istrue</span></tt>, <tt class="docutils literal"><span class="pre">encode</span></tt> and <tt class="docutils literal"><span class="pre">decode</span></tt> methods</li>
-<li>Running test_configobj.py now also runs the doctests in the configobj module</li>
-</ul>
-<p>As a consequence of the changes to configspec handling, when you create a ConfigObj instance and provide
-a configspec, the configspec attribute is only set on the ConfigObj instance - it isn't set on the
-sections until you validate. You also can't set the configspec attribute to be a dictionary. This wasn't
-documented but did work previously.</p>
-<p>In order to fix the problem with hashes in configspecs I had to turn off the parsing of inline comments
-in configspecs. This will only affect you if you are using <tt class="docutils literal"><span class="pre">copy=True</span></tt> when validating and expecting
-inline comments to be copied from the configspec into the ConfigObj instance (all other comments will be
-copied as usual).</p>
-<p>If you <em>create</em> the configspec by passing in a ConfigObj instance (usual way is to pass in a filename or
-list of lines) then you should pass in <tt class="docutils literal"><span class="pre">_inspec=True</span></tt> to the constructor to allow hashes in values.
-This is the magic that switches off inline comment parsing.</p>
-</div>
-<div class="section" id="version-4-5-3">
-<h2><a class="toc-backref" href="#id90">19.2&nbsp;&nbsp;&nbsp;2008/06/27 - Version 4.5.3</a></h2>
-<p>BUGFIX: fixed a problem with <tt class="docutils literal"><span class="pre">copy=True</span></tt> when validating with configspecs that use
-<tt class="docutils literal"><span class="pre">__many__</span></tt> sections.</p>
-</div>
-<div class="section" id="version-4-5-2">
-<h2><a class="toc-backref" href="#id91">19.3&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.2</a></h2>
-<p>Distribution updated to include version 0.3.2 of <a class="reference internal" href="#validate">validate</a>. This means that
-<tt class="docutils literal"><span class="pre">None</span></tt> as a default value win configspecs works.</p>
-</div>
-<div class="section" id="version-4-5-1">
-<h2><a class="toc-backref" href="#id92">19.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.1</a></h2>
-<p>Distribution updated to include version 0.3.1 of <a class="reference internal" href="#validate">validate</a>. This means that
-Unicode configspecs now work.</p>
-</div>
-<div class="section" id="version-4-5-0">
-<h2><a class="toc-backref" href="#id93">19.5&nbsp;&nbsp;&nbsp;2008/02/05 - Version 4.5.0</a></h2>
-<p>ConfigObj will now guarantee that files will be written terminated with a
-newline.</p>
-<p>ConfigObj will no longer attempt to import the <tt class="docutils literal"><span class="pre">validate</span></tt> module, until/unless
-you call <tt class="docutils literal"><span class="pre">ConfigObj.validate</span></tt> with <tt class="docutils literal"><span class="pre">preserve_errors=True</span></tt>. This makes it
-faster to import.</p>
-<p>New methods <tt class="docutils literal"><span class="pre">restore_default</span></tt> and <tt class="docutils literal"><span class="pre">restore_defaults</span></tt>. <tt class="docutils literal"><span class="pre">restore_default</span></tt>
-resets an entry to its default value (and returns that value). <tt class="docutils literal"><span class="pre">restore_defaults</span></tt>
-resets all entries to their default value. It doesn't modify entries without a
-default value. You must have validated a ConfigObj (which populates the
-<tt class="docutils literal"><span class="pre">default_values</span></tt> dictionary) before calling these methods.</p>
-<p>BUGFIX: Proper quoting of keys, values and list values that contain hashes
-(when writing).  When <tt class="docutils literal"><span class="pre">list_values=False</span></tt>, values containing hashes are
-triple quoted.</p>
-<p>Added the <tt class="docutils literal"><span class="pre">reload</span></tt> method. This reloads a ConfigObj from file. If the filename
-attribute is not set then a <tt class="docutils literal"><span class="pre">ReloadError</span></tt> (a new exception inheriting from
-<tt class="docutils literal"><span class="pre">IOError</span></tt>) is raised.</p>
-<p>BUGFIX: Files are read in with 'rb' mode, so that native/non-native line endings work!</p>
-<p>Minor efficiency improvement in <tt class="docutils literal"><span class="pre">unrepr</span></tt> mode.</p>
-<p>Added missing docstrings for some overidden dictionary methods.</p>
-<p>Added the <tt class="docutils literal"><span class="pre">reset</span></tt> method. This restores a ConfigObj to a freshly created state.</p>
-<p>Removed old CHANGELOG file.</p>
-</div>
-<div class="section" id="version-4-4-0">
-<h2><a class="toc-backref" href="#id94">19.6&nbsp;&nbsp;&nbsp;2007/02/04 - Version 4.4.0</a></h2>
-<p>Official release of 4.4.0</p>
-</div>
-<div class="section" id="version-4-3-3-alpha4">
-<h2><a class="toc-backref" href="#id95">19.7&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha4</a></h2>
-<p>By Nicola Larosa</p>
-<p>Allowed arbitrary indentation in the <tt class="docutils literal"><span class="pre">indent_type</span></tt> parameter, removed the
-<tt class="docutils literal"><span class="pre">NUM_INDENT_SPACES</span></tt> and <tt class="docutils literal"><span class="pre">MAX_INTERPOL_DEPTH</span></tt> (a leftover) constants,
-added indentation tests (including another docutils workaround, sigh), updated
-the documentation.</p>
-<p>By Michael Foord</p>
-<p>Made the import of <tt class="docutils literal"><span class="pre">compiler</span></tt> conditional so that <tt class="docutils literal"><span class="pre">ConfigObj</span></tt> can be used
-with <a class="reference external" href="http://www.codeplex.com/IronPython">IronPython</a>.</p>
-</div>
-<div class="section" id="version-4-3-3-alpha3">
-<h2><a class="toc-backref" href="#id96">19.8&nbsp;&nbsp;&nbsp;2006/12/17 - Version 4.3.3-alpha3</a></h2>
-<p>By Nicola Larosa</p>
-<p>Added a missing <tt class="docutils literal"><span class="pre">self.</span></tt> in the _handle_comment method and a related test,
-per Sourceforge bug #1523975.</p>
-</div>
-<div class="section" id="version-4-3-3-alpha2">
-<h2><a class="toc-backref" href="#id97">19.9&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha2</a></h2>
-<p>By Nicola Larosa</p>
-<p>Changed interpolation search strategy, based on this patch by Robin Munn:
-<a class="reference external" href="http://sourceforge.net/mailarchive/message.php?msg_id=17125993">http://sourceforge.net/mailarchive/message.php?msg_id=17125993</a></p>
-</div>
-<div class="section" id="version-4-3-3-alpha1">
-<h2><a class="toc-backref" href="#id98">19.10&nbsp;&nbsp;&nbsp;2006/12/09 - Version 4.3.3-alpha1</a></h2>
-<p>By Nicola Larosa</p>
-<p>Added Template-style interpolation, with tests, based on this patch by
-Robin Munn: <a class="reference external" href="http://sourceforge.net/mailarchive/message.php?msg_id=17125991">http://sourceforge.net/mailarchive/message.php?msg_id=17125991</a>
-(awful archives, bad Sourceforge, bad).</p>
-</div>
-<div class="section" id="version-4-3-2">
-<h2><a class="toc-backref" href="#id99">19.11&nbsp;&nbsp;&nbsp;2006/06/04 - Version 4.3.2</a></h2>
-<p>Changed error handling, if parsing finds a single error then that error will
-be re-raised. That error will still have an <tt class="docutils literal"><span class="pre">errors</span></tt> and a <tt class="docutils literal"><span class="pre">config</span></tt>
-attribute.</p>
-<p>Fixed bug where '\n' terminated files could be truncated.</p>
-<p>Bugfix in <tt class="docutils literal"><span class="pre">unrepr</span></tt> mode, it couldn't handle '#' in values. (Thanks to
-Philippe Normand for the report.)</p>
-<p>As a consequence of this fix, ConfigObj doesn't now keep inline comments in
-<tt class="docutils literal"><span class="pre">unrepr</span></tt> mode. This is because the parser in the <a class="reference external" href="http://docs.python.org/lib/compiler.html">compiler package</a>
-doesn't keep comments.  <img src="/smilies/smile.gif" alt="Smile" height="15" width="15" /> </p>
-<p>Error messages are now more useful. They tell you the number of parsing errors
-and the line number of the first error. (In the case of multiple errors.)</p>
-<p>Line numbers in exceptions now start at 1, not 0.</p>
-<p>Errors in <tt class="docutils literal"><span class="pre">unrepr</span></tt> mode are now handled the same way as in the normal mode.
-The errors stored will be an <tt class="docutils literal"><span class="pre">UnreprError</span></tt>.</p>
-</div>
-<div class="section" id="version-4-3-1">
-<h2><a class="toc-backref" href="#id100">19.12&nbsp;&nbsp;&nbsp;2006/04/29 - Version 4.3.1</a></h2>
-<p>Added <tt class="docutils literal"><span class="pre">validate.py</span></tt> back into <tt class="docutils literal"><span class="pre">configobj.zip</span></tt>. (Thanks to Stewart
-Midwinter)</p>
-<p>Updated to <a class="reference external" href="http://www.voidspace.org.uk/downloads/validate.py">validate.py</a> 0.2.2.</p>
-<p>Preserve tuples when calling the <tt class="docutils literal"><span class="pre">dict</span></tt> method. (Thanks to Gustavo Niemeyer.)</p>
-<p>Changed <tt class="docutils literal"><span class="pre">__repr__</span></tt> to return a string that contains <tt class="docutils literal"><span class="pre">ConfigObj({</span> <span class="pre">...</span> <span class="pre">})</span></tt>.</p>
-<p>Change so that an options dictionary isn't modified by passing it to ConfigObj.
-(Thanks to Artarious.)</p>
-<p>Added ability to handle negative integers in <tt class="docutils literal"><span class="pre">unrepr</span></tt>. (Thanks to Kevin
-Dangoor.)</p>
-</div>
-<div class="section" id="version-4-3-0">
-<h2><a class="toc-backref" href="#id101">19.13&nbsp;&nbsp;&nbsp;2006/03/24 - Version 4.3.0</a></h2>
-<p>Moved the tests and the CHANGELOG (etc) into a separate file. This has reduced
-the size of <tt class="docutils literal"><span class="pre">configobj.py</span></tt> by about 40%.</p>
-<p>Added the <tt class="docutils literal"><span class="pre">unrepr</span></tt> mode to reading and writing config files. Thanks to Kevin
-Dangoor for this suggestion.</p>
-<p>Empty values are now valid syntax. They are read as an empty string <tt class="docutils literal"><span class="pre">''</span></tt>.
-(<tt class="docutils literal"><span class="pre">key</span> <span class="pre">=</span></tt>, or <tt class="docutils literal"><span class="pre">key</span> <span class="pre">=</span> <span class="pre">#</span> <span class="pre">comment</span></tt>.)</p>
-<p><tt class="docutils literal"><span class="pre">validate</span></tt> now honours the order of the configspec.</p>
-<p>Added the <tt class="docutils literal"><span class="pre">copy</span></tt> mode to validate. Thanks to Louis Cordier for this
-suggestion.</p>
-<p>Fixed bug where files written on windows could be given <tt class="docutils literal"><span class="pre">'\r\r\n'</span></tt> line
-terminators.</p>
-<p>Fixed bug where last occurring comment line could be interpreted as the
-final comment if the last line isn't terminated.</p>
-<p>Fixed bug where nested list values would be flattened when <tt class="docutils literal"><span class="pre">write</span></tt> is
-called. Now sub-lists have a string representation written instead.</p>
-<p>Deprecated <tt class="docutils literal"><span class="pre">encode</span></tt> and <tt class="docutils literal"><span class="pre">decode</span></tt> methods instead.</p>
-<p>You can now pass in a ConfigObj instance as a configspec (remember to read
-the configspec file using <tt class="docutils literal"><span class="pre">list_values=False</span></tt>).</p>
-<p>Sorted footnotes in the docs.</p>
-</div>
-<div class="section" id="version-4-2-0">
-<h2><a class="toc-backref" href="#id102">19.14&nbsp;&nbsp;&nbsp;2006/02/16 - Version 4.2.0</a></h2>
-<p>Removed <tt class="docutils literal"><span class="pre">BOM_UTF8</span></tt> from <tt class="docutils literal"><span class="pre">__all__</span></tt>.</p>
-<p>The <tt class="docutils literal"><span class="pre">BOM</span></tt> attribute has become a boolean. (Defaults to <tt class="docutils literal"><span class="pre">False</span></tt>.) It is
-<em>only</em> <tt class="docutils literal"><span class="pre">True</span></tt> for the <tt class="docutils literal"><span class="pre">UTF16/UTF8</span></tt> encodings.</p>
-<p>File like objects no longer need a <tt class="docutils literal"><span class="pre">seek</span></tt> attribute.</p>
-<p>Full unicode support added. New options/attributes <tt class="docutils literal"><span class="pre">encoding</span></tt>,
-<tt class="docutils literal"><span class="pre">default_encoding</span></tt>.</p>
-<p>ConfigObj no longer keeps a reference to file like objects. Instead the
-<tt class="docutils literal"><span class="pre">write</span></tt> method takes a file like object as an optional argument. (Which
-will be used in preference of the <tt class="docutils literal"><span class="pre">filename</span></tt> attribute if that exists as
-well.)</p>
-<p>utf16 files decoded to unicode.</p>
-<p>If <tt class="docutils literal"><span class="pre">BOM</span></tt> is <tt class="docutils literal"><span class="pre">True</span></tt>, but no encoding specified, then the utf8 BOM is
-written out at the start of the file. (It will normally only be <tt class="docutils literal"><span class="pre">True</span></tt> if
-the utf8 BOM was found when the file was read.)</p>
-<p>Thanks to Aaron Bentley for help and testing on the unicode issues.</p>
-<p>File paths are <em>not</em> converted to absolute paths, relative paths will
-remain relative as the <tt class="docutils literal"><span class="pre">filename</span></tt> attribute.</p>
-<p>Fixed bug where <tt class="docutils literal"><span class="pre">final_comment</span></tt> wasn't returned if <tt class="docutils literal"><span class="pre">write</span></tt> is returning
-a list of lines.</p>
-<p>Deprecated <tt class="docutils literal"><span class="pre">istrue</span></tt>, replaced it with <tt class="docutils literal"><span class="pre">as_bool</span></tt>.</p>
-<p>Added <tt class="docutils literal"><span class="pre">as_int</span></tt> and <tt class="docutils literal"><span class="pre">as_float</span></tt>.</p>
-</div>
-<div class="section" id="version-4-1-0">
-<h2><a class="toc-backref" href="#id103">19.15&nbsp;&nbsp;&nbsp;2005/12/14 - Version 4.1.0</a></h2>
-<p>Added <tt class="docutils literal"><span class="pre">merge</span></tt>, a recursive update.</p>
-<p>Added <tt class="docutils literal"><span class="pre">preserve_errors</span></tt> to <tt class="docutils literal"><span class="pre">validate</span></tt> and the <tt class="docutils literal"><span class="pre">flatten_errors</span></tt>
-example function.</p>
-<p>Thanks to Matthew Brett for suggestions and helping me iron out bugs.</p>
-<p>Fixed bug where a config file is <em>all</em> comment, the comment will now be
-<tt class="docutils literal"><span class="pre">initial_comment</span></tt> rather than <tt class="docutils literal"><span class="pre">final_comment</span></tt>.</p>
-<p>Validation no longer done on the 'DEFAULT' section (only in the root level).
-This allows interpolation in configspecs.</p>
-<p>Also use the new list syntax in <a class="reference internal" href="#validate">validate</a> 0.2.1. (For configspecs).</p>
-</div>
-<div class="section" id="version-4-0-2">
-<h2><a class="toc-backref" href="#id104">19.16&nbsp;&nbsp;&nbsp;2005/12/02 - Version 4.0.2</a></h2>
-<p>Fixed bug in <tt class="docutils literal"><span class="pre">create_empty</span></tt>. Thanks to Paul Jimenez for the report.</p>
-</div>
-<div class="section" id="version-4-0-1">
-<h2><a class="toc-backref" href="#id105">19.17&nbsp;&nbsp;&nbsp;2005/11/05 - Version 4.0.1</a></h2>
-<p>Fixed bug in <tt class="docutils literal"><span class="pre">Section.walk</span></tt> when transforming names as well as values.</p>
-<p>Added the <tt class="docutils literal"><span class="pre">istrue</span></tt> method. (Fetches the boolean equivalent of a string
-value).</p>
-<p>Fixed <tt class="docutils literal"><span class="pre">list_values=False</span></tt> - they are now only quoted/unquoted if they
-are multiline values.</p>
-<p>List values are written as <tt class="docutils literal"><span class="pre">item,</span> <span class="pre">item</span></tt> rather than <tt class="docutils literal"><span class="pre">item,item</span></tt>.</p>
-</div>
-<div class="section" id="version-4-0-0">
-<h2><a class="toc-backref" href="#id106">19.18&nbsp;&nbsp;&nbsp;2005/10/17 - Version 4.0.0</a></h2>
-<p><strong>ConfigObj 4.0.0 Final</strong></p>
-<p>Fixed bug in <tt class="docutils literal"><span class="pre">setdefault</span></tt>. When creating a new section with setdefault the
-reference returned would be to the dictionary passed in <em>not</em> to the new
-section. Bug fixed and behaviour documented.</p>
-<p>Obscure typo/bug fixed in <tt class="docutils literal"><span class="pre">write</span></tt>. Wouldn't have affected anyone though.</p>
-</div>
-<div class="section" id="version-4-0-0-beta-5">
-<h2><a class="toc-backref" href="#id107">19.19&nbsp;&nbsp;&nbsp;2005/09/09 - Version 4.0.0 beta 5</a></h2>
-<p>Removed <tt class="docutils literal"><span class="pre">PositionError</span></tt>.</p>
-<p>Allowed quotes around keys as documented.</p>
-<p>Fixed bug with commas in comments. (matched as a list value)</p>
-</div>
-<div class="section" id="version-4-0-0-beta-4">
-<h2><a class="toc-backref" href="#id108">19.20&nbsp;&nbsp;&nbsp;2005/09/07 - Version 4.0.0 beta 4</a></h2>
-<p>Fixed bug in <tt class="docutils literal"><span class="pre">__delitem__</span></tt>. Deleting an item no longer deletes the
-<tt class="docutils literal"><span class="pre">inline_comments</span></tt> attribute.</p>
-<p>Fixed bug in initialising ConfigObj from a ConfigObj.</p>
-<p>Changed the mailing list address.</p>
-</div>
-<div class="section" id="version-4-0-0-beta-3">
-<h2><a class="toc-backref" href="#id109">19.21&nbsp;&nbsp;&nbsp;2005/08/28 - Version 4.0.0 beta 3</a></h2>
-<p>Interpolation is switched off before writing out files.</p>
-<p>Fixed bug in handling <tt class="docutils literal"><span class="pre">StringIO</span></tt> instances. (Thanks to report from
-Gustavo Niemeyer.)</p>
-<p>Moved the doctests from the <tt class="docutils literal"><span class="pre">__init__</span></tt> method to a separate function.
-(For the sake of IDE calltips).</p>
-</div>
-<div class="section" id="version-4-0-0-beta-2">
-<h2><a class="toc-backref" href="#id110">19.22&nbsp;&nbsp;&nbsp;2005/08/25 - Version 4.0.0 beta 2</a></h2>
-<p>Amendments to <em>validate.py</em>.</p>
-<p>First public release.</p>
-</div>
-<div class="section" id="version-4-0-0-beta-1">
-<h2><a class="toc-backref" href="#id111">19.23&nbsp;&nbsp;&nbsp;2005/08/21 - Version 4.0.0 beta 1</a></h2>
-<p>Reads nested subsections to any depth.</p>
-<p>Multiline values.</p>
-<p>Simplified options and methods.</p>
-<p>New list syntax.</p>
-<p>Faster, smaller, and better parser.</p>
-<p>Validation greatly improved. Includes:</p>
-<blockquote>
-<ul class="simple">
-<li>type conversion</li>
-<li>default values</li>
-<li>repeated sections</li>
-</ul>
-</blockquote>
-<p>Improved error handling.</p>
-<p>Plus lots of other improvements.  <img src="/smilies/biggrin.gif" alt="Very Happy" height="15" width="15" /> </p>
-</div>
-<div class="section" id="version-3-0-0">
-<h2><a class="toc-backref" href="#id112">19.24&nbsp;&nbsp;&nbsp;2004/05/24 - Version 3.0.0</a></h2>
-<p>Several incompatible changes: another major overhaul and change. (Lots of
-improvements though).</p>
-<p>Added support for standard config files with sections. This has an entirely
-new interface: each section is a dictionary of values.</p>
-<p>Changed the update method to be called writein: update clashes with a dict
-method.</p>
-<p>Made various attributes keyword arguments, added several.</p>
-<p>Configspecs and orderlists have changed a great deal.</p>
-<p>Removed support for adding dictionaries: use update instead.</p>
-<p>Now subclasses a new class called caselessDict. This should add various
-dictionary methods that could have caused errors before.</p>
-<p>It also preserves the original casing of keywords when writing them back out.</p>
-<p>Comments are also saved using a <tt class="docutils literal"><span class="pre">caselessDict</span></tt>.</p>
-<p>Using a non-string key will now raise a <tt class="docutils literal"><span class="pre">TypeError</span></tt> rather than converting
-the key.</p>
-<p>Added an exceptions keyword for <em>much</em> better handling of errors.</p>
-<p>Made <tt class="docutils literal"><span class="pre">creatempty=False</span></tt> the default.</p>
-<p>Now checks indict <em>and</em> any keyword args. Keyword args take precedence over
-indict.</p>
-<p><tt class="docutils literal"><span class="pre">'</span> <span class="pre">',</span> <span class="pre">':',</span> <span class="pre">'=',</span> <span class="pre">','</span></tt> and <tt class="docutils literal"><span class="pre">'\t'</span></tt> are now all valid dividers where the
-keyword is unquoted.</p>
-<p>ConfigObj now does no type checking against configspec when you set items.</p>
-<p>delete and add methods removed (they were unnecessary).</p>
-<p>Docs rewritten to include all this gumph and more; actually ConfigObj is
-<em>really</em> easy to use.</p>
-<p>Support for stdout was removed.</p>
-<p>A few new methods added.</p>
-<p>Charmap is now incorporated into ConfigObj.</p>
-</div>
-<div class="section" id="version-2-0-0-beta">
-<h2><a class="toc-backref" href="#id113">19.25&nbsp;&nbsp;&nbsp;2004/03/14 - Version 2.0.0 beta</a></h2>
-<p>Re-written it to subclass dict. My first forays into inheritance and operator
-overloading.</p>
-<p>The config object now behaves like a dictionary.</p>
-<p>I've completely broken the interface, but I don't think anyone was really
-using it anyway.</p>
-<p>This new version is much more 'classy'.  <img src="/smilies/wink.gif" alt="Wink" height="15" width="15" /> </p>
-<p>It will also read straight from/to a filename and completely parse a config
-file without you <em>having</em> to supply a config spec.</p>
-<p>Uses listparse, so can handle nested list items as values.</p>
-<p>No longer has getval and setval methods: use normal dictionary methods, or add
-and delete.</p>
-</div>
-<div class="section" id="version-1-0-5">
-<h2><a class="toc-backref" href="#id114">19.26&nbsp;&nbsp;&nbsp;2004/01/29 - Version 1.0.5</a></h2>
-<p>Version 1.0.5 has a couple of bugfixes as well as a couple of useful additions
-over previous versions.</p>
-<p>Since 1.0.0 the buildconfig function has been moved into this distribution,
-and the methods reset, verify, getval and setval have been added.</p>
-<p>A couple of bugs have been fixed.</p>
-</div>
-<div class="section" id="origins">
-<h2><a class="toc-backref" href="#id115">19.27&nbsp;&nbsp;&nbsp;Origins</a></h2>
-<p>ConfigObj originated in a set of functions for reading config files in the
-<a class="reference external" href="http://www.voidspace.org.uk/atlantibots/">atlantibots</a> project. The original
-functions were written by Rob McNeur.</p>
-</div>
-</div>
-<hr class="docutils" />
-<div class="section" id="footnotes">
-<h1><a class="toc-backref" href="#id116">20&nbsp;&nbsp;&nbsp;Footnotes</a></h1>
-<table class="docutils footnote" frame="void" id="id14" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>And if you discover any bugs, let us know. We'll fix them quickly.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id15" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>If you specify a filename that doesn't exist, ConfigObj will assume you
-are creating a new one. See the <em>create_empty</em> and <em>file_error</em> <a class="reference internal" href="#options">options</a>.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id16" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>They can be byte strings (<em>ordinary</em> strings) or Unicode.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id17" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id4">[4]</a></td><td>Except we don't support the RFC822 style line continuations, nor ':' as
-a divider.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id18" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id5">[5]</a></td><td>This is a change in ConfigObj 4.2.0. Note that ConfigObj doesn't call
-the seek method of any file like object you pass in. You may want to call
-<tt class="docutils literal"><span class="pre">file_object.seek(0)</span></tt> yourself, first.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id19" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id6">[6]</a></td><td><p class="first">A side effect of this is that it enables you to copy a ConfigObj :</p>
-<div class="pysrc"><span class="pycomment"># only copies members<br />
-</span><span class="pycomment"># not attributes/comments<br />
-</span><span class="pytext">config2</span> <span class="pyoperator">=</span> <span class="pytext">ConfigObj</span><span class="pyoperator">(</span><span class="pytext">config1</span><span class="pyoperator">)</span><span class="pytext"></span></div><p class="last">The order of values and sections will not be preserved, though.</p>
-</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id20" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id7">[7]</a></td><td>Other than lists of strings.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id21" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id8">[8]</a></td><td>The exception is if it detects a <tt class="docutils literal"><span class="pre">UTF16</span></tt> encoded file which it
-must decode before parsing.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id22" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id9">[9]</a></td><td>The method signature shows that this method takes
-two arguments. The second is the section to be written. This is because the
-<tt class="docutils literal"><span class="pre">write</span></tt> method is called recursively.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id23" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id10">[10]</a></td><td>The dict method doesn't actually use the deepcopy mechanism. This means
-if you add nested lists (etc) to your ConfigObj, then the dictionary
-returned by dict may contain some references. For all <em>normal</em> ConfigObjs
-it will return a deepcopy.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id24" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id11">[11]</a></td><td>Passing <tt class="docutils literal"><span class="pre">(section,</span> <span class="pre">key)</span></tt> rather than <tt class="docutils literal"><span class="pre">(value,</span> <span class="pre">key)</span></tt> allows you to
-change the value by setting <tt class="docutils literal"><span class="pre">section[key]</span> <span class="pre">=</span> <span class="pre">newval</span></tt>. It also gives you
-access to the <em>rename</em> method of the section.</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="id25" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id12">[12]</a></td><td>Minimum required version of <em>validate.py</em> 0.2.0 .</td></tr>
-</tbody>
-</table>
-</div>
-</div>
-<div class="footer">
-<hr class="footer" />
-<a class="reference external" href="configobj.txt">View document source</a>.
-Generated on: 2009-04-16 21:03 UTC.
-Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
-
-</div>
-</body>
-</html>

BIN
desktop/core/ext-py/configobj/docs/images/PythonPowered.png


BIN
desktop/core/ext-py/configobj/docs/images/new_python.gif


BIN
desktop/core/ext-py/configobj/docs/images/osi-certified-120x100.gif


BIN
desktop/core/ext-py/configobj/docs/images/powered_by_python.jpg


BIN
desktop/core/ext-py/configobj/docs/images/pythonbanner.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/arrow.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/badgrin.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/biggrin.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/confused.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/cool.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/cry.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/doubt.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/evil.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/exclaim.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/idea.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/lol.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/mad.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/neutral.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/question.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/razz.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/redface.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/rolleyes.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/sad.gif


+ 0 - 43
desktop/core/ext-py/configobj/docs/smilies/sc_smilies.pak

@@ -1,43 +0,0 @@
-biggrin.gif=+:Very Happy=+::D
-biggrin.gif=+:Very Happy=+::-D
-biggrin.gif=+:Very Happy=+::grin:
-biggrin.gif=+:Very Happy=+::biggrin:
-smile.gif=+:Smile=+::)
-smile.gif=+:Smile=+::-)
-smile.gif=+:Smile=+::smile:
-sad.gif=+:Sad=+::(
-sad.gif=+:Sad=+::-(
-sad.gif=+:Sad=+::sad:
-surprised.gif=+:Surprised=+::o
-surprised.gif=+:Surprised=+::-o
-surprised.gif=+:Surprised=+::eek:
-shock.gif=+:Shock=+::shock:
-confused.gif=+:Confused=+::?
-confused.gif=+:Confused=+::-?
-confused.gif=+:Confused=+::???:
-cool.gif=+:Cool=+:8)
-cool.gif=+:Cool=+:8-)
-cool.gif=+:Cool=+::cool:
-lol.gif=+:Laughing=+::lol:
-mad.gif=+:Mad=+::x
-mad.gif=+:Mad=+::-X
-mad.gif=+:Mad=+::mad:
-razz.gif=+:Razz=+::p
-razz.gif=+:Razz=+::-p
-razz.gif=+:Razz=+::razz:
-redface.gif=+:Embarassed=+::oops:
-cry.gif=+:Crying or Very sad=+::cry:
-evil.gif=+:Evil or Very Mad=+::evil:
-badgrin.gif=+:Bad Grin=+::badgrin:
-rolleyes.gif=+:Rolling Eyes=+::roll:
-wink.gif=+:Wink=+:;)
-wink.gif=+:Wink=+:;-)
-wink.gif=+:Wink=+::wink:
-exclaim.gif=+:Exclamation=+::!:
-question.gif=+:Question=+::?:
-idea.gif=+:Idea=+::idea:
-arrow.gif=+:Arrow=+::arrow:
-neutral.gif=+:Neutral=+::|
-neutral.gif=+:Neutral=+::-|
-neutral.gif=+:Neutral=+::neutral:
-doubt.gif=+:Doubt=+::doubt:

BIN
desktop/core/ext-py/configobj/docs/smilies/shock.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/smile.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/surprised.gif


BIN
desktop/core/ext-py/configobj/docs/smilies/wink.gif


+ 0 - 349
desktop/core/ext-py/configobj/docs/stylesheets/pep.css

@@ -1,349 +0,0 @@
-/*
-:Author: David Goodger
-:Contact: goodger@users.sourceforge.net
-:date: $Date: 2005-09-25 17:49:54 +0200 (Sun, 25 Sep 2005) $
-:version: $Revision: 3901 $
-:copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the PEP HTML output of Docutils.
-*/
-
-/* "! important" is used here to override other ``margin-top`` and
-   ``margin-bottom`` styles that are later in the stylesheet or 
-   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
-.first {
-  margin-top: 0 ! important }
-
-.last, .with-subtitle {
-  margin-bottom: 0 ! important }
-
-.hidden {
-  display: none }
-
-.navigation {
-  width: 100% ;
-  background: #99ccff ;
-  margin-top: 0px ;
-  margin-bottom: 0px }
-
-.navigation .navicon {
-  width: 150px ;
-  height: 35px }
-
-.navigation .textlinks {
-  padding-left: 1em ;
-  text-align: left }
-
-.navigation td, .navigation th {
-  padding-left: 0em ;
-  padding-right: 0em ;
-  vertical-align: middle }
-
-.rfc2822 {
-  margin-top: 0.5em ;
-  margin-left: 0.5em ;
-  margin-right: 0.5em ;
-  margin-bottom: 0em }
-
-.rfc2822 td {
-  text-align: left }
-
-.rfc2822 th.field-name {
-  text-align: right ;
-  font-family: sans-serif ;
-  padding-right: 0.5em ;
-  font-weight: bold ;
-  margin-bottom: 0em }
-
-a.toc-backref {
-  text-decoration: none ;
-  color: black }
-
-blockquote.epigraph {
-  margin: 2em 5em ; }
-
-body {
-  margin: 0px ;
-  margin-bottom: 1em ;
-  padding: 0px }
-
-dl.docutils dd {
-  margin-bottom: 0.5em }
-
-div.section {
-  margin-left: 1em ;
-  margin-right: 1em ;
-  margin-bottom: 1.5em }
-
-div.section div.section {
-  margin-left: 0em ;
-  margin-right: 0em ;
-  margin-top: 1.5em }
-
-div.abstract {
-  margin: 2em 5em }
-
-div.abstract p.topic-title {
-  font-weight: bold ;
-  text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
-  margin: 2em ;
-  border: medium outset ;
-  padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
-  font-weight: bold ;
-  font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title {
-  color: red ;
-  font-weight: bold ;
-  font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
-   compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
-  margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
-  margin-top: 0.5em }
-*/
-
-div.dedication {
-  margin: 2em 5em ;
-  text-align: center ;
-  font-style: italic }
-
-div.dedication p.topic-title {
-  font-weight: bold ;
-  font-style: normal }
-
-div.figure {
-  margin-left: 2em }
-
-div.footer, div.header {
-  clear: both;
-  font-size: smaller }
-
-div.footer {
-  margin-left: 1em ;
-  margin-right: 1em }
-
-div.line-block {
-  display: block ;
-  margin-top: 1em ;
-  margin-bottom: 1em }
-
-div.line-block div.line-block {
-  margin-top: 0 ;
-  margin-bottom: 0 ;
-  margin-left: 1.5em }
-
-div.sidebar {
-  margin-left: 1em ;
-  border: medium outset ;
-  padding: 1em ;
-  background-color: #ffffee ;
-  width: 40% ;
-  float: right ;
-  clear: right }
-
-div.sidebar p.rubric {
-  font-family: sans-serif ;
-  font-size: medium }
-
-div.system-messages {
-  margin: 5em }
-
-div.system-messages h1 {
-  color: red }
-
-div.system-message {
-  border: medium outset ;
-  padding: 1em }
-
-div.system-message p.system-message-title {
-  color: red ;
-  font-weight: bold }
-
-div.topic {
-  margin: 2em }
-
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
-  margin-top: 0.4em }
-
-h1 {
-  font-family: sans-serif ;
-  font-size: large }
-
-h2 {
-  font-family: sans-serif ;
-  font-size: medium }
-
-h3 {
-  font-family: sans-serif ;
-  font-size: small }
-
-h4 {
-  font-family: sans-serif ;
-  font-style: italic ;
-  font-size: small }
-
-h5 {
-  font-family: sans-serif;
-  font-size: x-small }
-
-h6 {
-  font-family: sans-serif;
-  font-style: italic ;
-  font-size: x-small }
-
-hr.docutils {
-  width: 75% }
-
-img.align-left {
-  clear: left }
-
-img.align-right {
-  clear: right }
-
-img.borderless {
-  border: 0 }
-
-ol.simple, ul.simple {
-  margin-bottom: 1em }
-
-ol.arabic {
-  list-style: decimal }
-
-ol.loweralpha {
-  list-style: lower-alpha }
-
-ol.upperalpha {
-  list-style: upper-alpha }
-
-ol.lowerroman {
-  list-style: lower-roman }
-
-ol.upperroman {
-  list-style: upper-roman }
-
-p.attribution {
-  text-align: right ;
-  margin-left: 50% }
-
-p.caption {
-  font-style: italic }
-
-p.credits {
-  font-style: italic ;
-  font-size: smaller }
-
-p.label {
-  white-space: nowrap }
-
-p.rubric {
-  font-weight: bold ;
-  font-size: larger ;
-  color: maroon ;
-  text-align: center }
-
-p.sidebar-title {
-  font-family: sans-serif ;
-  font-weight: bold ;
-  font-size: larger }
-
-p.sidebar-subtitle {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-p.topic-title {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-pre.address {
-  margin-bottom: 0 ;
-  margin-top: 0 ;
-  font-family: serif ;
-  font-size: 100% }
-
-pre.line-block {
-  font-family: serif ;
-  font-size: 100% }
-
-pre.literal-block, pre.doctest-block {
-  margin-left: 2em ;
-  margin-right: 2em ;
-  background-color: #eeeeee }
-
-span.classifier {
-  font-family: sans-serif ;
-  font-style: oblique }
-
-span.classifier-delimiter {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-span.interpreted {
-  font-family: sans-serif }
-
-span.option {
-  white-space: nowrap }
-
-span.option-argument {
-  font-style: italic }
-
-span.pre {
-  white-space: pre }
-
-span.problematic {
-  color: red }
-
-span.section-subtitle {
-  /* font-size relative to parent (h1..h6 element) */
-  font-size: 80% }
-
-table.citation {
-  border-left: solid thin gray }
-
-table.docinfo {
-  margin: 2em 4em }
-
-table.docutils {
-  margin-top: 0.5em ;
-  margin-bottom: 0.5em }
-
-table.footnote {
-  border-left: solid thin black }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
-  padding-left: 0.5em ;
-  padding-right: 0.5em ;
-  vertical-align: top }
-
-td.num {
-  text-align: right }
-
-th.field-name {
-  font-weight: bold ;
-  text-align: left ;
-  white-space: nowrap ;
-  padding-left: 0 }
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
-  font-size: 100% }
-
-tt.docutils {
-  background-color: #eeeeee }
-
-ul.auto-toc {
-  list-style-type: none }

+ 0 - 29
desktop/core/ext-py/configobj/docs/stylesheets/pysrc.css

@@ -1,29 +0,0 @@
-.pysrc {
-    border: #c0c0ff 2px dotted;  padding:10px;
-    font-weight: normal; background: #e0e0ff; margin: 20px;  
-    padding:10px; 
-}
-
-.pykeyword {
-    font-weight: bold;
-    color: orange;
-}
-.pystring {
-	color: green
-}
-.pycomment {
-	color: red
-}
-.pynumber {
-    color:purple;
-}
-.pyoperator {
-    color:purple;
-}
-.pytext {
-    color:black;
-}
-.pyerror {
-    font-wieght: bold;
-    color: red;
-}

+ 0 - 624
desktop/core/ext-py/configobj/docs/validate.html

@@ -1,624 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
-<title>Validation Schema with validate.py</title>
-<meta name="authors" content="Michael Foord  Nicola Larosa  Mark Andrews" />
-<meta name="date" content="2009/04/13" />
-<link rel="stylesheet" href="stylesheets/voidspace_docutils.css" type="text/css" />
-</head>
-<body>
-<div class="document" id="validation-schema-with-validate-py">
-<h1 class="title">Validation Schema with validate.py</h1>
-<h2 class="subtitle" id="using-the-validator-class">Using the Validator class</h2>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Authors:</th>
-<td>Michael Foord
-<br />Nicola Larosa
-<br />Mark Andrews</td></tr>
-<tr><th class="docinfo-name">Version:</th>
-<td>Validate 1.0.0</td></tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>2009/04/13</td></tr>
-<tr class="field"><th class="docinfo-name">Homepage:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">Validate Homepage</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">Repository:</th><td class="field-body"><a class="reference external" href="http://code.google.com/p/configobj/">Google code homepage</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">PyPI Entry:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/validate">Validate on Python Packaging Index</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">License:</th><td class="field-body"><a class="reference external" href="http://www.voidspace.org.uk/python/license.shtml">BSD License</a></td>
-</tr>
-<tr class="field"><th class="docinfo-name">Support:</th><td class="field-body"><a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a></td>
-</tr>
-</tbody>
-</table>
-<div class="contents topic" id="validate-manual">
-<p class="topic-title first">Validate Manual</p>
-<ul class="auto-toc simple">
-<li><a class="reference internal" href="#introduction" id="id1">1&nbsp;&nbsp;&nbsp;Introduction</a></li>
-<li><a class="reference internal" href="#downloading" id="id2">2&nbsp;&nbsp;&nbsp;Downloading</a><ul class="auto-toc">
-<li><a class="reference internal" href="#files" id="id3">2.1&nbsp;&nbsp;&nbsp;Files</a></li>
-<li><a class="reference internal" href="#documentation" id="id4">2.2&nbsp;&nbsp;&nbsp;Documentation</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#the-standard-functions" id="id5">3&nbsp;&nbsp;&nbsp;The standard functions</a></li>
-<li><a class="reference internal" href="#using-validator" id="id6">4&nbsp;&nbsp;&nbsp;Using Validator</a><ul class="auto-toc">
-<li><a class="reference internal" href="#instantiate" id="id7">4.1&nbsp;&nbsp;&nbsp;Instantiate</a></li>
-<li><a class="reference internal" href="#adding-functions" id="id8">4.2&nbsp;&nbsp;&nbsp;Adding functions</a></li>
-<li><a class="reference internal" href="#writing-the-check" id="id9">4.3&nbsp;&nbsp;&nbsp;Writing the check</a></li>
-<li><a class="reference internal" href="#the-check-method" id="id10">4.4&nbsp;&nbsp;&nbsp;The check method</a><ul class="auto-toc">
-<li><a class="reference internal" href="#default-values" id="id11">4.4.1&nbsp;&nbsp;&nbsp;Default Values</a></li>
-<li><a class="reference internal" href="#list-values" id="id12">4.4.2&nbsp;&nbsp;&nbsp;List Values</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#get-default-value" id="id13">4.5&nbsp;&nbsp;&nbsp;get_default_value</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#validator-exceptions" id="id14">5&nbsp;&nbsp;&nbsp;Validator Exceptions</a></li>
-<li><a class="reference internal" href="#writing-check-functions" id="id15">6&nbsp;&nbsp;&nbsp;Writing check functions</a><ul class="auto-toc">
-<li><a class="reference internal" href="#example" id="id16">6.1&nbsp;&nbsp;&nbsp;Example</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#known-issues" id="id17">7&nbsp;&nbsp;&nbsp;Known Issues</a></li>
-<li><a class="reference internal" href="#todo" id="id18">8&nbsp;&nbsp;&nbsp;TODO</a></li>
-<li><a class="reference internal" href="#issues" id="id19">9&nbsp;&nbsp;&nbsp;ISSUES</a></li>
-<li><a class="reference internal" href="#changelog" id="id20">10&nbsp;&nbsp;&nbsp;CHANGELOG</a><ul class="auto-toc">
-<li><a class="reference internal" href="#version-1-0-0" id="id21">10.1&nbsp;&nbsp;&nbsp;2009/04/13 - Version 1.0.0</a></li>
-<li><a class="reference internal" href="#version-0-3-2" id="id22">10.2&nbsp;&nbsp;&nbsp;2008/02/24 - Version 0.3.2</a></li>
-<li><a class="reference internal" href="#version-0-3-1" id="id23">10.3&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.1</a></li>
-<li><a class="reference internal" href="#version-0-3-0" id="id24">10.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.0</a></li>
-<li><a class="reference internal" href="#version-0-2-3" id="id25">10.5&nbsp;&nbsp;&nbsp;2007/02/04      Version 0.2.3</a></li>
-<li><a class="reference internal" href="#version-0-2-3-alpha1" id="id26">10.6&nbsp;&nbsp;&nbsp;2006/12/17      Version 0.2.3-alpha1</a></li>
-<li><a class="reference internal" href="#version-0-2-2" id="id27">10.7&nbsp;&nbsp;&nbsp;2006/04/29      Version 0.2.2</a></li>
-<li><a class="reference internal" href="#version-0-2-1" id="id28">10.8&nbsp;&nbsp;&nbsp;2005/12/16      Version 0.2.1</a></li>
-<li><a class="reference internal" href="#version-0-2-0" id="id29">10.9&nbsp;&nbsp;&nbsp;2005/08/18      Version 0.2.0</a></li>
-<li><a class="reference internal" href="#version-0-1-0" id="id30">10.10&nbsp;&nbsp;&nbsp;2005/02/01      Version 0.1.0</a></li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section" id="introduction">
-<h1><a class="toc-backref" href="#id1">1&nbsp;&nbsp;&nbsp;Introduction</a></h1>
-<p>Validation is used to check that supplied values conform to a specification.</p>
-<p>The value can be supplied as a string, e.g. from a config file. In this case
-the check will also <em>convert</em> the value to the required type. This allows you
-to add validation as a transparent layer to access data stored as strings. The
-validation checks that the data is correct <em>and</em> converts it to the expected
-type.</p>
-<p>Checks are also strings, and are easy to write. One generic system can be used
-to validate information from different sources via a single consistent
-mechanism.</p>
-<p>Checks look like function calls, and map to function calls. They can include
-parameters and keyword arguments. These arguments are passed to the relevant
-function by the <tt class="docutils literal"><span class="pre">Validator</span></tt> instance, along with the value being checked.</p>
-<p>The syntax for checks also allows for specifying a default value. This default
-value can be <tt class="docutils literal"><span class="pre">None</span></tt>, no matter what the type of the check. This can be used
-to indicate that a value was missing, and so holds no useful value.</p>
-<p>Functions either return a new value, or raise an exception. See <a class="reference internal" href="#validator-exceptions">Validator
-Exceptions</a> for the low down on the exception classes that <tt class="docutils literal"><span class="pre">validate.py</span></tt>
-defines.</p>
-<p>Some standard functions are provided, for basic data types; these come built
-into every validator. Additional checks are easy to write: they can be provided
-when the <tt class="docutils literal"><span class="pre">Validator</span></tt> is instantiated, or added afterwards.</p>
-<p>Validate was primarily written to support <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a>, but is designed to be
-applicable to many other situations.</p>
-<p>For support and bug reports please use the ConfigObj <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
-</div>
-<div class="section" id="downloading">
-<h1><a class="toc-backref" href="#id2">2&nbsp;&nbsp;&nbsp;Downloading</a></h1>
-<p>The current version is <strong>1.0.0</strong>, dated 24th February 2008.</p>
-<p>You can get obtain validate in the following ways :</p>
-<div class="section" id="files">
-<h2><a class="toc-backref" href="#id3">2.1&nbsp;&nbsp;&nbsp;Files</a></h2>
-<ul>
-<li><p class="first"><a class="reference external" href="http://www.voidspace.org.uk/cgi-bin/voidspace/download/validate.py">validate.py</a> from Voidspace</p>
-</li>
-<li><p class="first">configobj.zip from Voidspace - See the homepage of <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> for the latest
-version and download links.</p>
-<blockquote>
-<p>This contains validate.py and <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a>. (As well as <a class="reference external" href="http://www.voidspace.org.uk/python/configobj.html">ConfigObj</a> and
-the ConfigObj documentation).</p>
-</blockquote>
-</li>
-<li><p class="first">The latest development version can be obtained from the <a class="reference external" href="http://code.google.com/p/configobj/">Subversion Repository</a>.</p>
-</li>
-</ul>
-</div>
-<div class="section" id="documentation">
-<h2><a class="toc-backref" href="#id4">2.2&nbsp;&nbsp;&nbsp;Documentation</a></h2>
-<p><em>configobj.zip</em> contains <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a>.</p>
-<ul class="simple">
-<li>You can view <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">this document</a> online as the <a class="reference external" href="http://www.voidspace.org.uk/python/validate.html">Validate Homepage</a>.</li>
-</ul>
-</div>
-</div>
-<div class="section" id="the-standard-functions">
-<h1><a class="toc-backref" href="#id5">3&nbsp;&nbsp;&nbsp;The standard functions</a></h1>
-<p>The standard functions come built-in to every <tt class="docutils literal"><span class="pre">Validator</span></tt> instance. They work
-with the following basic data types :</p>
-<ul class="simple">
-<li>integer</li>
-<li>float</li>
-<li>boolean</li>
-<li>string</li>
-<li>ip_addr</li>
-</ul>
-<p>plus lists of these datatypes.</p>
-<p>Adding additional checks is done through coding simple functions.</p>
-<p>The full set of standard checks are :</p>
-<table class="docutils field-list" frame="void" rules="none">
-<col class="field-name" />
-<col class="field-body" />
-<tbody valign="top">
-<tr class="field"><th class="field-name">'integer':</th><td class="field-body"><p class="first">matches integer values (including negative). Takes optional 'min'
-and 'max' arguments :</p>
-<pre class="literal-block">
-integer()
-integer(3, 9)    # any value from 3 to 9
-integer(min=0) # any positive value
-integer(max=9)
-</pre>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'float':</th><td class="field-body"><p class="first">matches float values
-Has the same parameters as the integer check.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'boolean':</th><td class="field-body"><dl class="first docutils">
-<dt>matches boolean values: <tt class="docutils literal"><span class="pre">True</span></tt> or <tt class="docutils literal"><span class="pre">False</span></tt>.</dt>
-<dd><p class="first">Acceptable string values for True are :</p>
-<pre class="last literal-block">
-true, on, yes, 1
-</pre>
-</dd>
-</dl>
-<p>Acceptable string values for False are :</p>
-<pre class="literal-block">
-false, off, no, 0
-</pre>
-<p>Any other value raises an error.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'string':</th><td class="field-body"><p class="first">matches any string. Takes optional keyword args 'min' and 'max' to
-specify min and max length of string.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'ip_addr':</th><td class="field-body"><p class="first">matches an Internet Protocol address, v.4, represented by a
-dotted-quad string, i.e. '1.2.3.4'.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'list':</th><td class="field-body"><p class="first">matches any list. Takes optional keyword args 'min', and 'max' to
-specify min and max sizes of the list. The list checks always
-return a list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">force_list:</th><td class="field-body"><p class="first">matches any list, but if a single value is passed in will
-coerce it into a list containing that value. Useful for
-configobj if the user forgot the trailing comma to turn
-a single value into a list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'tuple':</th><td class="field-body"><p class="first">matches any list. This check returns a tuple rather than a list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'int_list':</th><td class="field-body"><p class="first">Matches a list of integers. Takes the same arguments as list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'float_list':</th><td class="field-body"><p class="first">Matches a list of floats. Takes the same arguments as list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'bool_list':</th><td class="field-body"><p class="first">Matches a list of boolean values. Takes the same arguments as
-list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'string_list':</th><td class="field-body"><p class="first">Matches a list of strings. Takes the same arguments as list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'ip_addr_list':</th><td class="field-body"><p class="first">Matches a list of IP addresses. Takes the same arguments as
-list.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'mixed_list':</th><td class="field-body"><p class="first">Matches a list with different types in specific positions.
-List size must match the number of arguments.</p>
-<p>Each position can be one of :</p>
-<pre class="literal-block">
-int, str, boolean, float, ip_addr
-</pre>
-<p>So to specify a list with two strings followed by two integers,
-you write the check as :</p>
-<pre class="literal-block">
-mixed_list(str, str, int, int)
-</pre>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'pass':</th><td class="field-body"><p class="first">matches everything: it never fails and the value is unchanged. It is
-also the default if no check is specified.</p>
-</td>
-</tr>
-<tr class="field"><th class="field-name">'option':</th><td class="field-body"><p class="first">matches any from a list of options.
-You specify this test with :</p>
-<pre class="last literal-block">
-option('option 1', 'option 2', 'option 3')
-</pre>
-</td>
-</tr>
-</tbody>
-</table>
-<p>The following code will work without you having to specifically add the
-functions yourself.</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">newval1</span> <span class="pyoperator">=</span> <span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">check</span><span class="pyoperator">(</span><span class="pystring">'integer'</span><span class="pyoperator">,</span> <span class="pytext">value1</span><span class="pyoperator">)</span><br />
-<span class="pytext">newval2</span> <span class="pyoperator">=</span> <span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">check</span><span class="pyoperator">(</span><span class="pystring">'boolean'</span><span class="pyoperator">,</span> <span class="pytext">value2</span><span class="pyoperator">)</span><br />
-<span class="pycomment"># etc ...</span><span class="pytext"></span></div><div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">Of course, if these checks fail they raise exceptions. So you should wrap
-them in <tt class="docutils literal"><span class="pre">try...except</span></tt> blocks. Better still,  use ConfigObj for a higher
-level interface.</p>
-</div>
-</div>
-<div class="section" id="using-validator">
-<h1><a class="toc-backref" href="#id6">4&nbsp;&nbsp;&nbsp;Using Validator</a></h1>
-<p>Using <tt class="docutils literal"><span class="pre">Validator</span></tt> is very easy. It has one public attribute and one public
-method.</p>
-<p>Shown below are the different steps in using <tt class="docutils literal"><span class="pre">Validator</span></tt>.</p>
-<p>The only additional thing you need to know, is about <a class="reference internal" href="#writing-check-functions">Writing check
-functions</a>.</p>
-<div class="section" id="instantiate">
-<h2><a class="toc-backref" href="#id7">4.1&nbsp;&nbsp;&nbsp;Instantiate</a></h2>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>or even :</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">fdict</span> <span class="pyoperator">=</span> <span class="pyoperator">{</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'check_name1'</span><span class="pyoperator">:</span> <span class="pytext">function1</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'check_name2'</span><span class="pyoperator">:</span> <span class="pytext">function2</span><span class="pyoperator">,</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">'check_name3'</span><span class="pyoperator">:</span> <span class="pytext">function3</span><span class="pyoperator">,</span><br />
-<span class="pyoperator">}</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pytext">fdict</span><span class="pyoperator">)</span><span class="pytext"></span></div><p>The second method adds a set of your functions as soon as your validator is
-created. They are stored in the <tt class="docutils literal"><span class="pre">vtor.functions</span></tt> dictionary. The 'key' you
-give them in this dictionary is the name you use in your checks (not the
-original function name).</p>
-<p>Dictionary keys/functions you pass in can override the built-in ones if you
-want.</p>
-</div>
-<div class="section" id="adding-functions">
-<h2><a class="toc-backref" href="#id8">4.2&nbsp;&nbsp;&nbsp;Adding functions</a></h2>
-<p>The code shown above, for adding functions on instantiation, has exactly the
-same effect as the following code :</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">functions</span><span class="pyoperator">[</span><span class="pystring">'check_name1'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">function1</span><br />
-<span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">functions</span><span class="pyoperator">[</span><span class="pystring">'check_name2'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">function2</span><br />
-<span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">functions</span><span class="pyoperator">[</span><span class="pystring">'check_name3'</span><span class="pyoperator">]</span> <span class="pyoperator">=</span> <span class="pytext">function3</span><span class="pytext"></span></div><p><tt class="docutils literal"><span class="pre">vtor.functions</span></tt> is just a dictionary that maps names to functions, so we
-could also have called <tt class="docutils literal"><span class="pre">vtor.functions.update(fdict)</span></tt>.</p>
-</div>
-<div class="section" id="writing-the-check">
-<h2><a class="toc-backref" href="#id9">4.3&nbsp;&nbsp;&nbsp;Writing the check</a></h2>
-<p>As we've heard, the checks map to the names in the <tt class="docutils literal"><span class="pre">functions</span></tt> dictionary.
-You've got a full list of <a class="reference internal" href="#the-standard-functions">The standard functions</a> and the arguments they
-take.</p>
-<p>If you're using <tt class="docutils literal"><span class="pre">Validator</span></tt> from ConfigObj, then your checks will look like
-:</p>
-<pre class="literal-block">
-keyword = int_list(max=6)
-</pre>
-<p>but the check part will be identical .</p>
-</div>
-<div class="section" id="the-check-method">
-<h2><a class="toc-backref" href="#id10">4.4&nbsp;&nbsp;&nbsp;The check method</a></h2>
-<p>If you're not using <tt class="docutils literal"><span class="pre">Validator</span></tt> from ConfigObj, then you'll need to call the
-<tt class="docutils literal"><span class="pre">check</span></tt> method yourself.</p>
-<p>If the check fails then it will raise an exception, so you'll want to trap
-that. Here's the basic example :</p>
-<div class="pysrc"><span class="pykeyword">from</span> <span class="pytext">validate</span> <span class="pykeyword">import</span> <span class="pytext">Validator</span><span class="pyoperator">,</span> <span class="pytext">ValidateError</span><br />
-<span class="pycomment">#<br />
-</span><span class="pytext">vtor</span> <span class="pyoperator">=</span> <span class="pytext">Validator</span><span class="pyoperator">(</span><span class="pyoperator">)</span><br />
-<span class="pytext">check</span> <span class="pyoperator">=</span> <span class="pystring">"integer(0, 9)"</span><br />
-<span class="pytext">value</span> <span class="pyoperator">=</span> <span class="pynumber">3</span><br />
-<span class="pykeyword">try</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">newvalue</span> <span class="pyoperator">=</span> <span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">check</span><span class="pyoperator">(</span><span class="pytext">check</span><span class="pyoperator">,</span> <span class="pytext">value</span><span class="pyoperator">)</span><br />
-<span class="pykeyword">except</span> <span class="pytext">ValidateError</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'Check Failed.'</span><br />
-<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">print</span> <span class="pystring">'Check passed.'</span><span class="pytext"></span></div><div class="caution">
-<p class="first admonition-title">Caution!</p>
-<p class="last">Although the value can be a string, if it represents a list it should
-already have been turned into a list of strings.</p>
-</div>
-<div class="section" id="default-values">
-<h3><a class="toc-backref" href="#id11">4.4.1&nbsp;&nbsp;&nbsp;Default Values</a></h3>
-<p>Some values may not be available, and you may want to be able to specify a
-default as part of the check.</p>
-<p>You do this by passing the keyword <tt class="docutils literal"><span class="pre">missing=True</span></tt> to the <tt class="docutils literal"><span class="pre">check</span></tt> method, as
-well as a <tt class="docutils literal"><span class="pre">default=value</span></tt> in the check. (Constructing these checks is done
-automatically by ConfigObj: you only need to know about the <tt class="docutils literal"><span class="pre">default=value</span></tt>
-part) :</p>
-<div class="pysrc"><span class="pytext">check1</span> <span class="pyoperator">=</span> <span class="pystring">'integer(default=50)'</span><br />
-<span class="pytext">check2</span> <span class="pyoperator">=</span> <span class="pystring">'option("val 1", "val 2", "val 3", default="val 1")'</span><br />
-<br />
-<span class="pykeyword">assert</span> <span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">check</span><span class="pyoperator">(</span><span class="pytext">check1</span><span class="pyoperator">,</span> <span class="pystring">''</span><span class="pyoperator">,</span> <span class="pytext">missing</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span> <span class="pyoperator">==</span> <span class="pynumber">50</span><br />
-<span class="pykeyword">assert</span> <span class="pytext">vtor</span><span class="pyoperator">.</span><span class="pytext">check</span><span class="pyoperator">(</span><span class="pytext">check2</span><span class="pyoperator">,</span> <span class="pystring">''</span><span class="pyoperator">,</span> <span class="pytext">missing</span><span class="pyoperator">=</span><span class="pytext">True</span><span class="pyoperator">)</span> <span class="pyoperator">==</span> <span class="pystring">"val 1"</span><span class="pytext"></span></div><p>If you pass in <tt class="docutils literal"><span class="pre">missing=True</span></tt> to the check method, then the actual value is
-ignored. If no default is specified in the check, a <tt class="docutils literal"><span class="pre">ValidateMissingValue</span></tt>
-exception is raised. If a default is specified then that is passed to the
-check instead.</p>
-<p>If the check has <tt class="docutils literal"><span class="pre">default=None</span></tt> (case sensitive) then <tt class="docutils literal"><span class="pre">vtor.check</span></tt> will
-<em>always</em> return <tt class="docutils literal"><span class="pre">None</span></tt> (the object). This makes it easy to tell your program
-that this check contains no useful value when missing, i.e. the value is
-optional, and may be omitted without harm.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">As of version 0.3.0, if you specify <tt class="docutils literal"><span class="pre">default='None'</span></tt> (note the quote marks
-around <tt class="docutils literal"><span class="pre">None</span></tt>) then it will be interpreted as the string <tt class="docutils literal"><span class="pre">'None'</span></tt>.</p>
-</div>
-</div>
-<div class="section" id="list-values">
-<h3><a class="toc-backref" href="#id12">4.4.2&nbsp;&nbsp;&nbsp;List Values</a></h3>
-<p>It's possible that you would like your default value to be a list. It's even
-possible that you will write your own check functions - and would like to pass
-them keyword arguments as lists from within the check.</p>
-<p>To avoid confusing syntax with commas and quotes you use a list constructor to
-specify that keyword arguments are lists. This includes the <tt class="docutils literal"><span class="pre">default</span></tt> value.
-This makes checks look something like :</p>
-<pre class="literal-block">
-checkname(default=list('val1', 'val2', 'val3'))
-</pre>
-</div>
-</div>
-<div class="section" id="get-default-value">
-<h2><a class="toc-backref" href="#id13">4.5&nbsp;&nbsp;&nbsp;get_default_value</a></h2>
-<p><tt class="docutils literal"><span class="pre">Validator</span></tt> instances have a <tt class="docutils literal"><span class="pre">get_default_value</span></tt> method. It takes a <tt class="docutils literal"><span class="pre">check</span></tt> string
-(the same string you would pass to the <tt class="docutils literal"><span class="pre">check</span></tt> method) and returns the default value,
-converted to the right type. If the check doesn't define a default value then this method
-raises a <tt class="docutils literal"><span class="pre">KeyError</span></tt>.</p>
-<p>If the <tt class="docutils literal"><span class="pre">check</span></tt> has been seen before then it will have been parsed and cached already,
-so this method is not expensive to call (however the conversion is done each time).</p>
-</div>
-</div>
-<div class="section" id="validator-exceptions">
-<h1><a class="toc-backref" href="#id14">5&nbsp;&nbsp;&nbsp;Validator Exceptions</a></h1>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">If you only use Validator through ConfigObj, it traps these Exceptions for
-you. You will still need to know about them for writing your own check
-functions.</p>
-</div>
-<p><tt class="docutils literal"><span class="pre">vtor.check</span></tt> indicates that the check has failed by raising an exception.
-The appropriate error should be raised in the check function.</p>
-<p>The base error class is <tt class="docutils literal"><span class="pre">ValidateError</span></tt>. All errors (except for <tt class="docutils literal"><span class="pre">VdtParamError</span></tt>)
-raised are sub-classes of this.</p>
-<p>If an unrecognised check is specified then <tt class="docutils literal"><span class="pre">VdtUnknownCheckError</span></tt> is
-raised.</p>
-<p>There are also <tt class="docutils literal"><span class="pre">VdtTypeError</span></tt> and <tt class="docutils literal"><span class="pre">VdtValueError</span></tt>.</p>
-<p>If incorrect parameters are passed to a check function then it will (or should)
-raise <tt class="docutils literal"><span class="pre">VdtParamError</span></tt>. As this indicates <em>programmer</em> error, rather than an error
-in the value, it is a subclass of <tt class="docutils literal"><span class="pre">SyntaxError</span></tt> instead of <tt class="docutils literal"><span class="pre">ValidateError</span></tt>.</p>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">This means it <em>won't</em> be caught by ConfigObj - but propagated instead.</p>
-</div>
-<p>If the value supplied is the wrong type, then the check should raise
-<tt class="docutils literal"><span class="pre">VdtTypeError</span></tt>. e.g. the check requires the value to be an integer (or
-representation of an integer) and something else was supplied.</p>
-<p>If the value supplied is the right type, but an unacceptable value, then the
-check should raise <tt class="docutils literal"><span class="pre">VdtValueError</span></tt>. e.g. the check requires the value to
-be an integer (or representation of an integer) less than ten and a higher
-value was supplied.</p>
-<p>Both <tt class="docutils literal"><span class="pre">VdtTypeError</span></tt> and <tt class="docutils literal"><span class="pre">VdtValueError</span></tt> are initialised with the
-incorrect value. In other words you raise them like this :</p>
-<div class="pysrc"><span class="pykeyword">raise</span> <span class="pytext">VdtTypeError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-<span class="pycomment">#<br />
-</span><span class="pykeyword">raise</span> <span class="pytext">VdtValueError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><span class="pytext"></span></div><p><tt class="docutils literal"><span class="pre">VdtValueError</span></tt> has the following subclasses, which should be raised if
-they are more appropriate.</p>
-<ul class="simple">
-<li><tt class="docutils literal"><span class="pre">VdtValueTooSmallError</span></tt></li>
-<li><tt class="docutils literal"><span class="pre">VdtValueTooBigError</span></tt></li>
-<li><tt class="docutils literal"><span class="pre">VdtValueTooShortError</span></tt></li>
-<li><tt class="docutils literal"><span class="pre">VdtValueTooLongError</span></tt></li>
-</ul>
-</div>
-<div class="section" id="writing-check-functions">
-<h1><a class="toc-backref" href="#id15">6&nbsp;&nbsp;&nbsp;Writing check functions</a></h1>
-<p>Writing check functions is easy.</p>
-<p>The check function will receive the value as its first argument, followed by
-any other parameters and keyword arguments.</p>
-<p>If the check fails, it should raise a <tt class="docutils literal"><span class="pre">VdtTypeError</span></tt> or a
-<tt class="docutils literal"><span class="pre">VdtValueError</span></tt> (or an appropriate subclass).</p>
-<p>All parameters and keyword arguments are <em>always</em> passed as strings. (Parsed
-from the check string).</p>
-<p>The value might be a string (or list of strings) and need
-converting to the right type - alternatively it might already be a list of
-integers. Our function needs to be able to handle either.</p>
-<p>If the check passes then it should return the value (possibly converted to the
-right type).</p>
-<p>And that's it !</p>
-<div class="section" id="example">
-<h2><a class="toc-backref" href="#id16">6.1&nbsp;&nbsp;&nbsp;Example</a></h2>
-<p>Here is an example function that requires a list of integers. Each integer
-must be between 0 and 99.</p>
-<p>It takes a single argument specifying the length of the list. (Which allows us
-to use the same check in more than one place). If the length can't be converted
-to an integer then we need to raise <tt class="docutils literal"><span class="pre">VdtParamError</span></tt>.</p>
-<p>Next we check that the value is a list. Anything else should raise a
-<tt class="docutils literal"><span class="pre">VdtTypeError</span></tt>. The list should also have 'length' entries. If the list
-has more or less entries then we will need to raise a
-<tt class="docutils literal"><span class="pre">VdtValueTooShortError</span></tt> or a <tt class="docutils literal"><span class="pre">VdtValueTooLongError</span></tt>.</p>
-<p>Then we need to check every entry in the list. Each entry should be an integer
-between 0 and 99, or a string representation of an integer between 0 and 99.
-Any other type is a <tt class="docutils literal"><span class="pre">VdtTypeError</span></tt>, any other value is a
-<tt class="docutils literal"><span class="pre">VdtValueError</span></tt> (either too big, or too small).</p>
-<div class="pysrc"><span class="pykeyword">def</span> <span class="pytext">special_list</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">,</span> <span class="pytext">length</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pystring">"""<br />
-&nbsp;&nbsp;&nbsp;&nbsp;Check that the supplied value is a list of integers,<br />
-&nbsp;&nbsp;&nbsp;&nbsp;with 'length' entries, and each entry between 0 and 99.<br />
-&nbsp;&nbsp;&nbsp;&nbsp;"""</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># length is supplied as a string<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># we need to convert it to an integer<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">try</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">length</span> <span class="pyoperator">=</span> <span class="pytext">int</span><span class="pyoperator">(</span><span class="pytext">length</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">except</span> <span class="pytext">ValueError</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtParamError</span><span class="pyoperator">(</span><span class="pystring">'length'</span><span class="pyoperator">,</span> <span class="pytext">length</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment">#<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># Check the supplied value is a list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">,</span> <span class="pytext">list</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtTypeError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment">#<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># check the length of the list is correct<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">len</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span> <span class="pyoperator">&gt;</span> <span class="pytext">length</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtValueTooLongError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">elif</span> <span class="pytext">len</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span> <span class="pyoperator">&lt;</span> <span class="pytext">length</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtValueTooShortError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment">#<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># Next, check every member in the list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># converting strings as necessary<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">out</span> <span class="pyoperator">=</span> <span class="pyoperator">[</span><span class="pyoperator">]</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">for</span> <span class="pytext">entry</span> <span class="pykeyword">in</span> <span class="pytext">value</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">str</span><span class="pyoperator">,</span> <span class="pytext">unicode</span><span class="pyoperator">,</span> <span class="pytext">int</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># a value in the list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># is neither an integer nor a string<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtTypeError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">elif</span> <span class="pytext">isinstance</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">,</span> <span class="pyoperator">(</span><span class="pytext">str</span><span class="pyoperator">,</span> <span class="pytext">unicode</span><span class="pyoperator">)</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pykeyword">not</span> <span class="pytext">entry</span><span class="pyoperator">.</span><span class="pytext">isdigit</span><span class="pyoperator">(</span><span class="pyoperator">)</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtTypeError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">else</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">entry</span> <span class="pyoperator">=</span> <span class="pytext">int</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">if</span> <span class="pytext">entry</span> <span class="pyoperator">&lt;</span> <span class="pynumber">0</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtValueTooSmallError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">elif</span> <span class="pytext">entry</span> <span class="pyoperator">&gt;</span> <span class="pynumber">99</span><span class="pyoperator">:</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">raise</span> <span class="pytext">VdtValueTooBigError</span><span class="pyoperator">(</span><span class="pytext">value</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="pytext">out</span><span class="pyoperator">.</span><span class="pytext">append</span><span class="pyoperator">(</span><span class="pytext">entry</span><span class="pyoperator">)</span><br />
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment">#<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># if we got this far, all is well<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pycomment"># return the new list<br />
-</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="pykeyword">return</span> <span class="pytext">out</span><span class="pytext"></span></div><p>If you are only using validate from ConfigObj then the error type (<em>TooBig</em>,
-<em>TooSmall</em>, etc) is lost - so you may only want to raise <tt class="docutils literal"><span class="pre">VdtValueError</span></tt>.</p>
-<div class="caution">
-<p class="first admonition-title">Caution!</p>
-<p>If your function raises an exception that isn't a subclass of
-<tt class="docutils literal"><span class="pre">ValidateError</span></tt>, then ConfigObj won't trap it. This means validation will
-fail.</p>
-<p class="last">This is why our function starts by checking the type of the value. If we
-are passed the wrong type (e.g. an integer rather than a list) we get a
-<tt class="docutils literal"><span class="pre">VdtTypeError</span></tt> rather than bombing out when we try to iterate over
-the value.</p>
-</div>
-<p>If you are using validate in another circumstance you may want to create your
-own subclasses of <tt class="docutils literal"><span class="pre">ValidateError</span></tt> which convey more specific information.</p>
-</div>
-</div>
-<div class="section" id="known-issues">
-<h1><a class="toc-backref" href="#id17">7&nbsp;&nbsp;&nbsp;Known Issues</a></h1>
-<p>The following parses and then blows up. The resulting error message
-is confusing:</p>
-<blockquote>
-<tt class="docutils literal"><span class="pre">checkname(default=list(1,</span> <span class="pre">2,</span> <span class="pre">3,</span> <span class="pre">4)</span></tt></blockquote>
-<p>This is because it parses as: <tt class="docutils literal"><span class="pre">checkname(default=&quot;list(1&quot;,</span> <span class="pre">2,</span> <span class="pre">3,</span> <span class="pre">4)</span></tt>.
-That isn't actually unreasonable, but the error message won't help you
-work out what has happened.</p>
-</div>
-<div class="section" id="todo">
-<h1><a class="toc-backref" href="#id18">8&nbsp;&nbsp;&nbsp;TODO</a></h1>
-<ul class="simple">
-<li>A regex check function ?</li>
-<li>A timestamp check function ? (Using the <tt class="docutils literal"><span class="pre">parse</span></tt> function from <tt class="docutils literal"><span class="pre">DateUtil</span></tt> perhaps).</li>
-</ul>
-</div>
-<div class="section" id="issues">
-<h1><a class="toc-backref" href="#id19">9&nbsp;&nbsp;&nbsp;ISSUES</a></h1>
-<div class="note">
-<p class="first admonition-title">Note</p>
-<p class="last">Please file any bug reports to <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a> or the ConfigObj
-<a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/configobj-develop">Mailing List</a>.</p>
-</div>
-<p>If we could pull tuples out of arguments, it would be easier
-to specify arguments for 'mixed_lists'.</p>
-</div>
-<div class="section" id="changelog">
-<h1><a class="toc-backref" href="#id20">10&nbsp;&nbsp;&nbsp;CHANGELOG</a></h1>
-<div class="section" id="version-1-0-0">
-<h2><a class="toc-backref" href="#id21">10.1&nbsp;&nbsp;&nbsp;2009/04/13 - Version 1.0.0</a></h2>
-<ul class="simple">
-<li>BUGFIX: can now handle multiline strings.</li>
-<li>Addition of 'force_list' validation option.</li>
-</ul>
-<p>As the API is stable and there are no known bugs or outstanding feature requests I am marking this 1.0.</p>
-</div>
-<div class="section" id="version-0-3-2">
-<h2><a class="toc-backref" href="#id22">10.2&nbsp;&nbsp;&nbsp;2008/02/24 - Version 0.3.2</a></h2>
-<p>BUGFIX: Handling of None as default value fixed.</p>
-</div>
-<div class="section" id="version-0-3-1">
-<h2><a class="toc-backref" href="#id23">10.3&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.1</a></h2>
-<p>BUGFIX: Unicode checks no longer broken.</p>
-</div>
-<div class="section" id="version-0-3-0">
-<h2><a class="toc-backref" href="#id24">10.4&nbsp;&nbsp;&nbsp;2008/02/05 - Version 0.3.0</a></h2>
-<p>Improved performance with a parse cache.</p>
-<p>New <tt class="docutils literal"><span class="pre">get_default_value</span></tt> method. Given a check it returns the default
-value (converted to the correct type) or raises a <tt class="docutils literal"><span class="pre">KeyError</span></tt> if the
-check doesn't specify a default.</p>
-<p>Added 'tuple' check and corresponding 'is_tuple' function (which always returns a tuple).</p>
-<p>BUGFIX: A quoted 'None' as a default value is no longer treated as None,
-but as the string 'None'.</p>
-<p>BUGFIX: We weren't unquoting keyword arguments of length two, so an
-empty string didn't work as a default.</p>
-<p>BUGFIX: Strings no longer pass the 'is_list' check. Additionally, the
-list checks always return lists.</p>
-<p>A couple of documentation bug fixes.</p>
-<p>Removed CHANGELOG from module.</p>
-</div>
-<div class="section" id="version-0-2-3">
-<h2><a class="toc-backref" href="#id25">10.5&nbsp;&nbsp;&nbsp;2007/02/04      Version 0.2.3</a></h2>
-<p>Release of 0.2.3</p>
-</div>
-<div class="section" id="version-0-2-3-alpha1">
-<h2><a class="toc-backref" href="#id26">10.6&nbsp;&nbsp;&nbsp;2006/12/17      Version 0.2.3-alpha1</a></h2>
-<p>By Nicola Larosa</p>
-<p>Fixed validate doc to talk of <tt class="docutils literal"><span class="pre">boolean</span></tt> instead of <tt class="docutils literal"><span class="pre">bool</span></tt>; changed the
-<tt class="docutils literal"><span class="pre">is_bool</span></tt> function to <tt class="docutils literal"><span class="pre">is_boolean</span></tt> (Sourceforge bug #1531525).</p>
-</div>
-<div class="section" id="version-0-2-2">
-<h2><a class="toc-backref" href="#id27">10.7&nbsp;&nbsp;&nbsp;2006/04/29      Version 0.2.2</a></h2>
-<p>Addressed bug where a string would pass the <tt class="docutils literal"><span class="pre">is_list</span></tt> test. (Thanks to
-Konrad Wojas.)</p>
-</div>
-<div class="section" id="version-0-2-1">
-<h2><a class="toc-backref" href="#id28">10.8&nbsp;&nbsp;&nbsp;2005/12/16      Version 0.2.1</a></h2>
-<p>Fixed bug so we can handle keyword argument values with commas.</p>
-<p>We now use a list constructor for passing list values to keyword arguments
-(including <tt class="docutils literal"><span class="pre">default</span></tt>) :</p>
-<pre class="literal-block">
-default=list(&quot;val&quot;, &quot;val&quot;, &quot;val&quot;)
-</pre>
-<p>Added the <tt class="docutils literal"><span class="pre">_test</span></tt> test.  <img src="/smilies/smile.gif" alt="Smile" height="15" width="15" /> </p>
-<p>Moved a function call outside a try...except block.</p>
-</div>
-<div class="section" id="version-0-2-0">
-<h2><a class="toc-backref" href="#id29">10.9&nbsp;&nbsp;&nbsp;2005/08/18      Version 0.2.0</a></h2>
-<p>Updated by <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a> and <a class="reference external" href="mailto:nico&#37;&#52;&#48;teknico&#46;net">Nicola Larosa</a></p>
-<p>Does type conversion as well.</p>
-</div>
-<div class="section" id="version-0-1-0">
-<h2><a class="toc-backref" href="#id30">10.10&nbsp;&nbsp;&nbsp;2005/02/01      Version 0.1.0</a></h2>
-<p>Initial version developed by <a class="reference external" href="mailto:fuzzyman&#37;&#52;&#48;voidspace&#46;org&#46;uk">Michael Foord</a>
-and Mark Andrews.</p>
-</div>
-</div>
-</div>
-<div class="footer">
-<hr class="footer" />
-<a class="reference external" href="validate.txt">View document source</a>.
-Generated on: 2009-04-16 21:03 UTC.
-Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
-
-</div>
-</body>
-</html>

+ 0 - 31
desktop/core/ext-py/configobj/setup.py

@@ -1,31 +0,0 @@
-# setup.py
-# Install script for ConfigObj
-# Copyright (C) 2005-2009 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
-
-# This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-
-import sys
-from distutils.core import setup
-from configobj import __version__ as VERSION
-
-NAME = 'configobj'
-MODULES = 'configobj', 'validate'
-DESCRIPTION = 'Config file reading, writing, and validation.'
-URL = 'http://www.voidspace.org.uk/python/configobj.html'
-LICENSE = 'BSD'
-PLATFORMS = ["Platform Independent"]
-
-setup(name= NAME,
-      version= VERSION,
-      description= DESCRIPTION,
-      license = LICENSE,
-      platforms = PLATFORMS,
-      author= 'Michael Foord & Nicola Larosa',
-      author_email= 'fuzzyman@voidspace.org.uk',
-      url= URL,
-      py_modules = MODULES,
-     )