home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1781 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  46.1 KB  |  1,608 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import generators
  5. import sys
  6. INTP_VER = sys.version_info[:2]
  7. if INTP_VER < (2, 2):
  8.     raise RuntimeError('Python v.2.2 or later needed')
  9. INTP_VER < (2, 2)
  10. import os
  11. import re
  12. compiler = None
  13.  
  14. try:
  15.     import compiler
  16. except ImportError:
  17.     pass
  18.  
  19. from types import StringTypes
  20. from warnings import warn
  21.  
  22. try:
  23.     from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
  24. except ImportError:
  25.     BOM_UTF8 = '\xef\xbb\xbf'
  26.     BOM_UTF16_LE = '\xff\xfe'
  27.     BOM_UTF16_BE = '\xfe\xff'
  28.     if sys.byteorder == 'little':
  29.         BOM_UTF16 = BOM_UTF16_LE
  30.     else:
  31.         BOM_UTF16 = BOM_UTF16_BE
  32. except:
  33.     sys.byteorder == 'little'
  34.  
  35. BOMS = {
  36.     BOM_UTF8: ('utf_8', None),
  37.     BOM_UTF16_BE: ('utf16_be', 'utf_16'),
  38.     BOM_UTF16_LE: ('utf16_le', 'utf_16'),
  39.     BOM_UTF16: ('utf_16', 'utf_16') }
  40. BOM_LIST = {
  41.     'utf_16': 'utf_16',
  42.     'u16': 'utf_16',
  43.     'utf16': 'utf_16',
  44.     'utf-16': 'utf_16',
  45.     'utf16_be': 'utf16_be',
  46.     'utf_16_be': 'utf16_be',
  47.     'utf-16be': 'utf16_be',
  48.     'utf16_le': 'utf16_le',
  49.     'utf_16_le': 'utf16_le',
  50.     'utf-16le': 'utf16_le',
  51.     'utf_8': 'utf_8',
  52.     'u8': 'utf_8',
  53.     'utf': 'utf_8',
  54.     'utf8': 'utf_8',
  55.     'utf-8': 'utf_8' }
  56. BOM_SET = {
  57.     'utf_8': BOM_UTF8,
  58.     'utf_16': BOM_UTF16,
  59.     'utf16_be': BOM_UTF16_BE,
  60.     'utf16_le': BOM_UTF16_LE,
  61.     None: BOM_UTF8 }
  62.  
  63. def match_utf8(encoding):
  64.     return BOM_LIST.get(encoding.lower()) == 'utf_8'
  65.  
  66. squot = "'%s'"
  67. dquot = '"%s"'
  68. noquot = '%s'
  69. wspace_plus = ' \r\t\n\x0b\t\'"'
  70. tsquot = '"""%s"""'
  71. tdquot = "'''%s'''"
  72.  
  73. try:
  74.     enumerate
  75. except NameError:
  76.     
  77.     def enumerate(obj):
  78.         i = -1
  79.         for item in obj:
  80.             i += 1
  81.             yield (i, item)
  82.         
  83.  
  84.  
  85.  
  86. try:
  87.     (True, False)
  88. except NameError:
  89.     (True, False) = (1, 0)
  90.  
  91. __version__ = '4.5.2'
  92. __revision__ = '$Id: configobj.py 156 2006-01-31 14:57:08Z fuzzyman $'
  93. __docformat__ = 'restructuredtext en'
  94. __all__ = ('__version__', 'DEFAULT_INDENT_TYPE', 'DEFAULT_INTERPOLATION', 'ConfigObjError', 'NestingError', 'ParseError', 'DuplicateError', 'ConfigspecError', 'ConfigObj', 'SimpleVal', 'InterpolationError', 'InterpolationLoopError', 'MissingInterpolationOption', 'RepeatSectionError', 'ReloadError', 'UnreprError', 'UnknownType', '__docformat__', 'flatten_errors')
  95. DEFAULT_INTERPOLATION = 'configparser'
  96. DEFAULT_INDENT_TYPE = '    '
  97. MAX_INTERPOL_DEPTH = 10
  98. OPTION_DEFAULTS = {
  99.     'interpolation': True,
  100.     'raise_errors': False,
  101.     'list_values': True,
  102.     'create_empty': False,
  103.     'file_error': False,
  104.     'configspec': None,
  105.     'stringify': True,
  106.     'indent_type': None,
  107.     'encoding': None,
  108.     'default_encoding': None,
  109.     'unrepr': False,
  110.     'write_empty_values': False }
  111.  
  112. def getObj(s):
  113.     s = 'a=' + s
  114.     if compiler is None:
  115.         raise ImportError('compiler module not available')
  116.     compiler is None
  117.     p = compiler.parse(s)
  118.     return p.getChildren()[1].getChildren()[0].getChildren()[1]
  119.  
  120.  
  121. class UnknownType(Exception):
  122.     pass
  123.  
  124.  
  125. class Builder(object):
  126.     
  127.     def build(self, o):
  128.         m = getattr(self, 'build_' + o.__class__.__name__, None)
  129.         if m is None:
  130.             raise UnknownType(o.__class__.__name__)
  131.         m is None
  132.         return m(o)
  133.  
  134.     
  135.     def build_List(self, o):
  136.         return map(self.build, o.getChildren())
  137.  
  138.     
  139.     def build_Const(self, o):
  140.         return o.value
  141.  
  142.     
  143.     def build_Dict(self, o):
  144.         d = { }
  145.         i = iter(map(self.build, o.getChildren()))
  146.         for el in i:
  147.             d[el] = i.next()
  148.         
  149.         return d
  150.  
  151.     
  152.     def build_Tuple(self, o):
  153.         return tuple(self.build_List(o))
  154.  
  155.     
  156.     def build_Name(self, o):
  157.         if o.name == 'None':
  158.             return None
  159.         if o.name == 'True':
  160.             return True
  161.         if o.name == 'False':
  162.             return False
  163.         raise UnknownType('Undefined Name')
  164.  
  165.     
  166.     def build_Add(self, o):
  167.         (real, imag) = map(self.build_Const, o.getChildren())
  168.         
  169.         try:
  170.             real = float(real)
  171.         except TypeError:
  172.             raise UnknownType('Add')
  173.  
  174.         if not isinstance(imag, complex) or imag.real != 0:
  175.             raise UnknownType('Add')
  176.         imag.real != 0
  177.         return real + imag
  178.  
  179.     
  180.     def build_Getattr(self, o):
  181.         parent = self.build(o.expr)
  182.         return getattr(parent, o.attrname)
  183.  
  184.     
  185.     def build_UnarySub(self, o):
  186.         return -self.build_Const(o.getChildren()[0])
  187.  
  188.     
  189.     def build_UnaryAdd(self, o):
  190.         return self.build_Const(o.getChildren()[0])
  191.  
  192.  
  193. _builder = Builder()
  194.  
  195. def unrepr(s):
  196.     if not s:
  197.         return s
  198.     return _builder.build(getObj(s))
  199.  
  200.  
  201. class ConfigObjError(SyntaxError):
  202.     
  203.     def __init__(self, message = '', line_number = None, line = ''):
  204.         self.line = line
  205.         self.line_number = line_number
  206.         self.message = message
  207.         SyntaxError.__init__(self, message)
  208.  
  209.  
  210.  
  211. class NestingError(ConfigObjError):
  212.     pass
  213.  
  214.  
  215. class ParseError(ConfigObjError):
  216.     pass
  217.  
  218.  
  219. class ReloadError(IOError):
  220.     
  221.     def __init__(self):
  222.         IOError.__init__(self, 'reload failed, filename is not set.')
  223.  
  224.  
  225.  
  226. class DuplicateError(ConfigObjError):
  227.     pass
  228.  
  229.  
  230. class ConfigspecError(ConfigObjError):
  231.     pass
  232.  
  233.  
  234. class InterpolationError(ConfigObjError):
  235.     pass
  236.  
  237.  
  238. class InterpolationLoopError(InterpolationError):
  239.     
  240.     def __init__(self, option):
  241.         InterpolationError.__init__(self, 'interpolation loop detected in value "%s".' % option)
  242.  
  243.  
  244.  
  245. class RepeatSectionError(ConfigObjError):
  246.     pass
  247.  
  248.  
  249. class MissingInterpolationOption(InterpolationError):
  250.     
  251.     def __init__(self, option):
  252.         InterpolationError.__init__(self, 'missing option "%s" in interpolation.' % option)
  253.  
  254.  
  255.  
  256. class UnreprError(ConfigObjError):
  257.     pass
  258.  
  259.  
  260. class InterpolationEngine(object):
  261.     _KEYCRE = re.compile('%\\(([^)]*)\\)s')
  262.     
  263.     def __init__(self, section):
  264.         self.section = section
  265.  
  266.     
  267.     def interpolate(self, key, value):
  268.         
  269.         def recursive_interpolate(key, value, section, backtrail):
  270.             if backtrail.has_key((key, section.name)):
  271.                 raise InterpolationLoopError(key)
  272.             backtrail.has_key((key, section.name))
  273.             backtrail[(key, section.name)] = 1
  274.             match = self._KEYCRE.search(value)
  275.             while match:
  276.                 (k, v, s) = self._parse_match(match)
  277.                 if k is None:
  278.                     replacement = v
  279.                 else:
  280.                     replacement = recursive_interpolate(k, v, s, backtrail)
  281.                 (start, end) = match.span()
  282.                 value = ''.join((value[:start], replacement, value[end:]))
  283.                 new_search_start = start + len(replacement)
  284.                 match = self._KEYCRE.search(value, new_search_start)
  285.             del backtrail[(key, section.name)]
  286.             return value
  287.  
  288.         value = recursive_interpolate(key, value, self.section, { })
  289.         return value
  290.  
  291.     
  292.     def _fetch(self, key):
  293.         save_interp = self.section.main.interpolation
  294.         self.section.main.interpolation = False
  295.         current_section = self.section
  296.         while True:
  297.             val = current_section.get(key)
  298.             if val is not None:
  299.                 break
  300.             
  301.             val = current_section.get('DEFAULT', { }).get(key)
  302.             if val is not None:
  303.                 break
  304.             
  305.             if current_section.parent is current_section:
  306.                 break
  307.             
  308.             current_section = current_section.parent
  309.         self.section.main.interpolation = save_interp
  310.         if val is None:
  311.             raise MissingInterpolationOption(key)
  312.         val is None
  313.         return (val, current_section)
  314.  
  315.     
  316.     def _parse_match(self, match):
  317.         raise NotImplementedError()
  318.  
  319.  
  320.  
  321. class ConfigParserInterpolation(InterpolationEngine):
  322.     _KEYCRE = re.compile('%\\(([^)]*)\\)s')
  323.     
  324.     def _parse_match(self, match):
  325.         key = match.group(1)
  326.         (value, section) = self._fetch(key)
  327.         return (key, value, section)
  328.  
  329.  
  330.  
  331. class TemplateInterpolation(InterpolationEngine):
  332.     _delimiter = '$'
  333.     _KEYCRE = re.compile('\n        \\$(?:\n          (?P<escaped>\\$)              |   # Two $ signs\n          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format\n          {(?P<braced>[^}]*)}              # ${name} format\n        )\n        ', re.IGNORECASE | re.VERBOSE)
  334.     
  335.     def _parse_match(self, match):
  336.         if not match.group('named'):
  337.             pass
  338.         key = match.group('braced')
  339.         if key is not None:
  340.             (value, section) = self._fetch(key)
  341.             return (key, value, section)
  342.         if match.group('escaped') is not None:
  343.             return (None, self._delimiter, None)
  344.         return (None, match.group(), None)
  345.  
  346.  
  347. interpolation_engines = {
  348.     'configparser': ConfigParserInterpolation,
  349.     'template': TemplateInterpolation }
  350.  
  351. class Section(dict):
  352.     
  353.     def __init__(self, parent, depth, main, indict = None, name = None):
  354.         if indict is None:
  355.             indict = { }
  356.         
  357.         dict.__init__(self)
  358.         self.parent = parent
  359.         self.main = main
  360.         self.depth = depth
  361.         self.name = name
  362.         self._initialise()
  363.         for entry, value in indict.iteritems():
  364.             self[entry] = value
  365.         
  366.  
  367.     
  368.     def _initialise(self):
  369.         self.scalars = []
  370.         self.sections = []
  371.         self.comments = { }
  372.         self.inline_comments = { }
  373.         self.configspec = { }
  374.         self._order = []
  375.         self._configspec_comments = { }
  376.         self._configspec_inline_comments = { }
  377.         self._cs_section_comments = { }
  378.         self._cs_section_inline_comments = { }
  379.         self.defaults = []
  380.         self.default_values = { }
  381.  
  382.     
  383.     def _interpolate(self, key, value):
  384.         
  385.         try:
  386.             engine = self._interpolation_engine
  387.         except AttributeError:
  388.             name = self.main.interpolation
  389.             if name == True:
  390.                 name = DEFAULT_INTERPOLATION
  391.             
  392.             name = name.lower()
  393.             class_ = interpolation_engines.get(name, None)
  394.             if class_ is None:
  395.                 self.main.interpolation = False
  396.                 return value
  397.         except:
  398.             engine = self._interpolation_engine = class_(self)
  399.  
  400.         return engine.interpolate(key, value)
  401.  
  402.     
  403.     def __getitem__(self, key):
  404.         val = dict.__getitem__(self, key)
  405.         if self.main.interpolation and isinstance(val, StringTypes):
  406.             return self._interpolate(key, val)
  407.         return val
  408.  
  409.     
  410.     def __setitem__(self, key, value, unrepr = False):
  411.         if not isinstance(key, StringTypes):
  412.             raise ValueError('The key "%s" is not a string.' % key)
  413.         isinstance(key, StringTypes)
  414.         if not self.comments.has_key(key):
  415.             self.comments[key] = []
  416.             self.inline_comments[key] = ''
  417.         
  418.         if key in self.defaults:
  419.             self.defaults.remove(key)
  420.         
  421.         if isinstance(value, Section):
  422.             if not self.has_key(key):
  423.                 self.sections.append(key)
  424.             
  425.             dict.__setitem__(self, key, value)
  426.         elif isinstance(value, dict) and not unrepr:
  427.             if not self.has_key(key):
  428.                 self.sections.append(key)
  429.             
  430.             new_depth = self.depth + 1
  431.             dict.__setitem__(self, key, Section(self, new_depth, self.main, indict = value, name = key))
  432.         elif not self.has_key(key):
  433.             self.scalars.append(key)
  434.         
  435.         if not self.main.stringify:
  436.             if isinstance(value, StringTypes):
  437.                 pass
  438.             elif isinstance(value, (list, tuple)):
  439.                 for entry in value:
  440.                     if not isinstance(entry, StringTypes):
  441.                         raise TypeError('Value is not a string "%s".' % entry)
  442.                     isinstance(entry, StringTypes)
  443.                 
  444.             else:
  445.                 raise TypeError('Value is not a string "%s".' % value)
  446.         isinstance(value, StringTypes)
  447.         dict.__setitem__(self, key, value)
  448.  
  449.     
  450.     def __delitem__(self, key):
  451.         dict.__delitem__(self, key)
  452.         if key in self.scalars:
  453.             self.scalars.remove(key)
  454.         else:
  455.             self.sections.remove(key)
  456.         del self.comments[key]
  457.         del self.inline_comments[key]
  458.  
  459.     
  460.     def get(self, key, default = None):
  461.         
  462.         try:
  463.             return self[key]
  464.         except KeyError:
  465.             return default
  466.  
  467.  
  468.     
  469.     def update(self, indict):
  470.         for entry in indict:
  471.             self[entry] = indict[entry]
  472.         
  473.  
  474.     
  475.     def pop(self, key, *args):
  476.         val = dict.pop(self, key, *args)
  477.         if key in self.scalars:
  478.             del self.comments[key]
  479.             del self.inline_comments[key]
  480.             self.scalars.remove(key)
  481.         elif key in self.sections:
  482.             del self.comments[key]
  483.             del self.inline_comments[key]
  484.             self.sections.remove(key)
  485.         
  486.         if self.main.interpolation and isinstance(val, StringTypes):
  487.             return self._interpolate(key, val)
  488.         return val
  489.  
  490.     
  491.     def popitem(self):
  492.         sequence = self.scalars + self.sections
  493.         if not sequence:
  494.             raise KeyError(": 'popitem(): dictionary is empty'")
  495.         sequence
  496.         key = sequence[0]
  497.         val = self[key]
  498.         del self[key]
  499.         return (key, val)
  500.  
  501.     
  502.     def clear(self):
  503.         dict.clear(self)
  504.         self.scalars = []
  505.         self.sections = []
  506.         self.comments = { }
  507.         self.inline_comments = { }
  508.         self.configspec = { }
  509.  
  510.     
  511.     def setdefault(self, key, default = None):
  512.         
  513.         try:
  514.             return self[key]
  515.         except KeyError:
  516.             self[key] = default
  517.             return self[key]
  518.  
  519.  
  520.     
  521.     def items(self):
  522.         return zip(self.scalars + self.sections, self.values())
  523.  
  524.     
  525.     def keys(self):
  526.         return self.scalars + self.sections
  527.  
  528.     
  529.     def values(self):
  530.         return [ self[key] for key in self.scalars + self.sections ]
  531.  
  532.     
  533.     def iteritems(self):
  534.         return iter(self.items())
  535.  
  536.     
  537.     def iterkeys(self):
  538.         return iter(self.scalars + self.sections)
  539.  
  540.     __iter__ = iterkeys
  541.     
  542.     def itervalues(self):
  543.         return iter(self.values())
  544.  
  545.     
  546.     def __repr__(self):
  547.         return [] % []([ '%s: %s' % (repr(key), repr(self[key])) for key in self.scalars + self.sections ])
  548.  
  549.     __str__ = __repr__
  550.     __str__.__doc__ = 'x.__str__() <==> str(x)'
  551.     
  552.     def dict(self):
  553.         newdict = { }
  554.         for entry in self:
  555.             this_entry = self[entry]
  556.             if isinstance(this_entry, Section):
  557.                 this_entry = this_entry.dict()
  558.             elif isinstance(this_entry, list):
  559.                 this_entry = list(this_entry)
  560.             elif isinstance(this_entry, tuple):
  561.                 this_entry = tuple(this_entry)
  562.             
  563.             newdict[entry] = this_entry
  564.         
  565.         return newdict
  566.  
  567.     
  568.     def merge(self, indict):
  569.         for key, val in indict.items():
  570.             if key in self and isinstance(self[key], dict) and isinstance(val, dict):
  571.                 self[key].merge(val)
  572.                 continue
  573.             self[key] = val
  574.         
  575.  
  576.     
  577.     def rename(self, oldkey, newkey):
  578.         if oldkey in self.scalars:
  579.             the_list = self.scalars
  580.         elif oldkey in self.sections:
  581.             the_list = self.sections
  582.         else:
  583.             raise KeyError('Key "%s" not found.' % oldkey)
  584.         pos = (oldkey in self.scalars).index(oldkey)
  585.         val = self[oldkey]
  586.         dict.__delitem__(self, oldkey)
  587.         dict.__setitem__(self, newkey, val)
  588.         the_list.remove(oldkey)
  589.         the_list.insert(pos, newkey)
  590.         comm = self.comments[oldkey]
  591.         inline_comment = self.inline_comments[oldkey]
  592.         del self.comments[oldkey]
  593.         del self.inline_comments[oldkey]
  594.         self.comments[newkey] = comm
  595.         self.inline_comments[newkey] = inline_comment
  596.  
  597.     
  598.     def walk(self, function, raise_errors = True, call_on_sections = False, **keywargs):
  599.         out = { }
  600.         for i in range(len(self.scalars)):
  601.             entry = self.scalars[i]
  602.             
  603.             try:
  604.                 val = function(self, entry, **keywargs)
  605.                 entry = self.scalars[i]
  606.                 out[entry] = val
  607.             continue
  608.             except Exception:
  609.                 if raise_errors:
  610.                     raise 
  611.                 raise_errors
  612.                 entry = self.scalars[i]
  613.                 out[entry] = False
  614.                 continue
  615.             
  616.  
  617.         
  618.         for i in range(len(self.sections)):
  619.             entry = self.sections[i]
  620.             if call_on_sections:
  621.                 
  622.                 try:
  623.                     function(self, entry, **keywargs)
  624.                 except Exception:
  625.                     None<EXCEPTION MATCH>Exception
  626.                     None<EXCEPTION MATCH>Exception
  627.                     if raise_errors:
  628.                         raise 
  629.                     raise_errors
  630.                     entry = self.sections[i]
  631.                     out[entry] = False
  632.                 except:
  633.                     None<EXCEPTION MATCH>Exception
  634.  
  635.                 entry = self.sections[i]
  636.             
  637.             out[entry] = self[entry].walk(function, raise_errors = raise_errors, call_on_sections = call_on_sections, **keywargs)
  638.         
  639.         return out
  640.  
  641.     
  642.     def decode(self, encoding):
  643.         warn('use of ``decode`` is deprecated.', DeprecationWarning)
  644.         
  645.         def decode(section, key, encoding = encoding, warn = True):
  646.             val = section[key]
  647.             if isinstance(val, (list, tuple)):
  648.                 newval = []
  649.                 for entry in val:
  650.                     newval.append(entry.decode(encoding))
  651.                 
  652.             elif isinstance(val, dict):
  653.                 newval = val
  654.             else:
  655.                 newval = val.decode(encoding)
  656.             newkey = key.decode(encoding)
  657.             section.rename(key, newkey)
  658.             section[newkey] = newval
  659.  
  660.         self.walk(decode, call_on_sections = True)
  661.  
  662.     
  663.     def encode(self, encoding):
  664.         warn('use of ``encode`` is deprecated.', DeprecationWarning)
  665.         
  666.         def encode(section, key, encoding = encoding):
  667.             val = section[key]
  668.             if isinstance(val, (list, tuple)):
  669.                 newval = []
  670.                 for entry in val:
  671.                     newval.append(entry.encode(encoding))
  672.                 
  673.             elif isinstance(val, dict):
  674.                 newval = val
  675.             else:
  676.                 newval = val.encode(encoding)
  677.             newkey = key.encode(encoding)
  678.             section.rename(key, newkey)
  679.             section[newkey] = newval
  680.  
  681.         self.walk(encode, call_on_sections = True)
  682.  
  683.     
  684.     def istrue(self, key):
  685.         warn('use of ``istrue`` is deprecated. Use ``as_bool`` method instead.', DeprecationWarning)
  686.         return self.as_bool(key)
  687.  
  688.     
  689.     def as_bool(self, key):
  690.         val = self[key]
  691.         if val == True:
  692.             return True
  693.         if val == False:
  694.             return False
  695.         
  696.         try:
  697.             if not isinstance(val, StringTypes):
  698.                 raise KeyError()
  699.             isinstance(val, StringTypes)
  700.             return self.main._bools[val.lower()]
  701.         except KeyError:
  702.             val == False
  703.             val == False
  704.             val == True
  705.             raise ValueError('Value "%s" is neither True nor False' % val)
  706.         except:
  707.             val == False
  708.  
  709.  
  710.     
  711.     def as_int(self, key):
  712.         return int(self[key])
  713.  
  714.     
  715.     def as_float(self, key):
  716.         return float(self[key])
  717.  
  718.     
  719.     def restore_default(self, key):
  720.         default = self.default_values[key]
  721.         dict.__setitem__(self, key, default)
  722.         if key not in self.defaults:
  723.             self.defaults.append(key)
  724.         
  725.         return default
  726.  
  727.     
  728.     def restore_defaults(self):
  729.         for key in self.default_values:
  730.             self.restore_default(key)
  731.         
  732.         for section in self.sections:
  733.             self[section].restore_defaults()
  734.         
  735.  
  736.  
  737.  
  738. class ConfigObj(Section):
  739.     _keyword = re.compile('^ # line start\n        (\\s*)                   # indentation\n        (                       # keyword\n            (?:".*?")|          # double quotes\n            (?:\'.*?\')|          # single quotes\n            (?:[^\'"=].*?)       # no quotes\n        )\n        \\s*=\\s*                 # divider\n        (.*)                    # value (including list values and comments)\n        $   # line end\n        ', re.VERBOSE)
  740.     _sectionmarker = re.compile('^\n        (\\s*)                     # 1: indentation\n        ((?:\\[\\s*)+)              # 2: section marker open\n        (                         # 3: section name open\n            (?:"\\s*\\S.*?\\s*")|    # at least one non-space with double quotes\n            (?:\'\\s*\\S.*?\\s*\')|    # at least one non-space with single quotes\n            (?:[^\'"\\s].*?)        # at least one non-space unquoted\n        )                         # section name close\n        ((?:\\s*\\])+)              # 4: section marker close\n        \\s*(\\#.*)?                # 5: optional comment\n        $', re.VERBOSE)
  741.     _valueexp = re.compile('^\n        (?:\n            (?:\n                (\n                    (?:\n                        (?:\n                            (?:".*?")|              # double quotes\n                            (?:\'.*?\')|              # single quotes\n                            (?:[^\'",\\#][^,\\#]*?)    # unquoted\n                        )\n                        \\s*,\\s*                     # comma\n                    )*      # match all list items ending in a comma (if any)\n                )\n                (\n                    (?:".*?")|                      # double quotes\n                    (?:\'.*?\')|                      # single quotes\n                    (?:[^\'",\\#\\s][^,]*?)|           # unquoted\n                    (?:(?<!,))                      # Empty value\n                )?          # last item in a list - or string value\n            )|\n            (,)             # alternatively a single comma - empty list\n        )\n        \\s*(\\#.*)?          # optional comment\n        $', re.VERBOSE)
  742.     _listvalueexp = re.compile('\n        (\n            (?:".*?")|          # double quotes\n            (?:\'.*?\')|          # single quotes\n            (?:[^\'",\\#].*?)       # unquoted\n        )\n        \\s*,\\s*                 # comma\n        ', re.VERBOSE)
  743.     _nolistvalue = re.compile('^\n        (\n            (?:".*?")|          # double quotes\n            (?:\'.*?\')|          # single quotes\n            (?:[^\'"\\#].*?)|     # unquoted\n            (?:)                # Empty value\n        )\n        \\s*(\\#.*)?              # optional comment\n        $', re.VERBOSE)
  744.     _single_line_single = re.compile("^'''(.*?)'''\\s*(#.*)?$")
  745.     _single_line_double = re.compile('^"""(.*?)"""\\s*(#.*)?$')
  746.     _multi_line_single = re.compile("^(.*?)'''\\s*(#.*)?$")
  747.     _multi_line_double = re.compile('^(.*?)"""\\s*(#.*)?$')
  748.     _triple_quote = {
  749.         "'''": (_single_line_single, _multi_line_single),
  750.         '"""': (_single_line_double, _multi_line_double) }
  751.     _bools = {
  752.         'yes': True,
  753.         'no': False,
  754.         'on': True,
  755.         'off': False,
  756.         '1': True,
  757.         '0': False,
  758.         'true': True,
  759.         'false': False }
  760.     
  761.     def __init__(self, infile = None, options = None, **kwargs):
  762.         Section.__init__(self, self, 0, self)
  763.         if infile is None:
  764.             infile = []
  765.         
  766.         if options is None:
  767.             options = { }
  768.         else:
  769.             options = dict(options)
  770.         options.update(kwargs)
  771.         defaults = OPTION_DEFAULTS.copy()
  772.         for entry in options:
  773.             if entry not in defaults:
  774.                 raise TypeError('Unrecognised option "%s".' % entry)
  775.             entry not in defaults
  776.         
  777.         defaults.update(options)
  778.         self._initialise(defaults)
  779.         configspec = defaults['configspec']
  780.         self._original_configspec = configspec
  781.         self._load(infile, configspec)
  782.  
  783.     
  784.     def _load(self, infile, configspec):
  785.         if isinstance(infile, StringTypes):
  786.             self.filename = infile
  787.             if os.path.isfile(infile):
  788.                 h = open(infile, 'rb')
  789.                 if not h.read():
  790.                     pass
  791.                 infile = []
  792.                 h.close()
  793.             elif self.file_error:
  794.                 raise IOError('Config file not found: "%s".' % self.filename)
  795.             elif self.create_empty:
  796.                 h = open(infile, 'w')
  797.                 h.write('')
  798.                 h.close()
  799.             
  800.             infile = []
  801.         elif isinstance(infile, (list, tuple)):
  802.             infile = list(infile)
  803.         elif isinstance(infile, dict):
  804.             if isinstance(infile, ConfigObj):
  805.                 infile = infile.dict()
  806.             
  807.             for entry in infile:
  808.                 self[entry] = infile[entry]
  809.             
  810.             del self._errors
  811.             if configspec is not None:
  812.                 self._handle_configspec(configspec)
  813.             else:
  814.                 self.configspec = None
  815.             return None
  816.         if hasattr(infile, 'read'):
  817.             if not infile.read():
  818.                 pass
  819.             infile = []
  820.         else:
  821.             raise TypeError('infile must be a filename, file like object, or list of lines.')
  822.         self._parse(infile)
  823.         if self._errors:
  824.             info = 'at line %s.' % self._errors[0].line_number
  825.             if len(self._errors) > 1:
  826.                 msg = 'Parsing failed with several errors.\nFirst error %s' % info
  827.                 error = ConfigObjError(msg)
  828.             else:
  829.                 error = self._errors[0]
  830.             error.errors = self._errors
  831.             error.config = self
  832.             raise error
  833.         self._errors
  834.         del self._errors
  835.         if configspec is None:
  836.             self.configspec = None
  837.         else:
  838.             self._handle_configspec(configspec)
  839.  
  840.     
  841.     def _initialise(self, options = None):
  842.         if options is None:
  843.             options = OPTION_DEFAULTS
  844.         
  845.         self.filename = None
  846.         self._errors = []
  847.         self.raise_errors = options['raise_errors']
  848.         self.interpolation = options['interpolation']
  849.         self.list_values = options['list_values']
  850.         self.create_empty = options['create_empty']
  851.         self.file_error = options['file_error']
  852.         self.stringify = options['stringify']
  853.         self.indent_type = options['indent_type']
  854.         self.encoding = options['encoding']
  855.         self.default_encoding = options['default_encoding']
  856.         self.BOM = False
  857.         self.newlines = None
  858.         self.write_empty_values = options['write_empty_values']
  859.         self.unrepr = options['unrepr']
  860.         self.initial_comment = []
  861.         self.final_comment = []
  862.         self.configspec = { }
  863.         Section._initialise(self)
  864.  
  865.     
  866.     def __repr__(self):
  867.         return [] % []([ '%s: %s' % (repr(key), repr(self[key])) for key in self.scalars + self.sections ])
  868.  
  869.     
  870.     def _handle_bom(self, infile):
  871.         if self.encoding is not None and self.encoding.lower() not in BOM_LIST:
  872.             return self._decode(infile, self.encoding)
  873.         if isinstance(infile, (list, tuple)):
  874.             line = infile[0]
  875.         else:
  876.             line = infile
  877.         if self.encoding is not None:
  878.             enc = BOM_LIST[self.encoding.lower()]
  879.             if enc == 'utf_16':
  880.                 for encoding, final_encoding in BOMS.items():
  881.                     if not final_encoding:
  882.                         continue
  883.                     
  884.                     if infile.startswith(BOM):
  885.                         return self._decode(infile, encoding)
  886.                 
  887.                 return self._decode(infile, self.encoding)
  888.             BOM = BOM_SET[enc]
  889.             if not line.startswith(BOM):
  890.                 return self._decode(infile, self.encoding)
  891.             newline = line[len(BOM):]
  892.             self.BOM = True
  893.             return self._decode(infile, self.encoding)
  894.         for encoding, final_encoding in BOMS.items():
  895.             if not line.startswith(BOM):
  896.                 continue
  897.                 continue
  898.             self.encoding = final_encoding
  899.             if not final_encoding:
  900.                 self.BOM = True
  901.                 newline = line[len(BOM):]
  902.                 if isinstance(infile, (list, tuple)):
  903.                     infile[0] = newline
  904.                 else:
  905.                     infile = newline
  906.                 if isinstance(infile, StringTypes):
  907.                     return infile.splitlines(True)
  908.                 return infile
  909.             final_encoding
  910.             return self._decode(infile, encoding)
  911.         
  912.         if isinstance(infile, StringTypes):
  913.             return infile.splitlines(True)
  914.         return infile
  915.  
  916.     
  917.     def _a_to_u(self, aString):
  918.         if self.encoding:
  919.             return aString.decode('ascii')
  920.         return aString
  921.  
  922.     
  923.     def _decode(self, infile, encoding):
  924.         if isinstance(infile, StringTypes):
  925.             return infile.decode(encoding).splitlines(True)
  926.         for i, line in enumerate(infile):
  927.             if not isinstance(line, unicode):
  928.                 infile[i] = line.decode(encoding)
  929.                 continue
  930.             isinstance(infile, StringTypes)
  931.         
  932.         return infile
  933.  
  934.     
  935.     def _decode_element(self, line):
  936.         if not self.encoding:
  937.             return line
  938.         if isinstance(line, str) and self.default_encoding:
  939.             return line.decode(self.default_encoding)
  940.         return line
  941.  
  942.     
  943.     def _str(self, value):
  944.         if not isinstance(value, StringTypes):
  945.             return str(value)
  946.         return value
  947.  
  948.     
  949.     def _parse(self, infile):
  950.         temp_list_values = self.list_values
  951.         if self.unrepr:
  952.             self.list_values = False
  953.         
  954.         comment_list = []
  955.         done_start = False
  956.         this_section = self
  957.         maxline = len(infile) - 1
  958.         cur_index = -1
  959.         reset_comment = False
  960.         while cur_index < maxline:
  961.             if reset_comment:
  962.                 comment_list = []
  963.             
  964.             cur_index += 1
  965.             line = infile[cur_index]
  966.             sline = line.strip()
  967.             if not sline or sline.startswith('#'):
  968.                 reset_comment = False
  969.                 comment_list.append(line)
  970.                 continue
  971.             
  972.             if not done_start:
  973.                 self.initial_comment = comment_list
  974.                 comment_list = []
  975.                 done_start = True
  976.             
  977.             reset_comment = True
  978.             mat = self._sectionmarker.match(line)
  979.             if mat is not None:
  980.                 (indent, sect_open, sect_name, sect_close, comment) = mat.groups()
  981.                 if indent and self.indent_type is None:
  982.                     self.indent_type = indent
  983.                 
  984.                 cur_depth = sect_open.count('[')
  985.                 if cur_depth != sect_close.count(']'):
  986.                     self._handle_error('Cannot compute the section depth at line %s.', NestingError, infile, cur_index)
  987.                     continue
  988.                 
  989.                 if cur_depth < this_section.depth:
  990.                     
  991.                     try:
  992.                         parent = self._match_depth(this_section, cur_depth).parent
  993.                     except SyntaxError:
  994.                         self._handle_error('Cannot compute nesting level at line %s.', NestingError, infile, cur_index)
  995.                         continue
  996.                     except:
  997.                         None<EXCEPTION MATCH>SyntaxError
  998.                     
  999.  
  1000.                 None<EXCEPTION MATCH>SyntaxError
  1001.                 if cur_depth == this_section.depth:
  1002.                     parent = this_section.parent
  1003.                 elif cur_depth == this_section.depth + 1:
  1004.                     parent = this_section
  1005.                 else:
  1006.                     self._handle_error('Section too nested at line %s.', NestingError, infile, cur_index)
  1007.                 sect_name = self._unquote(sect_name)
  1008.                 if parent.has_key(sect_name):
  1009.                     self._handle_error('Duplicate section name at line %s.', DuplicateError, infile, cur_index)
  1010.                     continue
  1011.                 
  1012.                 this_section = Section(parent, cur_depth, self, name = sect_name)
  1013.                 parent[sect_name] = this_section
  1014.                 parent.inline_comments[sect_name] = comment
  1015.                 parent.comments[sect_name] = comment_list
  1016.                 continue
  1017.             
  1018.             mat = self._keyword.match(line)
  1019.             if mat is None:
  1020.                 self._handle_error('Invalid line at line "%s".', ParseError, infile, cur_index)
  1021.                 continue
  1022.             (indent, key, value) = mat.groups()
  1023.             if indent and self.indent_type is None:
  1024.                 self.indent_type = indent
  1025.             
  1026.             if value[:3] in ('"""', "'''"):
  1027.                 
  1028.                 try:
  1029.                     (value, comment, cur_index) = self._multiline(value, infile, cur_index, maxline)
  1030.                 except SyntaxError:
  1031.                     self._handle_error('Parse error in value at line %s.', ParseError, infile, cur_index)
  1032.                     continue
  1033.  
  1034.                 if self.unrepr:
  1035.                     comment = ''
  1036.                     
  1037.                     try:
  1038.                         value = unrepr(value)
  1039.                     except Exception:
  1040.                         e = None
  1041.                         if type(e) == UnknownType:
  1042.                             msg = 'Unknown name or type in value at line %s.'
  1043.                         else:
  1044.                             msg = 'Parse error in value at line %s.'
  1045.                         self._handle_error(msg, UnreprError, infile, cur_index)
  1046.                         continue
  1047.                     except:
  1048.                         None<EXCEPTION MATCH>Exception
  1049.                     
  1050.  
  1051.                 None<EXCEPTION MATCH>Exception
  1052.             elif self.unrepr:
  1053.                 comment = ''
  1054.                 
  1055.                 try:
  1056.                     value = unrepr(value)
  1057.                 except Exception:
  1058.                     e = None
  1059.                     if isinstance(e, UnknownType):
  1060.                         msg = 'Unknown name or type in value at line %s.'
  1061.                     else:
  1062.                         msg = 'Parse error in value at line %s.'
  1063.                     self._handle_error(msg, UnreprError, infile, cur_index)
  1064.                     continue
  1065.                 except:
  1066.                     None<EXCEPTION MATCH>Exception
  1067.                 
  1068.  
  1069.             None<EXCEPTION MATCH>Exception
  1070.             
  1071.             try:
  1072.                 (value, comment) = self._handle_value(value)
  1073.             except SyntaxError:
  1074.                 self._handle_error('Parse error in value at line %s.', ParseError, infile, cur_index)
  1075.                 continue
  1076.  
  1077.             key = self._unquote(key)
  1078.             if this_section.has_key(key):
  1079.                 self._handle_error('Duplicate keyword name at line %s.', DuplicateError, infile, cur_index)
  1080.                 continue
  1081.             
  1082.             this_section.__setitem__(key, value, unrepr = True)
  1083.             this_section.inline_comments[key] = comment
  1084.             this_section.comments[key] = comment_list
  1085.             continue
  1086.         if self.indent_type is None:
  1087.             self.indent_type = ''
  1088.         
  1089.         if not self and not (self.initial_comment):
  1090.             self.initial_comment = comment_list
  1091.         elif not reset_comment:
  1092.             self.final_comment = comment_list
  1093.         
  1094.         self.list_values = temp_list_values
  1095.  
  1096.     
  1097.     def _match_depth(self, sect, depth):
  1098.         while depth < sect.depth:
  1099.             if sect is sect.parent:
  1100.                 raise SyntaxError()
  1101.             sect is sect.parent
  1102.             sect = sect.parent
  1103.         if sect.depth == depth:
  1104.             return sect
  1105.         raise SyntaxError()
  1106.  
  1107.     
  1108.     def _handle_error(self, text, ErrorClass, infile, cur_index):
  1109.         line = infile[cur_index]
  1110.         cur_index += 1
  1111.         message = text % cur_index
  1112.         error = ErrorClass(message, cur_index, line)
  1113.         if self.raise_errors:
  1114.             raise error
  1115.         self.raise_errors
  1116.         self._errors.append(error)
  1117.  
  1118.     
  1119.     def _unquote(self, value):
  1120.         if value[0] == value[-1] and value[0] in ('"', "'"):
  1121.             value = value[1:-1]
  1122.         
  1123.         return value
  1124.  
  1125.     
  1126.     def _quote(self, value, multiline = True):
  1127.         if multiline and self.write_empty_values and value == '':
  1128.             return ''
  1129.         if multiline and isinstance(value, (list, tuple)):
  1130.             if not value:
  1131.                 return ','
  1132.             if len(value) == 1:
  1133.                 return self._quote(value[0], multiline = False) + ','
  1134.             return []([ self._quote(val, multiline = False) for val in value ])
  1135.         if not isinstance(value, StringTypes):
  1136.             if self.stringify:
  1137.                 value = str(value)
  1138.             else:
  1139.                 raise TypeError('Value "%s" is not a string.' % value)
  1140.         self.stringify
  1141.         if not value:
  1142.             return '""'
  1143.         if not (self.list_values) and '\n' not in value:
  1144.             pass
  1145.         no_lists_no_quotes = '#' not in value
  1146.         if multiline:
  1147.             if not "'" in value or '"' in value:
  1148.                 pass
  1149.         need_triple = '\n' in value
  1150.         if multiline and not need_triple and "'" in value and '"' in value:
  1151.             pass
  1152.         hash_triple_quote = '#' in value
  1153.         if no_lists_no_quotes or not need_triple:
  1154.             pass
  1155.         check_for_single = not hash_triple_quote
  1156.         if quot == noquot and '#' in value and self.list_values:
  1157.             quot = self._get_single_quote(value)
  1158.         
  1159.         return quot % value
  1160.  
  1161.     
  1162.     def _get_single_quote(self, value):
  1163.         if "'" in value and '"' in value:
  1164.             raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
  1165.         '"' in value
  1166.         if '"' in value:
  1167.             quot = squot
  1168.         else:
  1169.             quot = dquot
  1170.         return quot
  1171.  
  1172.     
  1173.     def _get_triple_quote(self, value):
  1174.         if value.find('"""') != -1 and value.find("'''") != -1:
  1175.             raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
  1176.         value.find("'''") != -1
  1177.         if value.find('"""') == -1:
  1178.             quot = tdquot
  1179.         else:
  1180.             quot = tsquot
  1181.         return quot
  1182.  
  1183.     
  1184.     def _handle_value(self, value):
  1185.         if not self.list_values:
  1186.             mat = self._nolistvalue.match(value)
  1187.             if mat is None:
  1188.                 raise SyntaxError()
  1189.             mat is None
  1190.             return mat.groups()
  1191.         mat = self._valueexp.match(value)
  1192.         if mat is None:
  1193.             raise SyntaxError()
  1194.         mat is None
  1195.         (list_values, single, empty_list, comment) = mat.groups()
  1196.         if list_values == '' and single is None:
  1197.             raise SyntaxError()
  1198.         single is None
  1199.         if empty_list is not None:
  1200.             return ([], comment)
  1201.         if list_values == '':
  1202.             return (single, comment)
  1203.         the_list = self._listvalueexp.findall(list_values)
  1204.         the_list = [ self._unquote(val) for val in the_list ]
  1205.         return (the_list, comment)
  1206.  
  1207.     
  1208.     def _multiline(self, value, infile, cur_index, maxline):
  1209.         quot = value[:3]
  1210.         newvalue = value[3:]
  1211.         single_line = self._triple_quote[quot][0]
  1212.         multi_line = self._triple_quote[quot][1]
  1213.         mat = single_line.match(value)
  1214.         if mat is not None:
  1215.             retval = list(mat.groups())
  1216.             retval.append(cur_index)
  1217.             return retval
  1218.         if newvalue.find(quot) != -1:
  1219.             raise SyntaxError()
  1220.         newvalue.find(quot) != -1
  1221.         while cur_index < maxline:
  1222.             cur_index += 1
  1223.             newvalue += '\n'
  1224.             line = infile[cur_index]
  1225.             if line.find(quot) == -1:
  1226.                 newvalue += line
  1227.                 continue
  1228.             mat is not None
  1229.             break
  1230.         raise SyntaxError()
  1231.         mat = multi_line.match(line)
  1232.         if mat is None:
  1233.             raise SyntaxError()
  1234.         mat is None
  1235.         (value, comment) = mat.groups()
  1236.         return (newvalue + value, comment, cur_index)
  1237.  
  1238.     
  1239.     def _handle_configspec(self, configspec):
  1240.         if not isinstance(configspec, ConfigObj):
  1241.             
  1242.             try:
  1243.                 configspec = ConfigObj(configspec, raise_errors = True, file_error = True, list_values = False)
  1244.             except ConfigObjError:
  1245.                 e = None
  1246.                 raise ConfigspecError('Parsing configspec failed: %s' % e)
  1247.             except IOError:
  1248.                 e = None
  1249.                 raise IOError('Reading configspec failed: %s' % e)
  1250.             except:
  1251.                 None<EXCEPTION MATCH>ConfigObjError
  1252.             
  1253.  
  1254.         None<EXCEPTION MATCH>ConfigObjError
  1255.         self._set_configspec_value(configspec, self)
  1256.  
  1257.     
  1258.     def _set_configspec_value(self, configspec, section):
  1259.         if '__many__' in configspec.sections:
  1260.             section.configspec['__many__'] = configspec['__many__']
  1261.             if len(configspec.sections) > 1:
  1262.                 raise RepeatSectionError()
  1263.             len(configspec.sections) > 1
  1264.         
  1265.         if hasattr(configspec, 'initial_comment'):
  1266.             section._configspec_initial_comment = configspec.initial_comment
  1267.             section._configspec_final_comment = configspec.final_comment
  1268.             section._configspec_encoding = configspec.encoding
  1269.             section._configspec_BOM = configspec.BOM
  1270.             section._configspec_newlines = configspec.newlines
  1271.             section._configspec_indent_type = configspec.indent_type
  1272.         
  1273.         for entry in configspec.scalars:
  1274.             section._configspec_comments[entry] = configspec.comments[entry]
  1275.             section._configspec_inline_comments[entry] = configspec.inline_comments[entry]
  1276.             section.configspec[entry] = configspec[entry]
  1277.             section._order.append(entry)
  1278.         
  1279.         for entry in configspec.sections:
  1280.             if entry == '__many__':
  1281.                 continue
  1282.             
  1283.             section._cs_section_comments[entry] = configspec.comments[entry]
  1284.             section._cs_section_inline_comments[entry] = configspec.inline_comments[entry]
  1285.             if not section.has_key(entry):
  1286.                 section[entry] = { }
  1287.             
  1288.             self._set_configspec_value(configspec[entry], section[entry])
  1289.         
  1290.  
  1291.     
  1292.     def _handle_repeat(self, section, configspec):
  1293.         
  1294.         try:
  1295.             section_keys = configspec.sections
  1296.             scalar_keys = configspec.scalars
  1297.         except AttributeError:
  1298.             section_keys = _[1]
  1299.             scalar_keys = _[2]
  1300.         except:
  1301.             []
  1302.  
  1303.         if '__many__' in section_keys and len(section_keys) > 1:
  1304.             raise RepeatSectionError()
  1305.         len(section_keys) > 1
  1306.         scalars = { }
  1307.         sections = { }
  1308.         for entry in scalar_keys:
  1309.             val = configspec[entry]
  1310.             scalars[entry] = val
  1311.         
  1312.         for entry in section_keys:
  1313.             val = configspec[entry]
  1314.             sections[entry] = val
  1315.         
  1316.         section.configspec = scalars
  1317.         for entry in sections:
  1318.             self._handle_repeat(section[entry], sections[entry])
  1319.         
  1320.  
  1321.     
  1322.     def _write_line(self, indent_string, entry, this_entry, comment):
  1323.         if not self.unrepr:
  1324.             val = self._decode_element(self._quote(this_entry))
  1325.         else:
  1326.             val = repr(this_entry)
  1327.         return '%s%s%s%s%s' % (indent_string, self._decode_element(self._quote(entry, multiline = False)), self._a_to_u(' = '), val, self._decode_element(comment))
  1328.  
  1329.     
  1330.     def _write_marker(self, indent_string, depth, entry, comment):
  1331.         return '%s%s%s%s%s' % (indent_string, self._a_to_u('[' * depth), self._quote(self._decode_element(entry), multiline = False), self._a_to_u(']' * depth), self._decode_element(comment))
  1332.  
  1333.     
  1334.     def _handle_comment(self, comment):
  1335.         if not comment:
  1336.             return ''
  1337.         start = self.indent_type
  1338.         if not comment.startswith('#'):
  1339.             start += self._a_to_u(' # ')
  1340.         
  1341.         return start + comment
  1342.  
  1343.     
  1344.     def write(self, outfile = None, section = None):
  1345.         if self.indent_type is None:
  1346.             self.indent_type = DEFAULT_INDENT_TYPE
  1347.         
  1348.         out = []
  1349.         cs = self._a_to_u('#')
  1350.         csp = self._a_to_u('# ')
  1351.         if section is None:
  1352.             int_val = self.interpolation
  1353.             self.interpolation = False
  1354.             section = self
  1355.             for line in self.initial_comment:
  1356.                 line = self._decode_element(line)
  1357.                 stripped_line = line.strip()
  1358.                 if stripped_line and not stripped_line.startswith(cs):
  1359.                     line = csp + line
  1360.                 
  1361.                 out.append(line)
  1362.             
  1363.         
  1364.         indent_string = self.indent_type * section.depth
  1365.         for entry in section.scalars + section.sections:
  1366.             if entry in section.defaults:
  1367.                 continue
  1368.             
  1369.             for comment_line in section.comments[entry]:
  1370.                 comment_line = self._decode_element(comment_line.lstrip())
  1371.                 if comment_line and not comment_line.startswith(cs):
  1372.                     comment_line = csp + comment_line
  1373.                 
  1374.                 out.append(indent_string + comment_line)
  1375.             
  1376.             this_entry = section[entry]
  1377.             comment = self._handle_comment(section.inline_comments[entry])
  1378.             if isinstance(this_entry, dict):
  1379.                 out.append(self._write_marker(indent_string, this_entry.depth, entry, comment))
  1380.                 out.extend(self.write(section = this_entry))
  1381.                 continue
  1382.             out.append(self._write_line(indent_string, entry, this_entry, comment))
  1383.         
  1384.         if section is self:
  1385.             for line in self.final_comment:
  1386.                 line = self._decode_element(line)
  1387.                 stripped_line = line.strip()
  1388.                 if stripped_line and not stripped_line.startswith(cs):
  1389.                     line = csp + line
  1390.                 
  1391.                 out.append(line)
  1392.             
  1393.             self.interpolation = int_val
  1394.         
  1395.         if section is not self:
  1396.             return out
  1397.         if self.filename is None and outfile is None:
  1398.             if self.BOM:
  1399.                 pass
  1400.             return out
  1401.         if not self.newlines:
  1402.             pass
  1403.         newline = os.linesep
  1404.         output = self._a_to_u(newline).join(out)
  1405.         if self.BOM:
  1406.             if self.encoding is None or match_utf8(self.encoding):
  1407.                 output = BOM_UTF8 + output
  1408.             
  1409.         if not output.endswith(newline):
  1410.             output += newline
  1411.         
  1412.         if outfile is not None:
  1413.             outfile.write(output)
  1414.         else:
  1415.             h = open(self.filename, 'wb')
  1416.             h.write(output)
  1417.             h.close()
  1418.  
  1419.     
  1420.     def validate(self, validator, preserve_errors = False, copy = False, section = None):
  1421.         if section is None:
  1422.             if self.configspec is None:
  1423.                 raise ValueError('No configspec supplied.')
  1424.             self.configspec is None
  1425.             if preserve_errors:
  1426.                 VdtMissingValue = VdtMissingValue
  1427.                 import validate
  1428.                 self._vdtMissingValue = VdtMissingValue
  1429.             
  1430.             section = self
  1431.         
  1432.         spec_section = section.configspec
  1433.         if copy and hasattr(section, '_configspec_initial_comment'):
  1434.             section.initial_comment = section._configspec_initial_comment
  1435.             section.final_comment = section._configspec_final_comment
  1436.             section.encoding = section._configspec_encoding
  1437.             section.BOM = section._configspec_BOM
  1438.             section.newlines = section._configspec_newlines
  1439.             section.indent_type = section._configspec_indent_type
  1440.         
  1441.         if '__many__' in section.configspec:
  1442.             many = spec_section['__many__']
  1443.             for entry in section.sections:
  1444.                 self._handle_repeat(section[entry], many)
  1445.             
  1446.         
  1447.         out = { }
  1448.         ret_true = True
  1449.         ret_false = True
  1450.         order = _[1]
  1451.         [] += _[2]
  1452.         for entry in order:
  1453.             
  1454.             try:
  1455.                 check = validator.check(spec_section[entry], val, missing = missing)
  1456.             except validator.baseErrorClass:
  1457.                 None if entry not in section.scalars or entry in section.defaults else []
  1458.                 e = None if entry not in section.scalars or entry in section.defaults else []
  1459.                 if not preserve_errors or isinstance(e, self._vdtMissingValue):
  1460.                     out[entry] = False
  1461.                 else:
  1462.                     out[entry] = e
  1463.                     ret_false = False
  1464.                 ret_true = False
  1465.                 continue
  1466.  
  1467.             
  1468.             try:
  1469.                 section.default_values.pop(entry, None)
  1470.             except AttributeError:
  1471.                 None if entry not in section.scalars or entry in section.defaults else []
  1472.                 None if entry not in section.scalars or entry in section.defaults else []
  1473.                 
  1474.                 try:
  1475.                     del section.default_values[entry]
  1476.                 except KeyError:
  1477.                     pass
  1478.                 except:
  1479.                     None<EXCEPTION MATCH>KeyError
  1480.                 
  1481.  
  1482.                 None<EXCEPTION MATCH>KeyError
  1483.  
  1484.             if hasattr(validator, 'get_default_value'):
  1485.                 
  1486.                 try:
  1487.                     section.default_values[entry] = validator.get_default_value(spec_section[entry])
  1488.                 except KeyError:
  1489.                     None if entry not in section.scalars or entry in section.defaults else []
  1490.                     None if entry not in section.scalars or entry in section.defaults else []
  1491.                 except:
  1492.                     None if entry not in section.scalars or entry in section.defaults else []<EXCEPTION MATCH>KeyError
  1493.                 
  1494.  
  1495.             None if entry not in section.scalars or entry in section.defaults else []
  1496.             ret_false = False
  1497.             out[entry] = True
  1498.             if self.stringify or missing:
  1499.                 if not self.stringify:
  1500.                     if isinstance(check, (list, tuple)):
  1501.                         check = [ self._str(item) for item in check ]
  1502.                     elif missing and check is None:
  1503.                         check = ''
  1504.                     else:
  1505.                         check = self._str(check)
  1506.                 
  1507.                 if check != val or missing:
  1508.                     section[entry] = check
  1509.                 
  1510.             
  1511.             if not copy and missing and entry not in section.defaults:
  1512.                 section.defaults.append(entry)
  1513.                 continue
  1514.         
  1515.         for entry in section.sections:
  1516.             if section is self and entry == 'DEFAULT':
  1517.                 continue
  1518.             
  1519.             if copy:
  1520.                 section.comments[entry] = section._cs_section_comments[entry]
  1521.                 section.inline_comments[entry] = section._cs_section_inline_comments[entry]
  1522.             
  1523.             check = self.validate(validator, preserve_errors = preserve_errors, copy = copy, section = section[entry])
  1524.             out[entry] = check
  1525.             if check == False:
  1526.                 ret_true = False
  1527.                 continue
  1528.             if check == True:
  1529.                 ret_false = False
  1530.                 continue
  1531.             ret_true = False
  1532.             ret_false = False
  1533.         
  1534.         if ret_true:
  1535.             return True
  1536.         if ret_false:
  1537.             return False
  1538.         return out
  1539.  
  1540.     
  1541.     def reset(self):
  1542.         self.clear()
  1543.         self._initialise()
  1544.         self.configspec = None
  1545.         self._original_configspec = None
  1546.  
  1547.     
  1548.     def reload(self):
  1549.         if not isinstance(self.filename, StringTypes):
  1550.             raise ReloadError()
  1551.         isinstance(self.filename, StringTypes)
  1552.         filename = self.filename
  1553.         current_options = { }
  1554.         for entry in OPTION_DEFAULTS:
  1555.             if entry == 'configspec':
  1556.                 continue
  1557.             
  1558.             current_options[entry] = getattr(self, entry)
  1559.         
  1560.         configspec = self._original_configspec
  1561.         current_options['configspec'] = configspec
  1562.         self.clear()
  1563.         self._initialise(current_options)
  1564.         self._load(filename, configspec)
  1565.  
  1566.  
  1567.  
  1568. class SimpleVal(object):
  1569.     
  1570.     def __init__(self):
  1571.         self.baseErrorClass = ConfigObjError
  1572.  
  1573.     
  1574.     def check(self, check, member, missing = False):
  1575.         if missing:
  1576.             raise self.baseErrorClass()
  1577.         missing
  1578.         return member
  1579.  
  1580.  
  1581.  
  1582. def flatten_errors(cfg, res, levels = None, results = None):
  1583.     if levels is None:
  1584.         levels = []
  1585.         results = []
  1586.     
  1587.     if res is True:
  1588.         return results
  1589.     if res is False:
  1590.         results.append((levels[:], None, False))
  1591.         if levels:
  1592.             levels.pop()
  1593.         
  1594.         return results
  1595.     for key, val in res.items():
  1596.         if isinstance(cfg.get(key), dict):
  1597.             levels.append(key)
  1598.             flatten_errors(cfg[key], val, levels, results)
  1599.             continue
  1600.         
  1601.         results.append((levels[:], key, val))
  1602.     
  1603.     if levels:
  1604.         levels.pop()
  1605.     
  1606.     return results
  1607.  
  1608.