~bzr-pqm/bzr/bzr.dev

1185.12.49 by Aaron Bentley
Switched to ConfigObj
1
# configobj.py
2
# A config file reader/writer that supports nested sections in config files.
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
3
# Copyright (C) 2005-2009 Michael Foord, Nicola Larosa
1185.12.49 by Aaron Bentley
Switched to ConfigObj
4
# E-mail: fuzzyman AT voidspace DOT org DOT uk
5
#         nico AT tekNico DOT net
6
7
# ConfigObj 4
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
8
# http://www.voidspace.org.uk/python/configobj.html
1185.12.49 by Aaron Bentley
Switched to ConfigObj
9
10
# Released subject to the BSD License
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
11
# Please see http://www.voidspace.org.uk/python/license.shtml
1185.12.49 by Aaron Bentley
Switched to ConfigObj
12
13
# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
14
# For information about bugfixes, updates and support, please join the
15
# ConfigObj mailing list:
16
# http://lists.sourceforge.net/lists/listinfo/configobj-develop
17
# Comments, suggestions and bug reports welcome.
18
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
19
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
20
from __future__ import generators
21
1185.12.49 by Aaron Bentley
Switched to ConfigObj
22
import sys
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
23
import os
24
import re
1185.12.49 by Aaron Bentley
Switched to ConfigObj
25
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
26
compiler = None
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
27
# Bzr modification: Disabled import of 'compiler' module
28
# bzr doesn't use the 'unrepr' feature of configobj, so importing compiler just
29
# wastes several milliseconds on every single bzr invocation.
30
#   -- Andrew Bennetts, 2008-10-14
31
#try:
32
#    import compiler
33
#except ImportError:
34
#    # for IronPython
35
#    pass
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
36
37
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
38
try:
39
    from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
40
except ImportError:
41
    # Python 2.2 does not have these
42
    # UTF-8
43
    BOM_UTF8 = '\xef\xbb\xbf'
44
    # UTF-16, little endian
45
    BOM_UTF16_LE = '\xff\xfe'
46
    # UTF-16, big endian
47
    BOM_UTF16_BE = '\xfe\xff'
48
    if sys.byteorder == 'little':
49
        # UTF-16, native endianness
50
        BOM_UTF16 = BOM_UTF16_LE
51
    else:
52
        # UTF-16, native endianness
53
        BOM_UTF16 = BOM_UTF16_BE
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
54
55
# A dictionary mapping BOM to
56
# the encoding to decode with, and what to set the
57
# encoding attribute to.
58
BOMS = {
59
    BOM_UTF8: ('utf_8', None),
60
    BOM_UTF16_BE: ('utf16_be', 'utf_16'),
61
    BOM_UTF16_LE: ('utf16_le', 'utf_16'),
62
    BOM_UTF16: ('utf_16', 'utf_16'),
63
    }
64
# All legal variants of the BOM codecs.
65
# TODO: the list of aliases is not meant to be exhaustive, is there a
66
#   better way ?
67
BOM_LIST = {
68
    'utf_16': 'utf_16',
69
    'u16': 'utf_16',
70
    'utf16': 'utf_16',
71
    'utf-16': 'utf_16',
72
    'utf16_be': 'utf16_be',
73
    'utf_16_be': 'utf16_be',
74
    'utf-16be': 'utf16_be',
75
    'utf16_le': 'utf16_le',
76
    'utf_16_le': 'utf16_le',
77
    'utf-16le': 'utf16_le',
78
    'utf_8': 'utf_8',
79
    'u8': 'utf_8',
80
    'utf': 'utf_8',
81
    'utf8': 'utf_8',
82
    'utf-8': 'utf_8',
83
    }
84
85
# Map of encodings to the BOM to write.
86
BOM_SET = {
87
    'utf_8': BOM_UTF8,
88
    'utf_16': BOM_UTF16,
89
    'utf16_be': BOM_UTF16_BE,
90
    'utf16_le': BOM_UTF16_LE,
91
    None: BOM_UTF8
92
    }
93
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
94
95
def match_utf8(encoding):
96
    return BOM_LIST.get(encoding.lower()) == 'utf_8'
97
98
99
# Quote strings used for writing values
100
squot = "'%s'"
101
dquot = '"%s"'
102
noquot = "%s"
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
103
wspace_plus = ' \r\n\v\t\'"'
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
104
tsquot = '"""%s"""'
105
tdquot = "'''%s'''"
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
106
107
try:
108
    enumerate
109
except NameError:
110
    def enumerate(obj):
111
        """enumerate for Python 2.2."""
112
        i = -1
113
        for item in obj:
114
            i += 1
115
            yield i, item
116
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
117
# Sentinel for use in getattr calls to replace hasattr
118
MISSING = object()
119
120
__version__ = '4.6.0'
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
121
122
__revision__ = '$Id: configobj.py 156 2006-01-31 14:57:08Z fuzzyman $'
1185.12.49 by Aaron Bentley
Switched to ConfigObj
123
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
124
__docformat__ = "restructuredtext en"
1185.12.49 by Aaron Bentley
Switched to ConfigObj
125
126
__all__ = (
127
    '__version__',
128
    'DEFAULT_INDENT_TYPE',
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
129
    'DEFAULT_INTERPOLATION',
1185.12.49 by Aaron Bentley
Switched to ConfigObj
130
    'ConfigObjError',
131
    'NestingError',
132
    'ParseError',
133
    'DuplicateError',
134
    'ConfigspecError',
135
    'ConfigObj',
136
    'SimpleVal',
137
    'InterpolationError',
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
138
    'InterpolationLoopError',
1185.12.49 by Aaron Bentley
Switched to ConfigObj
139
    'MissingInterpolationOption',
140
    'RepeatSectionError',
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
141
    'ReloadError',
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
142
    'UnreprError',
143
    'UnknownType',
1185.12.49 by Aaron Bentley
Switched to ConfigObj
144
    '__docformat__',
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
145
    'flatten_errors',
1185.12.49 by Aaron Bentley
Switched to ConfigObj
146
)
147
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
148
DEFAULT_INTERPOLATION = 'configparser'
149
DEFAULT_INDENT_TYPE = '    '
1185.12.49 by Aaron Bentley
Switched to ConfigObj
150
MAX_INTERPOL_DEPTH = 10
151
152
OPTION_DEFAULTS = {
153
    'interpolation': True,
154
    'raise_errors': False,
155
    'list_values': True,
156
    'create_empty': False,
157
    'file_error': False,
158
    'configspec': None,
159
    'stringify': True,
160
    # option may be set to one of ('', ' ', '\t')
161
    'indent_type': None,
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
162
    'encoding': None,
163
    'default_encoding': None,
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
164
    'unrepr': False,
165
    'write_empty_values': False,
1185.12.49 by Aaron Bentley
Switched to ConfigObj
166
}
167
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
168
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
169
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
170
def getObj(s):
171
    s = "a=" + s
172
    if compiler is None:
173
        raise ImportError('compiler module not available')
174
    p = compiler.parse(s)
175
    return p.getChildren()[1].getChildren()[0].getChildren()[1]
176
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
177
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
178
class UnknownType(Exception):
179
    pass
180
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
181
182
class Builder(object):
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
183
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
184
    def build(self, o):
185
        m = getattr(self, 'build_' + o.__class__.__name__, None)
186
        if m is None:
187
            raise UnknownType(o.__class__.__name__)
188
        return m(o)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
189
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
190
    def build_List(self, o):
191
        return map(self.build, o.getChildren())
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
192
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
193
    def build_Const(self, o):
194
        return o.value
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
195
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
196
    def build_Dict(self, o):
197
        d = {}
198
        i = iter(map(self.build, o.getChildren()))
199
        for el in i:
200
            d[el] = i.next()
201
        return d
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
202
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
203
    def build_Tuple(self, o):
204
        return tuple(self.build_List(o))
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
205
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
206
    def build_Name(self, o):
207
        if o.name == 'None':
208
            return None
209
        if o.name == 'True':
210
            return True
211
        if o.name == 'False':
212
            return False
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
213
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
214
        # An undefined Name
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
215
        raise UnknownType('Undefined Name')
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
216
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
217
    def build_Add(self, o):
218
        real, imag = map(self.build_Const, o.getChildren())
219
        try:
220
            real = float(real)
221
        except TypeError:
222
            raise UnknownType('Add')
223
        if not isinstance(imag, complex) or imag.real != 0.0:
224
            raise UnknownType('Add')
225
        return real+imag
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
226
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
227
    def build_Getattr(self, o):
228
        parent = self.build(o.expr)
229
        return getattr(parent, o.attrname)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
230
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
231
    def build_UnarySub(self, o):
232
        return -self.build_Const(o.getChildren()[0])
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
233
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
234
    def build_UnaryAdd(self, o):
235
        return self.build_Const(o.getChildren()[0])
236
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
237
238
_builder = Builder()
239
240
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
241
def unrepr(s):
242
    if not s:
243
        return s
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
244
    return _builder.build(getObj(s))
245
246
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
247
1185.12.49 by Aaron Bentley
Switched to ConfigObj
248
class ConfigObjError(SyntaxError):
249
    """
250
    This is the base class for all errors that ConfigObj raises.
251
    It is a subclass of SyntaxError.
252
    """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
253
    def __init__(self, message='', line_number=None, line=''):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
254
        self.line = line
255
        self.line_number = line_number
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
256
        SyntaxError.__init__(self, message)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
257
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
258
1185.12.49 by Aaron Bentley
Switched to ConfigObj
259
class NestingError(ConfigObjError):
260
    """
261
    This error indicates a level of nesting that doesn't match.
262
    """
263
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
264
1185.12.49 by Aaron Bentley
Switched to ConfigObj
265
class ParseError(ConfigObjError):
266
    """
267
    This error indicates that a line is badly written.
268
    It is neither a valid ``key = value`` line,
269
    nor a valid section marker line.
270
    """
271
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
272
273
class ReloadError(IOError):
274
    """
275
    A 'reload' operation failed.
276
    This exception is a subclass of ``IOError``.
277
    """
278
    def __init__(self):
279
        IOError.__init__(self, 'reload failed, filename is not set.')
280
281
1185.12.49 by Aaron Bentley
Switched to ConfigObj
282
class DuplicateError(ConfigObjError):
283
    """
284
    The keyword or section specified already exists.
285
    """
286
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
287
1185.12.49 by Aaron Bentley
Switched to ConfigObj
288
class ConfigspecError(ConfigObjError):
289
    """
290
    An error occured whilst parsing a configspec.
291
    """
292
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
293
1185.12.49 by Aaron Bentley
Switched to ConfigObj
294
class InterpolationError(ConfigObjError):
295
    """Base class for the two interpolation errors."""
296
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
297
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
298
class InterpolationLoopError(InterpolationError):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
299
    """Maximum interpolation depth exceeded in string interpolation."""
300
301
    def __init__(self, option):
302
        InterpolationError.__init__(
303
            self,
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
304
            'interpolation loop detected in value "%s".' % option)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
305
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
306
1185.12.49 by Aaron Bentley
Switched to ConfigObj
307
class RepeatSectionError(ConfigObjError):
308
    """
309
    This error indicates additional sections in a section with a
310
    ``__many__`` (repeated) section.
311
    """
312
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
313
1185.12.49 by Aaron Bentley
Switched to ConfigObj
314
class MissingInterpolationOption(InterpolationError):
315
    """A value specified for interpolation was missing."""
316
317
    def __init__(self, option):
318
        InterpolationError.__init__(
319
            self,
320
            'missing option "%s" in interpolation.' % option)
321
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
322
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
323
class UnreprError(ConfigObjError):
324
    """An error parsing in unrepr mode."""
325
326
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
327
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
328
class InterpolationEngine(object):
329
    """
330
    A helper class to help perform string interpolation.
331
332
    This class is an abstract base class; its descendants perform
333
    the actual work.
334
    """
335
336
    # compiled regexp to use in self.interpolate()
337
    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
338
339
    def __init__(self, section):
340
        # the Section instance that "owns" this engine
341
        self.section = section
342
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
343
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
344
    def interpolate(self, key, value):
345
        def recursive_interpolate(key, value, section, backtrail):
346
            """The function that does the actual work.
347
348
            ``value``: the string we're trying to interpolate.
349
            ``section``: the section in which that string was found
350
            ``backtrail``: a dict to keep track of where we've been,
351
            to detect and prevent infinite recursion loops
352
353
            This is similar to a depth-first-search algorithm.
354
            """
355
            # Have we been here already?
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
356
            if (key, section.name) in backtrail:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
357
                # Yes - infinite loop detected
358
                raise InterpolationLoopError(key)
359
            # Place a marker on our backtrail so we won't come back here again
360
            backtrail[(key, section.name)] = 1
361
362
            # Now start the actual work
363
            match = self._KEYCRE.search(value)
364
            while match:
365
                # The actual parsing of the match is implementation-dependent,
366
                # so delegate to our helper function
367
                k, v, s = self._parse_match(match)
368
                if k is None:
369
                    # That's the signal that no further interpolation is needed
370
                    replacement = v
371
                else:
372
                    # Further interpolation may be needed to obtain final value
373
                    replacement = recursive_interpolate(k, v, s, backtrail)
374
                # Replace the matched string with its final value
375
                start, end = match.span()
376
                value = ''.join((value[:start], replacement, value[end:]))
377
                new_search_start = start + len(replacement)
378
                # Pick up the next interpolation key, if any, for next time
379
                # through the while loop
380
                match = self._KEYCRE.search(value, new_search_start)
381
382
            # Now safe to come back here again; remove marker from backtrail
383
            del backtrail[(key, section.name)]
384
385
            return value
386
387
        # Back in interpolate(), all we have to do is kick off the recursive
388
        # function with appropriate starting values
389
        value = recursive_interpolate(key, value, self.section, {})
390
        return value
391
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
392
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
393
    def _fetch(self, key):
394
        """Helper function to fetch values from owning section.
395
396
        Returns a 2-tuple: the value, and the section where it was found.
397
        """
398
        # switch off interpolation before we try and fetch anything !
399
        save_interp = self.section.main.interpolation
400
        self.section.main.interpolation = False
401
402
        # Start at section that "owns" this InterpolationEngine
403
        current_section = self.section
404
        while True:
405
            # try the current section first
406
            val = current_section.get(key)
407
            if val is not None:
408
                break
409
            # try "DEFAULT" next
410
            val = current_section.get('DEFAULT', {}).get(key)
411
            if val is not None:
412
                break
413
            # move up to parent and try again
414
            # top-level's parent is itself
415
            if current_section.parent is current_section:
416
                # reached top level, time to give up
417
                break
418
            current_section = current_section.parent
419
420
        # restore interpolation to previous value before returning
421
        self.section.main.interpolation = save_interp
422
        if val is None:
423
            raise MissingInterpolationOption(key)
424
        return val, current_section
425
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
426
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
427
    def _parse_match(self, match):
428
        """Implementation-dependent helper function.
429
430
        Will be passed a match object corresponding to the interpolation
431
        key we just found (e.g., "%(foo)s" or "$foo"). Should look up that
432
        key in the appropriate config file section (using the ``_fetch()``
433
        helper function) and return a 3-tuple: (key, value, section)
434
435
        ``key`` is the name of the key we're looking for
436
        ``value`` is the value found for that key
437
        ``section`` is a reference to the section where it was found
438
439
        ``key`` and ``section`` should be None if no further
440
        interpolation should be performed on the resulting value
441
        (e.g., if we interpolated "$$" and returned "$").
442
        """
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
443
        raise NotImplementedError()
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
444
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
445
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
446
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
447
class ConfigParserInterpolation(InterpolationEngine):
448
    """Behaves like ConfigParser."""
449
    _KEYCRE = re.compile(r"%\(([^)]*)\)s")
450
451
    def _parse_match(self, match):
452
        key = match.group(1)
453
        value, section = self._fetch(key)
454
        return key, value, section
455
456
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
457
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
458
class TemplateInterpolation(InterpolationEngine):
459
    """Behaves like string.Template."""
460
    _delimiter = '$'
461
    _KEYCRE = re.compile(r"""
462
        \$(?:
463
          (?P<escaped>\$)              |   # Two $ signs
464
          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format
465
          {(?P<braced>[^}]*)}              # ${name} format
466
        )
467
        """, re.IGNORECASE | re.VERBOSE)
468
469
    def _parse_match(self, match):
470
        # Valid name (in or out of braces): fetch value from section
471
        key = match.group('named') or match.group('braced')
472
        if key is not None:
473
            value, section = self._fetch(key)
474
            return key, value, section
475
        # Escaped delimiter (e.g., $$): return single delimiter
476
        if match.group('escaped') is not None:
477
            # Return None for key and section to indicate it's time to stop
478
            return None, self._delimiter, None
479
        # Anything else: ignore completely, just return it unchanged
480
        return None, match.group(), None
481
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
482
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
483
interpolation_engines = {
484
    'configparser': ConfigParserInterpolation,
485
    'template': TemplateInterpolation,
486
}
487
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
488
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
489
def __newobj__(cls, *args):
490
    # Hack for pickle
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
491
    return cls.__new__(cls, *args)
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
492
1185.12.49 by Aaron Bentley
Switched to ConfigObj
493
class Section(dict):
494
    """
495
    A dictionary-like object that represents a section in a config file.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
496
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
497
    It does string interpolation if the 'interpolation' attribute
1185.12.49 by Aaron Bentley
Switched to ConfigObj
498
    of the 'main' object is set to True.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
499
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
500
    Interpolation is tried first from this object, then from the 'DEFAULT'
501
    section of this object, next from the parent and its 'DEFAULT' section,
502
    and so on until the main object is reached.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
503
1185.12.49 by Aaron Bentley
Switched to ConfigObj
504
    A Section will behave like an ordered dictionary - following the
505
    order of the ``scalars`` and ``sections`` attributes.
506
    You can use this to change the order of members.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
507
1185.12.49 by Aaron Bentley
Switched to ConfigObj
508
    Iteration follows the order: scalars, then sections.
509
    """
510
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
511
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
512
    def __setstate__(self, state):
513
        dict.update(self, state[0])
514
        self.__dict__.update(state[1])
515
516
    def __reduce__(self):
517
        state = (dict(self), self.__dict__)
518
        return (__newobj__, (self.__class__,), state)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
519
520
1185.12.49 by Aaron Bentley
Switched to ConfigObj
521
    def __init__(self, parent, depth, main, indict=None, name=None):
522
        """
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
523
        * parent is the section above
524
        * depth is the depth level of this section
525
        * main is the main ConfigObj
526
        * indict is a dictionary to initialise the section with
1185.12.49 by Aaron Bentley
Switched to ConfigObj
527
        """
528
        if indict is None:
529
            indict = {}
530
        dict.__init__(self)
531
        # used for nesting level *and* interpolation
532
        self.parent = parent
533
        # used for the interpolation attribute
534
        self.main = main
535
        # level of nesting depth of this Section
536
        self.depth = depth
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
537
        # purely for information
538
        self.name = name
539
        #
540
        self._initialise()
541
        # we do this explicitly so that __setitem__ is used properly
542
        # (rather than just passing to ``dict.__init__``)
543
        for entry, value in indict.iteritems():
544
            self[entry] = value
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
545
546
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
547
    def _initialise(self):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
548
        # the sequence of scalar values in this Section
549
        self.scalars = []
550
        # the sequence of sections in this Section
551
        self.sections = []
552
        # for comments :-)
553
        self.comments = {}
554
        self.inline_comments = {}
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
555
        # the configspec
556
        self.configspec = None
1185.12.49 by Aaron Bentley
Switched to ConfigObj
557
        # for defaults
558
        self.defaults = []
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
559
        self.default_values = {}
560
1185.12.49 by Aaron Bentley
Switched to ConfigObj
561
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
562
    def _interpolate(self, key, value):
563
        try:
564
            # do we already have an interpolation engine?
565
            engine = self._interpolation_engine
566
        except AttributeError:
567
            # not yet: first time running _interpolate(), so pick the engine
568
            name = self.main.interpolation
569
            if name == True:  # note that "if name:" would be incorrect here
570
                # backwards-compatibility: interpolation=True means use default
571
                name = DEFAULT_INTERPOLATION
572
            name = name.lower()  # so that "Template", "template", etc. all work
573
            class_ = interpolation_engines.get(name, None)
574
            if class_ is None:
575
                # invalid value for self.main.interpolation
576
                self.main.interpolation = False
577
                return value
1185.12.49 by Aaron Bentley
Switched to ConfigObj
578
            else:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
579
                # save reference to engine so we don't have to do this again
580
                engine = self._interpolation_engine = class_(self)
581
        # let the engine do the actual work
582
        return engine.interpolate(key, value)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
583
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
584
1185.12.49 by Aaron Bentley
Switched to ConfigObj
585
    def __getitem__(self, key):
586
        """Fetch the item and do string interpolation."""
587
        val = dict.__getitem__(self, key)
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
588
        if self.main.interpolation and isinstance(val, basestring):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
589
            return self._interpolate(key, val)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
590
        return val
591
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
592
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
593
    def __setitem__(self, key, value, unrepr=False):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
594
        """
595
        Correctly set a value.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
596
1185.12.49 by Aaron Bentley
Switched to ConfigObj
597
        Making dictionary values Section instances.
598
        (We have to special case 'Section' instances - which are also dicts)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
599
1185.12.49 by Aaron Bentley
Switched to ConfigObj
600
        Keys must be strings.
601
        Values need only be strings (or lists of strings) if
602
        ``main.stringify`` is set.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
603
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
604
        ``unrepr`` must be set when setting a value to a dictionary, without
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
605
        creating a new sub-section.
1185.12.49 by Aaron Bentley
Switched to ConfigObj
606
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
607
        if not isinstance(key, basestring):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
608
            raise ValueError('The key "%s" is not a string.' % key)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
609
1185.12.49 by Aaron Bentley
Switched to ConfigObj
610
        # add the comment
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
611
        if key not in self.comments:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
612
            self.comments[key] = []
613
            self.inline_comments[key] = ''
614
        # remove the entry from defaults
615
        if key in self.defaults:
616
            self.defaults.remove(key)
617
        #
618
        if isinstance(value, Section):
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
619
            if key not in self:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
620
                self.sections.append(key)
621
            dict.__setitem__(self, key, value)
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
622
        elif isinstance(value, dict) and not unrepr:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
623
            # First create the new depth level,
624
            # then create the section
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
625
            if key not in self:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
626
                self.sections.append(key)
627
            new_depth = self.depth + 1
628
            dict.__setitem__(
629
                self,
630
                key,
631
                Section(
632
                    self,
633
                    new_depth,
634
                    self.main,
635
                    indict=value,
636
                    name=key))
637
        else:
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
638
            if key not in self:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
639
                self.scalars.append(key)
640
            if not self.main.stringify:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
641
                if isinstance(value, basestring):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
642
                    pass
643
                elif isinstance(value, (list, tuple)):
644
                    for entry in value:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
645
                        if not isinstance(entry, basestring):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
646
                            raise TypeError('Value is not a string "%s".' % entry)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
647
                else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
648
                    raise TypeError('Value is not a string "%s".' % value)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
649
            dict.__setitem__(self, key, value)
650
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
651
1185.12.49 by Aaron Bentley
Switched to ConfigObj
652
    def __delitem__(self, key):
653
        """Remove items from the sequence when deleting."""
654
        dict. __delitem__(self, key)
655
        if key in self.scalars:
656
            self.scalars.remove(key)
657
        else:
658
            self.sections.remove(key)
659
        del self.comments[key]
660
        del self.inline_comments[key]
661
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
662
1185.12.49 by Aaron Bentley
Switched to ConfigObj
663
    def get(self, key, default=None):
664
        """A version of ``get`` that doesn't bypass string interpolation."""
665
        try:
666
            return self[key]
667
        except KeyError:
668
            return default
669
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
670
1185.12.49 by Aaron Bentley
Switched to ConfigObj
671
    def update(self, indict):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
672
        """
673
        A version of update that uses our ``__setitem__``.
674
        """
1185.12.49 by Aaron Bentley
Switched to ConfigObj
675
        for entry in indict:
676
            self[entry] = indict[entry]
677
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
678
1185.12.49 by Aaron Bentley
Switched to ConfigObj
679
    def pop(self, key, *args):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
680
        """
681
        'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
682
        If key is not found, d is returned if given, otherwise KeyError is raised'
683
        """
1185.12.49 by Aaron Bentley
Switched to ConfigObj
684
        val = dict.pop(self, key, *args)
685
        if key in self.scalars:
686
            del self.comments[key]
687
            del self.inline_comments[key]
688
            self.scalars.remove(key)
689
        elif key in self.sections:
690
            del self.comments[key]
691
            del self.inline_comments[key]
692
            self.sections.remove(key)
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
693
        if self.main.interpolation and isinstance(val, basestring):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
694
            return self._interpolate(key, val)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
695
        return val
696
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
697
1185.12.49 by Aaron Bentley
Switched to ConfigObj
698
    def popitem(self):
699
        """Pops the first (key,val)"""
700
        sequence = (self.scalars + self.sections)
701
        if not sequence:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
702
            raise KeyError(": 'popitem(): dictionary is empty'")
1185.12.49 by Aaron Bentley
Switched to ConfigObj
703
        key = sequence[0]
704
        val =  self[key]
705
        del self[key]
706
        return key, val
707
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
708
1185.12.49 by Aaron Bentley
Switched to ConfigObj
709
    def clear(self):
710
        """
711
        A version of clear that also affects scalars/sections
712
        Also clears comments and configspec.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
713
1185.12.49 by Aaron Bentley
Switched to ConfigObj
714
        Leaves other attributes alone :
715
            depth/main/parent are not affected
716
        """
717
        dict.clear(self)
718
        self.scalars = []
719
        self.sections = []
720
        self.comments = {}
721
        self.inline_comments = {}
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
722
        self.configspec = None
1185.12.49 by Aaron Bentley
Switched to ConfigObj
723
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
724
1185.12.49 by Aaron Bentley
Switched to ConfigObj
725
    def setdefault(self, key, default=None):
726
        """A version of setdefault that sets sequence if appropriate."""
727
        try:
728
            return self[key]
729
        except KeyError:
730
            self[key] = default
731
            return self[key]
732
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
733
1185.12.49 by Aaron Bentley
Switched to ConfigObj
734
    def items(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
735
        """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
736
        return zip((self.scalars + self.sections), self.values())
737
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
738
1185.12.49 by Aaron Bentley
Switched to ConfigObj
739
    def keys(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
740
        """D.keys() -> list of D's keys"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
741
        return (self.scalars + self.sections)
742
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
743
1185.12.49 by Aaron Bentley
Switched to ConfigObj
744
    def values(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
745
        """D.values() -> list of D's values"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
746
        return [self[key] for key in (self.scalars + self.sections)]
747
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
748
1185.12.49 by Aaron Bentley
Switched to ConfigObj
749
    def iteritems(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
750
        """D.iteritems() -> an iterator over the (key, value) items of D"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
751
        return iter(self.items())
752
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
753
1185.12.49 by Aaron Bentley
Switched to ConfigObj
754
    def iterkeys(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
755
        """D.iterkeys() -> an iterator over the keys of D"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
756
        return iter((self.scalars + self.sections))
757
758
    __iter__ = iterkeys
759
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
760
1185.12.49 by Aaron Bentley
Switched to ConfigObj
761
    def itervalues(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
762
        """D.itervalues() -> an iterator over the values of D"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
763
        return iter(self.values())
764
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
765
1185.12.49 by Aaron Bentley
Switched to ConfigObj
766
    def __repr__(self):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
767
        """x.__repr__() <==> repr(x)"""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
768
        return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(self[key])))
769
            for key in (self.scalars + self.sections)])
770
771
    __str__ = __repr__
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
772
    __str__.__doc__ = "x.__str__() <==> str(x)"
773
1185.12.49 by Aaron Bentley
Switched to ConfigObj
774
775
    # Extra methods - not in a normal dictionary
776
777
    def dict(self):
778
        """
779
        Return a deepcopy of self as a dictionary.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
780
1185.12.49 by Aaron Bentley
Switched to ConfigObj
781
        All members that are ``Section`` instances are recursively turned to
782
        ordinary dictionaries - by calling their ``dict`` method.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
783
1185.12.49 by Aaron Bentley
Switched to ConfigObj
784
        >>> n = a.dict()
785
        >>> n == a
786
        1
787
        >>> n is a
788
        0
789
        """
790
        newdict = {}
791
        for entry in self:
792
            this_entry = self[entry]
793
            if isinstance(this_entry, Section):
794
                this_entry = this_entry.dict()
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
795
            elif isinstance(this_entry, list):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
796
                # create a copy rather than a reference
797
                this_entry = list(this_entry)
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
798
            elif isinstance(this_entry, tuple):
799
                # create a copy rather than a reference
800
                this_entry = tuple(this_entry)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
801
            newdict[entry] = this_entry
802
        return newdict
803
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
804
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
805
    def merge(self, indict):
806
        """
807
        A recursive update - useful for merging config files.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
808
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
809
        >>> a = '''[section1]
810
        ...     option1 = True
811
        ...     [[subsection]]
812
        ...     more_options = False
813
        ...     # end of file'''.splitlines()
814
        >>> b = '''# File is user.ini
815
        ...     [section1]
816
        ...     option1 = False
817
        ...     # end of file'''.splitlines()
818
        >>> c1 = ConfigObj(b)
819
        >>> c2 = ConfigObj(a)
820
        >>> c2.merge(c1)
821
        >>> c2
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
822
        ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}})
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
823
        """
824
        for key, val in indict.items():
825
            if (key in self and isinstance(self[key], dict) and
826
                                isinstance(val, dict)):
827
                self[key].merge(val)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
828
            else:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
829
                self[key] = val
830
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
831
1185.12.49 by Aaron Bentley
Switched to ConfigObj
832
    def rename(self, oldkey, newkey):
833
        """
834
        Change a keyname to another, without changing position in sequence.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
835
1185.12.49 by Aaron Bentley
Switched to ConfigObj
836
        Implemented so that transformations can be made on keys,
837
        as well as on values. (used by encode and decode)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
838
1185.12.49 by Aaron Bentley
Switched to ConfigObj
839
        Also renames comments.
840
        """
841
        if oldkey in self.scalars:
842
            the_list = self.scalars
843
        elif oldkey in self.sections:
844
            the_list = self.sections
845
        else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
846
            raise KeyError('Key "%s" not found.' % oldkey)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
847
        pos = the_list.index(oldkey)
848
        #
849
        val = self[oldkey]
850
        dict.__delitem__(self, oldkey)
851
        dict.__setitem__(self, newkey, val)
852
        the_list.remove(oldkey)
853
        the_list.insert(pos, newkey)
854
        comm = self.comments[oldkey]
855
        inline_comment = self.inline_comments[oldkey]
856
        del self.comments[oldkey]
857
        del self.inline_comments[oldkey]
858
        self.comments[newkey] = comm
859
        self.inline_comments[newkey] = inline_comment
860
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
861
1185.12.49 by Aaron Bentley
Switched to ConfigObj
862
    def walk(self, function, raise_errors=True,
863
            call_on_sections=False, **keywargs):
864
        """
865
        Walk every member and call a function on the keyword and value.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
866
1185.12.49 by Aaron Bentley
Switched to ConfigObj
867
        Return a dictionary of the return values
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
868
1185.12.49 by Aaron Bentley
Switched to ConfigObj
869
        If the function raises an exception, raise the errror
870
        unless ``raise_errors=False``, in which case set the return value to
871
        ``False``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
872
1185.12.49 by Aaron Bentley
Switched to ConfigObj
873
        Any unrecognised keyword arguments you pass to walk, will be pased on
874
        to the function you pass in.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
875
1185.12.49 by Aaron Bentley
Switched to ConfigObj
876
        Note: if ``call_on_sections`` is ``True`` then - on encountering a
877
        subsection, *first* the function is called for the *whole* subsection,
878
        and then recurses into it's members. This means your function must be
879
        able to handle strings, dictionaries and lists. This allows you
880
        to change the key of subsections as well as for ordinary members. The
881
        return value when called on the whole subsection has to be discarded.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
882
1185.12.49 by Aaron Bentley
Switched to ConfigObj
883
        See  the encode and decode methods for examples, including functions.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
884
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
885
        .. admonition:: caution
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
886
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
887
            You can use ``walk`` to transform the names of members of a section
888
            but you mustn't add or delete members.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
889
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
890
        >>> config = '''[XXXXsection]
891
        ... XXXXkey = XXXXvalue'''.splitlines()
892
        >>> cfg = ConfigObj(config)
893
        >>> cfg
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
894
        ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
895
        >>> def transform(section, key):
896
        ...     val = section[key]
897
        ...     newkey = key.replace('XXXX', 'CLIENT1')
898
        ...     section.rename(key, newkey)
899
        ...     if isinstance(val, (tuple, list, dict)):
900
        ...         pass
901
        ...     else:
902
        ...         val = val.replace('XXXX', 'CLIENT1')
903
        ...         section[newkey] = val
904
        >>> cfg.walk(transform, call_on_sections=True)
905
        {'CLIENT1section': {'CLIENT1key': None}}
906
        >>> cfg
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
907
        ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}})
1185.12.49 by Aaron Bentley
Switched to ConfigObj
908
        """
909
        out = {}
910
        # scalars first
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
911
        for i in range(len(self.scalars)):
912
            entry = self.scalars[i]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
913
            try:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
914
                val = function(self, entry, **keywargs)
915
                # bound again in case name has changed
916
                entry = self.scalars[i]
917
                out[entry] = val
1185.12.49 by Aaron Bentley
Switched to ConfigObj
918
            except Exception:
919
                if raise_errors:
920
                    raise
921
                else:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
922
                    entry = self.scalars[i]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
923
                    out[entry] = False
924
        # then sections
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
925
        for i in range(len(self.sections)):
926
            entry = self.sections[i]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
927
            if call_on_sections:
928
                try:
929
                    function(self, entry, **keywargs)
930
                except Exception:
931
                    if raise_errors:
932
                        raise
933
                    else:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
934
                        entry = self.sections[i]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
935
                        out[entry] = False
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
936
                # bound again in case name has changed
937
                entry = self.sections[i]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
938
            # previous result is discarded
939
            out[entry] = self[entry].walk(
940
                function,
941
                raise_errors=raise_errors,
942
                call_on_sections=call_on_sections,
943
                **keywargs)
944
        return out
945
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
946
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
947
    def as_bool(self, key):
948
        """
949
        Accepts a key as input. The corresponding value must be a string or
950
        the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
951
        retain compatibility with Python 2.2.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
952
953
        If the string is one of  ``True``, ``On``, ``Yes``, or ``1`` it returns
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
954
        ``True``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
955
956
        If the string is one of  ``False``, ``Off``, ``No``, or ``0`` it returns
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
957
        ``False``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
958
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
959
        ``as_bool`` is not case sensitive.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
960
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
961
        Any other input will raise a ``ValueError``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
962
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
963
        >>> a = ConfigObj()
964
        >>> a['a'] = 'fish'
965
        >>> a.as_bool('a')
966
        Traceback (most recent call last):
967
        ValueError: Value "fish" is neither True nor False
968
        >>> a['b'] = 'True'
969
        >>> a.as_bool('b')
970
        1
971
        >>> a['b'] = 'off'
972
        >>> a.as_bool('b')
973
        0
974
        """
975
        val = self[key]
976
        if val == True:
977
            return True
978
        elif val == False:
979
            return False
980
        else:
981
            try:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
982
                if not isinstance(val, basestring):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
983
                    # TODO: Why do we raise a KeyError here?
984
                    raise KeyError()
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
985
                else:
986
                    return self.main._bools[val.lower()]
987
            except KeyError:
988
                raise ValueError('Value "%s" is neither True nor False' % val)
989
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
990
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
991
    def as_int(self, key):
992
        """
993
        A convenience method which coerces the specified value to an integer.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
994
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
995
        If the value is an invalid literal for ``int``, a ``ValueError`` will
996
        be raised.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
997
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
998
        >>> a = ConfigObj()
999
        >>> a['a'] = 'fish'
1000
        >>> a.as_int('a')
1001
        Traceback (most recent call last):
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1002
        ValueError: invalid literal for int() with base 10: 'fish'
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1003
        >>> a['b'] = '1'
1004
        >>> a.as_int('b')
1005
        1
1006
        >>> a['b'] = '3.2'
1007
        >>> a.as_int('b')
1008
        Traceback (most recent call last):
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1009
        ValueError: invalid literal for int() with base 10: '3.2'
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1010
        """
1011
        return int(self[key])
1012
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1013
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1014
    def as_float(self, key):
1015
        """
1016
        A convenience method which coerces the specified value to a float.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1017
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1018
        If the value is an invalid literal for ``float``, a ``ValueError`` will
1019
        be raised.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1020
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1021
        >>> a = ConfigObj()
1022
        >>> a['a'] = 'fish'
1023
        >>> a.as_float('a')
1024
        Traceback (most recent call last):
1025
        ValueError: invalid literal for float(): fish
1026
        >>> a['b'] = '1'
1027
        >>> a.as_float('b')
1028
        1.0
1029
        >>> a['b'] = '3.2'
1030
        >>> a.as_float('b')
1031
        3.2000000000000002
1032
        """
1033
        return float(self[key])
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1034
1035
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1036
    def as_list(self, key):
1037
        """
1038
        A convenience method which fetches the specified value, guaranteeing
1039
        that it is a list.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1040
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1041
        >>> a = ConfigObj()
1042
        >>> a['a'] = 1
1043
        >>> a.as_list('a')
1044
        [1]
1045
        >>> a['a'] = (1,)
1046
        >>> a.as_list('a')
1047
        [1]
1048
        >>> a['a'] = [1]
1049
        >>> a.as_list('a')
1050
        [1]
1051
        """
1052
        result = self[key]
1053
        if isinstance(result, (tuple, list)):
1054
            return list(result)
1055
        return [result]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1056
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1057
1058
    def restore_default(self, key):
1059
        """
1060
        Restore (and return) default value for the specified key.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1061
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1062
        This method will only work for a ConfigObj that was created
1063
        with a configspec and has been validated.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1064
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1065
        If there is no default value for this key, ``KeyError`` is raised.
1066
        """
1067
        default = self.default_values[key]
1068
        dict.__setitem__(self, key, default)
1069
        if key not in self.defaults:
1070
            self.defaults.append(key)
1071
        return default
1072
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1073
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1074
    def restore_defaults(self):
1075
        """
1076
        Recursively restore default values to all members
1077
        that have them.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1078
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1079
        This method will only work for a ConfigObj that was created
1080
        with a configspec and has been validated.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1081
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1082
        It doesn't delete or modify entries without default values.
1083
        """
1084
        for key in self.default_values:
1085
            self.restore_default(key)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1086
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1087
        for section in self.sections:
1088
            self[section].restore_defaults()
1089
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1090
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1091
class ConfigObj(Section):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1092
    """An object to read, create, and write config files."""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1093
1094
    _keyword = re.compile(r'''^ # line start
1095
        (\s*)                   # indentation
1096
        (                       # keyword
1097
            (?:".*?")|          # double quotes
1098
            (?:'.*?')|          # single quotes
1099
            (?:[^'"=].*?)       # no quotes
1100
        )
1101
        \s*=\s*                 # divider
1102
        (.*)                    # value (including list values and comments)
1103
        $   # line end
1104
        ''',
1105
        re.VERBOSE)
1106
1107
    _sectionmarker = re.compile(r'''^
1108
        (\s*)                     # 1: indentation
1109
        ((?:\[\s*)+)              # 2: section marker open
1110
        (                         # 3: section name open
1111
            (?:"\s*\S.*?\s*")|    # at least one non-space with double quotes
1112
            (?:'\s*\S.*?\s*')|    # at least one non-space with single quotes
1113
            (?:[^'"\s].*?)        # at least one non-space unquoted
1114
        )                         # section name close
1115
        ((?:\s*\])+)              # 4: section marker close
1116
        \s*(\#.*)?                # 5: optional comment
1117
        $''',
1118
        re.VERBOSE)
1119
1120
    # this regexp pulls list values out as a single string
1121
    # or single values and comments
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1122
    # FIXME: this regex adds a '' to the end of comma terminated lists
1123
    #   workaround in ``_handle_value``
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1124
    _valueexp = re.compile(r'''^
1125
        (?:
1126
            (?:
1127
                (
1128
                    (?:
1129
                        (?:
1130
                            (?:".*?")|              # double quotes
1131
                            (?:'.*?')|              # single quotes
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1132
                            (?:[^'",\#][^,\#]*?)    # unquoted
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1133
                        )
1134
                        \s*,\s*                     # comma
1135
                    )*      # match all list items ending in a comma (if any)
1136
                )
1137
                (
1138
                    (?:".*?")|                      # double quotes
1139
                    (?:'.*?')|                      # single quotes
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1140
                    (?:[^'",\#\s][^,]*?)|           # unquoted
1141
                    (?:(?<!,))                      # Empty value
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1142
                )?          # last item in a list - or string value
1143
            )|
1144
            (,)             # alternatively a single comma - empty list
1145
        )
1146
        \s*(\#.*)?          # optional comment
1147
        $''',
1148
        re.VERBOSE)
1149
1150
    # use findall to get the members of a list value
1151
    _listvalueexp = re.compile(r'''
1152
        (
1153
            (?:".*?")|          # double quotes
1154
            (?:'.*?')|          # single quotes
1155
            (?:[^'",\#].*?)       # unquoted
1156
        )
1157
        \s*,\s*                 # comma
1158
        ''',
1159
        re.VERBOSE)
1160
1161
    # this regexp is used for the value
1162
    # when lists are switched off
1163
    _nolistvalue = re.compile(r'''^
1164
        (
1165
            (?:".*?")|          # double quotes
1166
            (?:'.*?')|          # single quotes
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1167
            (?:[^'"\#].*?)|     # unquoted
1168
            (?:)                # Empty value
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1169
        )
1170
        \s*(\#.*)?              # optional comment
1171
        $''',
1172
        re.VERBOSE)
1173
1174
    # regexes for finding triple quoted values on one line
1175
    _single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")
1176
    _single_line_double = re.compile(r'^"""(.*?)"""\s*(#.*)?$')
1177
    _multi_line_single = re.compile(r"^(.*?)'''\s*(#.*)?$")
1178
    _multi_line_double = re.compile(r'^(.*?)"""\s*(#.*)?$')
1179
1180
    _triple_quote = {
1181
        "'''": (_single_line_single, _multi_line_single),
1182
        '"""': (_single_line_double, _multi_line_double),
1183
    }
1184
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1185
    # Used by the ``istrue`` Section method
1186
    _bools = {
1187
        'yes': True, 'no': False,
1188
        'on': True, 'off': False,
1189
        '1': True, '0': False,
1190
        'true': True, 'false': False,
1191
        }
1192
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1193
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1194
    def __init__(self, infile=None, options=None, _inspec=False, **kwargs):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1195
        """
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1196
        Parse a config file or create a config file object.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1197
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1198
        ``ConfigObj(infile=None, options=None, **kwargs)``
1199
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1200
        self._inspec = _inspec
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1201
        # init the superclass
1202
        Section.__init__(self, self, 0, self)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1203
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1204
        infile = infile or []
1205
        options = dict(options or {})
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1206
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1207
        # keyword arguments take precedence over an options dictionary
1208
        options.update(kwargs)
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1209
        if _inspec:
1210
            options['list_values'] = False
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1211
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1212
        defaults = OPTION_DEFAULTS.copy()
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1213
        # TODO: check the values too.
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1214
        for entry in options:
1215
            if entry not in defaults:
1216
                raise TypeError('Unrecognised option "%s".' % entry)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1217
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1218
        # Add any explicit options to the defaults
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1219
        defaults.update(options)
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1220
        self._initialise(defaults)
1221
        configspec = defaults['configspec']
1222
        self._original_configspec = configspec
1223
        self._load(infile, configspec)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1224
1225
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1226
    def _load(self, infile, configspec):
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1227
        if isinstance(infile, basestring):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1228
            self.filename = infile
1229
            if os.path.isfile(infile):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1230
                h = open(infile, 'rb')
1231
                infile = h.read() or []
1232
                h.close()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1233
            elif self.file_error:
1234
                # raise an error if the file doesn't exist
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1235
                raise IOError('Config file not found: "%s".' % self.filename)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1236
            else:
1237
                # file doesn't already exist
1238
                if self.create_empty:
1239
                    # this is a good test that the filename specified
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1240
                    # isn't impossible - like on a non-existent device
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1241
                    h = open(infile, 'w')
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1242
                    h.write('')
1243
                    h.close()
1244
                infile = []
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1245
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1246
        elif isinstance(infile, (list, tuple)):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1247
            infile = list(infile)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1248
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1249
        elif isinstance(infile, dict):
1250
            # initialise self
1251
            # the Section class handles creating subsections
1252
            if isinstance(infile, ConfigObj):
1253
                # get a copy of our ConfigObj
1254
                infile = infile.dict()
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1255
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1256
            for entry in infile:
1257
                self[entry] = infile[entry]
1258
            del self._errors
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1259
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1260
            if configspec is not None:
1261
                self._handle_configspec(configspec)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1262
            else:
1263
                self.configspec = None
1264
            return
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1265
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1266
        elif getattr(infile, 'read', MISSING) is not MISSING:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1267
            # This supports file like objects
1268
            infile = infile.read() or []
1269
            # needs splitting into lines - but needs doing *after* decoding
1270
            # in case it's not an 8 bit encoding
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1271
        else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1272
            raise TypeError('infile must be a filename, file like object, or list of lines.')
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1273
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1274
        if infile:
1275
            # don't do it for the empty ConfigObj
1276
            infile = self._handle_bom(infile)
1277
            # infile is now *always* a list
1278
            #
1279
            # Set the newlines attribute (first line ending it finds)
1280
            # and strip trailing '\n' or '\r' from lines
1281
            for line in infile:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1282
                if (not line) or (line[-1] not in ('\r', '\n', '\r\n')):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1283
                    continue
1284
                for end in ('\r\n', '\n', '\r'):
1285
                    if line.endswith(end):
1286
                        self.newlines = end
1287
                        break
1288
                break
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1289
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1290
            infile = [line.rstrip('\r\n') for line in infile]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1291
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1292
        self._parse(infile)
1293
        # if we had any errors, now is the time to raise them
1294
        if self._errors:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1295
            info = "at line %s." % self._errors[0].line_number
1296
            if len(self._errors) > 1:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1297
                msg = "Parsing failed with several errors.\nFirst error %s" % info
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1298
                error = ConfigObjError(msg)
1299
            else:
1300
                error = self._errors[0]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1301
            # set the errors attribute; it's a list of tuples:
1302
            # (error_type, message, line_number)
1303
            error.errors = self._errors
1304
            # set the config attribute
1305
            error.config = self
1306
            raise error
1307
        # delete private attributes
1308
        del self._errors
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1309
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1310
        if configspec is None:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1311
            self.configspec = None
1312
        else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1313
            self._handle_configspec(configspec)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1314
1315
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1316
    def _initialise(self, options=None):
1317
        if options is None:
1318
            options = OPTION_DEFAULTS
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1319
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1320
        # initialise a few variables
1321
        self.filename = None
1322
        self._errors = []
1323
        self.raise_errors = options['raise_errors']
1324
        self.interpolation = options['interpolation']
1325
        self.list_values = options['list_values']
1326
        self.create_empty = options['create_empty']
1327
        self.file_error = options['file_error']
1328
        self.stringify = options['stringify']
1329
        self.indent_type = options['indent_type']
1330
        self.encoding = options['encoding']
1331
        self.default_encoding = options['default_encoding']
1332
        self.BOM = False
1333
        self.newlines = None
1334
        self.write_empty_values = options['write_empty_values']
1335
        self.unrepr = options['unrepr']
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1336
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1337
        self.initial_comment = []
1338
        self.final_comment = []
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1339
        self.configspec = None
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1340
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1341
        if self._inspec:
1342
            self.list_values = False
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1343
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1344
        # Clear section attributes as well
1345
        Section._initialise(self)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1346
1347
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1348
    def __repr__(self):
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1349
        return ('ConfigObj({%s})' %
1350
                ', '.join([('%s: %s' % (repr(key), repr(self[key])))
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1351
                for key in (self.scalars + self.sections)]))
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1352
1353
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1354
    def _handle_bom(self, infile):
1355
        """
1356
        Handle any BOM, and decode if necessary.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1357
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1358
        If an encoding is specified, that *must* be used - but the BOM should
1359
        still be removed (and the BOM attribute set).
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1360
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1361
        (If the encoding is wrongly specified, then a BOM for an alternative
1362
        encoding won't be discovered or removed.)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1363
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1364
        If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
1365
        removed. The BOM attribute will be set. UTF16 will be decoded to
1366
        unicode.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1367
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1368
        NOTE: This method must not be called with an empty ``infile``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1369
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1370
        Specifying the *wrong* encoding is likely to cause a
1371
        ``UnicodeDecodeError``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1372
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1373
        ``infile`` must always be returned as a list of lines, but may be
1374
        passed in as a single string.
1375
        """
1376
        if ((self.encoding is not None) and
1377
            (self.encoding.lower() not in BOM_LIST)):
1378
            # No need to check for a BOM
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1379
            # the encoding specified doesn't have one
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1380
            # just decode
1381
            return self._decode(infile, self.encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1382
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1383
        if isinstance(infile, (list, tuple)):
1384
            line = infile[0]
1385
        else:
1386
            line = infile
1387
        if self.encoding is not None:
1388
            # encoding explicitly supplied
1389
            # And it could have an associated BOM
1390
            # TODO: if encoding is just UTF16 - we ought to check for both
1391
            # TODO: big endian and little endian versions.
1392
            enc = BOM_LIST[self.encoding.lower()]
1393
            if enc == 'utf_16':
1394
                # For UTF16 we try big endian and little endian
1395
                for BOM, (encoding, final_encoding) in BOMS.items():
1396
                    if not final_encoding:
1397
                        # skip UTF8
1398
                        continue
1399
                    if infile.startswith(BOM):
1400
                        ### BOM discovered
1401
                        ##self.BOM = True
1402
                        # Don't need to remove BOM
1403
                        return self._decode(infile, encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1404
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1405
                # If we get this far, will *probably* raise a DecodeError
1406
                # As it doesn't appear to start with a BOM
1407
                return self._decode(infile, self.encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1408
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1409
            # Must be UTF8
1410
            BOM = BOM_SET[enc]
1411
            if not line.startswith(BOM):
1412
                return self._decode(infile, self.encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1413
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1414
            newline = line[len(BOM):]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1415
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1416
            # BOM removed
1417
            if isinstance(infile, (list, tuple)):
1418
                infile[0] = newline
1419
            else:
1420
                infile = newline
1421
            self.BOM = True
1422
            return self._decode(infile, self.encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1423
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1424
        # No encoding specified - so we need to check for UTF8/UTF16
1425
        for BOM, (encoding, final_encoding) in BOMS.items():
1426
            if not line.startswith(BOM):
1427
                continue
1428
            else:
1429
                # BOM discovered
1430
                self.encoding = final_encoding
1431
                if not final_encoding:
1432
                    self.BOM = True
1433
                    # UTF8
1434
                    # remove BOM
1435
                    newline = line[len(BOM):]
1436
                    if isinstance(infile, (list, tuple)):
1437
                        infile[0] = newline
1438
                    else:
1439
                        infile = newline
1440
                    # UTF8 - don't decode
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1441
                    if isinstance(infile, basestring):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1442
                        return infile.splitlines(True)
1443
                    else:
1444
                        return infile
1445
                # UTF16 - have to decode
1446
                return self._decode(infile, encoding)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1447
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1448
        # No BOM discovered and no encoding specified, just return
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1449
        if isinstance(infile, basestring):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1450
            # infile read from a file will be a single string
1451
            return infile.splitlines(True)
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1452
        return infile
1453
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1454
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1455
    def _a_to_u(self, aString):
1456
        """Decode ASCII strings to unicode if a self.encoding is specified."""
1457
        if self.encoding:
1458
            return aString.decode('ascii')
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1459
        else:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1460
            return aString
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1461
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1462
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1463
    def _decode(self, infile, encoding):
1464
        """
1465
        Decode infile to unicode. Using the specified encoding.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1466
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1467
        if is a string, it also needs converting to a list.
1468
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1469
        if isinstance(infile, basestring):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1470
            # can't be unicode
1471
            # NOTE: Could raise a ``UnicodeDecodeError``
1472
            return infile.decode(encoding).splitlines(True)
1473
        for i, line in enumerate(infile):
1474
            if not isinstance(line, unicode):
1475
                # NOTE: The isinstance test here handles mixed lists of unicode/string
1476
                # NOTE: But the decode will break on any non-string values
1477
                # NOTE: Or could raise a ``UnicodeDecodeError``
1478
                infile[i] = line.decode(encoding)
1479
        return infile
1480
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1481
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1482
    def _decode_element(self, line):
1483
        """Decode element to unicode if necessary."""
1484
        if not self.encoding:
1485
            return line
1486
        if isinstance(line, str) and self.default_encoding:
1487
            return line.decode(self.default_encoding)
1488
        return line
1489
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1490
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1491
    def _str(self, value):
1492
        """
1493
        Used by ``stringify`` within validate, to turn non-string values
1494
        into strings.
1495
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1496
        if not isinstance(value, basestring):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1497
            return str(value)
1498
        else:
1499
            return value
1500
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1501
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1502
    def _parse(self, infile):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1503
        """Actually parse the config file."""
1504
        temp_list_values = self.list_values
1505
        if self.unrepr:
1506
            self.list_values = False
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1507
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1508
        comment_list = []
1509
        done_start = False
1510
        this_section = self
1511
        maxline = len(infile) - 1
1512
        cur_index = -1
1513
        reset_comment = False
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1514
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1515
        while cur_index < maxline:
1516
            if reset_comment:
1517
                comment_list = []
1518
            cur_index += 1
1519
            line = infile[cur_index]
1520
            sline = line.strip()
1521
            # do we have anything on the line ?
1522
            if not sline or sline.startswith('#'):
1523
                reset_comment = False
1524
                comment_list.append(line)
1525
                continue
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1526
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1527
            if not done_start:
1528
                # preserve initial comment
1529
                self.initial_comment = comment_list
1530
                comment_list = []
1531
                done_start = True
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1532
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1533
            reset_comment = True
1534
            # first we check if it's a section marker
1535
            mat = self._sectionmarker.match(line)
1536
            if mat is not None:
1537
                # is a section line
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1538
                (indent, sect_open, sect_name, sect_close, comment) = mat.groups()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1539
                if indent and (self.indent_type is None):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1540
                    self.indent_type = indent
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1541
                cur_depth = sect_open.count('[')
1542
                if cur_depth != sect_close.count(']'):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1543
                    self._handle_error("Cannot compute the section depth at line %s.",
1544
                                       NestingError, infile, cur_index)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1545
                    continue
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1546
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1547
                if cur_depth < this_section.depth:
1548
                    # the new section is dropping back to a previous level
1549
                    try:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1550
                        parent = self._match_depth(this_section,
1551
                                                   cur_depth).parent
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1552
                    except SyntaxError:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1553
                        self._handle_error("Cannot compute nesting level at line %s.",
1554
                                           NestingError, infile, cur_index)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1555
                        continue
1556
                elif cur_depth == this_section.depth:
1557
                    # the new section is a sibling of the current section
1558
                    parent = this_section.parent
1559
                elif cur_depth == this_section.depth + 1:
1560
                    # the new section is a child the current section
1561
                    parent = this_section
1562
                else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1563
                    self._handle_error("Section too nested at line %s.",
1564
                                       NestingError, infile, cur_index)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1565
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1566
                sect_name = self._unquote(sect_name)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1567
                if sect_name in parent:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1568
                    self._handle_error('Duplicate section name at line %s.',
1569
                                       DuplicateError, infile, cur_index)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1570
                    continue
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1571
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1572
                # create the new section
1573
                this_section = Section(
1574
                    parent,
1575
                    cur_depth,
1576
                    self,
1577
                    name=sect_name)
1578
                parent[sect_name] = this_section
1579
                parent.inline_comments[sect_name] = comment
1580
                parent.comments[sect_name] = comment_list
1581
                continue
1582
            #
1583
            # it's not a section marker,
1584
            # so it should be a valid ``key = value`` line
1585
            mat = self._keyword.match(line)
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1586
            if mat is None:
1587
                # it neither matched as a keyword
1588
                # or a section marker
1589
                self._handle_error(
1590
                    'Invalid line at line "%s".',
1591
                    ParseError, infile, cur_index)
1592
            else:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1593
                # is a keyword value
1594
                # value will include any inline comment
1595
                (indent, key, value) = mat.groups()
1596
                if indent and (self.indent_type is None):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1597
                    self.indent_type = indent
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1598
                # check for a multiline value
1599
                if value[:3] in ['"""', "'''"]:
1600
                    try:
1601
                        (value, comment, cur_index) = self._multiline(
1602
                            value, infile, cur_index, maxline)
1603
                    except SyntaxError:
1604
                        self._handle_error(
1605
                            'Parse error in value at line %s.',
1606
                            ParseError, infile, cur_index)
1607
                        continue
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1608
                    else:
1609
                        if self.unrepr:
1610
                            comment = ''
1611
                            try:
1612
                                value = unrepr(value)
1613
                            except Exception, e:
1614
                                if type(e) == UnknownType:
1615
                                    msg = 'Unknown name or type in value at line %s.'
1616
                                else:
1617
                                    msg = 'Parse error in value at line %s.'
1618
                                self._handle_error(msg, UnreprError, infile,
1619
                                    cur_index)
1620
                                continue
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1621
                else:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1622
                    if self.unrepr:
1623
                        comment = ''
1624
                        try:
1625
                            value = unrepr(value)
1626
                        except Exception, e:
1627
                            if isinstance(e, UnknownType):
1628
                                msg = 'Unknown name or type in value at line %s.'
1629
                            else:
1630
                                msg = 'Parse error in value at line %s.'
1631
                            self._handle_error(msg, UnreprError, infile,
1632
                                cur_index)
1633
                            continue
1634
                    else:
1635
                        # extract comment and lists
1636
                        try:
1637
                            (value, comment) = self._handle_value(value)
1638
                        except SyntaxError:
1639
                            self._handle_error(
1640
                                'Parse error in value at line %s.',
1641
                                ParseError, infile, cur_index)
1642
                            continue
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1643
                #
1644
                key = self._unquote(key)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1645
                if key in this_section:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1646
                    self._handle_error(
1647
                        'Duplicate keyword name at line %s.',
1648
                        DuplicateError, infile, cur_index)
1649
                    continue
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1650
                # add the key.
1651
                # we set unrepr because if we have got this far we will never
1652
                # be creating a new section
1653
                this_section.__setitem__(key, value, unrepr=True)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1654
                this_section.inline_comments[key] = comment
1655
                this_section.comments[key] = comment_list
1656
                continue
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1657
        #
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1658
        if self.indent_type is None:
1659
            # no indentation used, set the type accordingly
1660
            self.indent_type = ''
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1661
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1662
        # preserve the final comment
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1663
        if not self and not self.initial_comment:
1664
            self.initial_comment = comment_list
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1665
        elif not reset_comment:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1666
            self.final_comment = comment_list
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1667
        self.list_values = temp_list_values
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1668
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1669
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1670
    def _match_depth(self, sect, depth):
1671
        """
1672
        Given a section and a depth level, walk back through the sections
1673
        parents to see if the depth level matches a previous section.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1674
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1675
        Return a reference to the right section,
1676
        or raise a SyntaxError.
1677
        """
1678
        while depth < sect.depth:
1679
            if sect is sect.parent:
1680
                # we've reached the top level already
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1681
                raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1682
            sect = sect.parent
1683
        if sect.depth == depth:
1684
            return sect
1685
        # shouldn't get here
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1686
        raise SyntaxError()
1687
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1688
1689
    def _handle_error(self, text, ErrorClass, infile, cur_index):
1690
        """
1691
        Handle an error according to the error settings.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1692
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1693
        Either raise the error or store it.
1694
        The error will have occured at ``cur_index``
1695
        """
1696
        line = infile[cur_index]
2900.1.2 by Vincent Ladeuil
Fix 149019 by using a proper line number when reporting errors.
1697
        cur_index += 1
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1698
        message = text % cur_index
1699
        error = ErrorClass(message, cur_index, line)
1700
        if self.raise_errors:
1701
            # raise the error - parsing stops here
1702
            raise error
1703
        # store the error
1704
        # reraise when parsing has finished
1705
        self._errors.append(error)
1706
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1707
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1708
    def _unquote(self, value):
1709
        """Return an unquoted version of a value"""
1710
        if (value[0] == value[-1]) and (value[0] in ('"', "'")):
1711
            value = value[1:-1]
1712
        return value
1713
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1714
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1715
    def _quote(self, value, multiline=True):
1716
        """
1717
        Return a safely quoted version of a value.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1718
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1719
        Raise a ConfigObjError if the value cannot be safely quoted.
1720
        If multiline is ``True`` (default) then use triple quotes
1721
        if necessary.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1722
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1723
        * Don't quote values that don't need it.
1724
        * Recursively quote members of a list and return a comma joined list.
1725
        * Multiline is ``False`` for lists.
1726
        * Obey list syntax for empty and single member lists.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1727
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1728
        If ``list_values=False`` then the value is only quoted if it contains
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1729
        a ``\\n`` (is multiline) or '#'.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1730
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1731
        If ``write_empty_values`` is set, and the value is an empty string, it
1732
        won't be quoted.
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1733
        """
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1734
        if multiline and self.write_empty_values and value == '':
1735
            # Only if multiline is set, so that it is used for values not
1736
            # keys, and not values that are part of a list
1737
            return ''
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1738
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1739
        if multiline and isinstance(value, (list, tuple)):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1740
            if not value:
1741
                return ','
1742
            elif len(value) == 1:
1743
                return self._quote(value[0], multiline=False) + ','
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1744
            return ', '.join([self._quote(val, multiline=False)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1745
                for val in value])
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1746
        if not isinstance(value, basestring):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1747
            if self.stringify:
1748
                value = str(value)
1749
            else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1750
                raise TypeError('Value "%s" is not a string.' % value)
1751
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1752
        if not value:
1753
            return '""'
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1754
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1755
        no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value
1756
        need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))
1757
        hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)
1758
        check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1759
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1760
        if check_for_single:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1761
            if not self.list_values:
1762
                # we don't quote if ``list_values=False``
1763
                quot = noquot
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1764
            # for normal values either single or double quotes will do
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1765
            elif '\n' in value:
1766
                # will only happen if multiline is off - e.g. '\n' in key
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1767
                raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1768
            elif ((value[0] not in wspace_plus) and
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1769
                    (value[-1] not in wspace_plus) and
1770
                    (',' not in value)):
1771
                quot = noquot
1772
            else:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1773
                quot = self._get_single_quote(value)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1774
        else:
1775
            # if value has '\n' or "'" *and* '"', it will need triple quotes
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1776
            quot = self._get_triple_quote(value)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1777
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1778
        if quot == noquot and '#' in value and self.list_values:
1779
            quot = self._get_single_quote(value)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1780
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1781
        return quot % value
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1782
1783
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1784
    def _get_single_quote(self, value):
1785
        if ("'" in value) and ('"' in value):
1786
            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
1787
        elif '"' in value:
1788
            quot = squot
1789
        else:
1790
            quot = dquot
1791
        return quot
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1792
1793
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1794
    def _get_triple_quote(self, value):
1795
        if (value.find('"""') != -1) and (value.find("'''") != -1):
1796
            raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
1797
        if value.find('"""') == -1:
1798
            quot = tdquot
1799
        else:
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1800
            quot = tsquot
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1801
        return quot
1802
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1803
1804
    def _handle_value(self, value):
1805
        """
1806
        Given a value string, unquote, remove comment,
1807
        handle lists. (including empty and single member lists)
1808
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1809
        if self._inspec:
1810
            # Parsing a configspec so don't handle comments
1811
            return (value, '')
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1812
        # do we look for lists in values ?
1813
        if not self.list_values:
1814
            mat = self._nolistvalue.match(value)
1815
            if mat is None:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1816
                raise SyntaxError()
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1817
            # NOTE: we don't unquote here
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1818
            return mat.groups()
1819
        #
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1820
        mat = self._valueexp.match(value)
1821
        if mat is None:
1822
            # the value is badly constructed, probably badly quoted,
1823
            # or an invalid list
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1824
            raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1825
        (list_values, single, empty_list, comment) = mat.groups()
1826
        if (list_values == '') and (single is None):
1827
            # change this if you want to accept empty values
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1828
            raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1829
        # NOTE: note there is no error handling from here if the regex
1830
        # is wrong: then incorrect values will slip through
1831
        if empty_list is not None:
1832
            # the single comma - meaning an empty list
1833
            return ([], comment)
1834
        if single is not None:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1835
            # handle empty values
1836
            if list_values and not single:
1837
                # FIXME: the '' is a workaround because our regex now matches
1838
                #   '' at the end of a list if it has a trailing comma
1839
                single = None
1840
            else:
1841
                single = single or '""'
1842
                single = self._unquote(single)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1843
        if list_values == '':
1844
            # not a list value
1845
            return (single, comment)
1846
        the_list = self._listvalueexp.findall(list_values)
1847
        the_list = [self._unquote(val) for val in the_list]
1848
        if single is not None:
1849
            the_list += [single]
1850
        return (the_list, comment)
1851
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1852
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1853
    def _multiline(self, value, infile, cur_index, maxline):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1854
        """Extract the value, where we are in a multiline situation."""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1855
        quot = value[:3]
1856
        newvalue = value[3:]
1857
        single_line = self._triple_quote[quot][0]
1858
        multi_line = self._triple_quote[quot][1]
1859
        mat = single_line.match(value)
1860
        if mat is not None:
1861
            retval = list(mat.groups())
1862
            retval.append(cur_index)
1863
            return retval
1864
        elif newvalue.find(quot) != -1:
1865
            # somehow the triple quote is missing
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1866
            raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1867
        #
1868
        while cur_index < maxline:
1869
            cur_index += 1
1870
            newvalue += '\n'
1871
            line = infile[cur_index]
1872
            if line.find(quot) == -1:
1873
                newvalue += line
1874
            else:
1875
                # end of multiline, process it
1876
                break
1877
        else:
1878
            # we've got to the end of the config, oops...
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1879
            raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1880
        mat = multi_line.match(line)
1881
        if mat is None:
1882
            # a badly formed line
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1883
            raise SyntaxError()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1884
        (value, comment) = mat.groups()
1885
        return (newvalue + value, comment, cur_index)
1886
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1887
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1888
    def _handle_configspec(self, configspec):
1889
        """Parse the configspec."""
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1890
        # FIXME: Should we check that the configspec was created with the
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1891
        #        correct settings ? (i.e. ``list_values=False``)
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1892
        if not isinstance(configspec, ConfigObj):
1893
            try:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1894
                configspec = ConfigObj(configspec,
1895
                                       raise_errors=True,
1896
                                       file_error=True,
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1897
                                       _inspec=True)
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1898
            except ConfigObjError, e:
1899
                # FIXME: Should these errors have a reference
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1900
                #        to the already parsed ConfigObj ?
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1901
                raise ConfigspecError('Parsing configspec failed: %s' % e)
1902
            except IOError, e:
1903
                raise IOError('Reading configspec failed: %s' % e)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1904
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1905
        self.configspec = configspec
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1906
1907
1908
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1909
    def _set_configspec(self, section, copy):
1910
        """
1911
        Called by validate. Handles setting the configspec on subsections
1912
        including sections to be validated by __many__
1913
        """
1914
        configspec = section.configspec
1915
        many = configspec.get('__many__')
1916
        if isinstance(many, dict):
1917
            for entry in section.sections:
1918
                if entry not in configspec:
1919
                    section[entry].configspec = many
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1920
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1921
        for entry in configspec.sections:
1922
            if entry == '__many__':
1923
                continue
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1924
            if entry not in section:
1925
                section[entry] = {}
1926
                if copy:
1927
                    # copy comments
1928
                    section.comments[entry] = configspec.comments.get(entry, [])
1929
                    section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1930
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
1931
            # Could be a scalar when we expect a section
1932
            if isinstance(section[entry], Section):
1933
                section[entry].configspec = configspec[entry]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1934
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1935
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1936
    def _write_line(self, indent_string, entry, this_entry, comment):
1937
        """Write an individual line, for the write method"""
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1938
        # NOTE: the calls to self._quote here handles non-StringType values.
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1939
        if not self.unrepr:
1940
            val = self._decode_element(self._quote(this_entry))
1941
        else:
1942
            val = repr(this_entry)
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1943
        return '%s%s%s%s%s' % (indent_string,
1944
                               self._decode_element(self._quote(entry, multiline=False)),
1945
                               self._a_to_u(' = '),
1946
                               val,
1947
                               self._decode_element(comment))
1948
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1949
1950
    def _write_marker(self, indent_string, depth, entry, comment):
1951
        """Write a section marker line"""
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1952
        return '%s%s%s%s%s' % (indent_string,
1953
                               self._a_to_u('[' * depth),
1954
                               self._quote(self._decode_element(entry), multiline=False),
1955
                               self._a_to_u(']' * depth),
1956
                               self._decode_element(comment))
1957
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1958
1959
    def _handle_comment(self, comment):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1960
        """Deal with a comment."""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1961
        if not comment:
1962
            return ''
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1963
        start = self.indent_type
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1964
        if not comment.startswith('#'):
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
1965
            start += self._a_to_u(' # ')
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1966
        return (start + comment)
1967
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
1968
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1969
    # Public methods
1970
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1971
    def write(self, outfile=None, section=None):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1972
        """
1973
        Write the current ConfigObj as a file
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1974
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1975
        tekNico: FIXME: use StringIO instead of real files
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1976
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1977
        >>> filename = a.filename
1978
        >>> a.filename = 'test.ini'
1979
        >>> a.write()
1980
        >>> a.filename = filename
1981
        >>> a == ConfigObj('test.ini', raise_errors=True)
1982
        1
1983
        """
1984
        if self.indent_type is None:
1985
            # this can be true if initialised from a dictionary
1986
            self.indent_type = DEFAULT_INDENT_TYPE
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
1987
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1988
        out = []
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1989
        cs = self._a_to_u('#')
1990
        csp = self._a_to_u('# ')
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1991
        if section is None:
1992
            int_val = self.interpolation
1993
            self.interpolation = False
1994
            section = self
1995
            for line in self.initial_comment:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1996
                line = self._decode_element(line)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
1997
                stripped_line = line.strip()
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
1998
                if stripped_line and not stripped_line.startswith(cs):
1999
                    line = csp + line
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2000
                out.append(line)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2001
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2002
        indent_string = self.indent_type * section.depth
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2003
        for entry in (section.scalars + section.sections):
2004
            if entry in section.defaults:
2005
                # don't write out default values
2006
                continue
2007
            for comment_line in section.comments[entry]:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2008
                comment_line = self._decode_element(comment_line.lstrip())
2009
                if comment_line and not comment_line.startswith(cs):
2010
                    comment_line = csp + comment_line
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2011
                out.append(indent_string + comment_line)
2012
            this_entry = section[entry]
2013
            comment = self._handle_comment(section.inline_comments[entry])
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2014
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2015
            if isinstance(this_entry, dict):
2016
                # a section
2017
                out.append(self._write_marker(
2018
                    indent_string,
2019
                    this_entry.depth,
2020
                    entry,
2021
                    comment))
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2022
                out.extend(self.write(section=this_entry))
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2023
            else:
2024
                out.append(self._write_line(
2025
                    indent_string,
2026
                    entry,
2027
                    this_entry,
2028
                    comment))
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2029
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2030
        if section is self:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2031
            for line in self.final_comment:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2032
                line = self._decode_element(line)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2033
                stripped_line = line.strip()
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2034
                if stripped_line and not stripped_line.startswith(cs):
2035
                    line = csp + line
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2036
                out.append(line)
2037
            self.interpolation = int_val
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2038
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2039
        if section is not self:
2040
            return out
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2041
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2042
        if (self.filename is None) and (outfile is None):
2043
            # output a list of lines
2044
            # might need to encode
2045
            # NOTE: This will *screw* UTF16, each line will start with the BOM
2046
            if self.encoding:
2047
                out = [l.encode(self.encoding) for l in out]
2048
            if (self.BOM and ((self.encoding is None) or
2049
                (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
2050
                # Add the UTF8 BOM
2051
                if not out:
2052
                    out.append('')
2053
                out[0] = BOM_UTF8 + out[0]
2054
            return out
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2055
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2056
        # Turn the list to a string, joined with correct newlines
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2057
        newline = self.newlines or os.linesep
2058
        output = self._a_to_u(newline).join(out)
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2059
        if self.encoding:
2060
            output = output.encode(self.encoding)
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2061
        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2062
            # Add the UTF8 BOM
2063
            output = BOM_UTF8 + output
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2064
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2065
        if not output.endswith(newline):
2066
            output += newline
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2067
        if outfile is not None:
2068
            outfile.write(output)
2069
        else:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2070
            h = open(self.filename, 'wb')
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2071
            h.write(output)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2072
            h.close()
2073
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2074
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2075
    def validate(self, validator, preserve_errors=False, copy=False,
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2076
                 section=None):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2077
        """
2078
        Test the ConfigObj against a configspec.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2079
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2080
        It uses the ``validator`` object from *validate.py*.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2081
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2082
        To run ``validate`` on the current ConfigObj, call: ::
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2083
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2084
            test = config.validate(validator)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2085
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2086
        (Normally having previously passed in the configspec when the ConfigObj
2087
        was created - you can dynamically assign a dictionary of checks to the
2088
        ``configspec`` attribute of a section though).
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2089
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2090
        It returns ``True`` if everything passes, or a dictionary of
2091
        pass/fails (True/False). If every member of a subsection passes, it
2092
        will just have the value ``True``. (It also returns ``False`` if all
2093
        members fail).
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2094
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2095
        In addition, it converts the values from strings to their native
2096
        types if their checks pass (and ``stringify`` is set).
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2097
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2098
        If ``preserve_errors`` is ``True`` (``False`` is default) then instead
2099
        of a marking a fail with a ``False``, it will preserve the actual
2100
        exception object. This can contain info about the reason for failure.
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2101
        For example the ``VdtValueTooSmallError`` indicates that the value
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2102
        supplied was too small. If a value (or section) is missing it will
2103
        still be marked as ``False``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2104
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2105
        You must have the validate module to use ``preserve_errors=True``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2106
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2107
        You can then use the ``flatten_errors`` function to turn your nested
2108
        results dictionary into a flattened list of failures - useful for
2109
        displaying meaningful error messages.
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2110
        """
2111
        if section is None:
2112
            if self.configspec is None:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2113
                raise ValueError('No configspec supplied.')
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2114
            if preserve_errors:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2115
                # We do this once to remove a top level dependency on the validate module
2116
                # Which makes importing configobj faster
2117
                from validate import VdtMissingValue
2118
                self._vdtMissingValue = VdtMissingValue
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2119
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2120
            section = self
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2121
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2122
            if copy:
2123
                section.initial_comment = section.configspec.initial_comment
2124
                section.final_comment = section.configspec.final_comment
2125
                section.encoding = section.configspec.encoding
2126
                section.BOM = section.configspec.BOM
2127
                section.newlines = section.configspec.newlines
2128
                section.indent_type = section.configspec.indent_type
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2129
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2130
        #
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2131
        configspec = section.configspec
2132
        self._set_configspec(section, copy)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2133
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2134
        def validate_entry(entry, spec, val, missing, ret_true, ret_false):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2135
            try:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2136
                check = validator.check(spec,
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2137
                                        val,
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2138
                                        missing=missing
2139
                                        )
2140
            except validator.baseErrorClass, e:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2141
                if not preserve_errors or isinstance(e, self._vdtMissingValue):
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2142
                    out[entry] = False
2143
                else:
2144
                    # preserve the error
2145
                    out[entry] = e
2146
                    ret_false = False
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2147
                ret_true = False
2148
            else:
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2149
                try:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2150
                    section.default_values.pop(entry, None)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2151
                except AttributeError:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2152
                    # For Python 2.2 compatibility
2153
                    try:
2154
                        del section.default_values[entry]
2155
                    except KeyError:
2156
                        pass
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2157
2158
                try:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2159
                    section.default_values[entry] = validator.get_default_value(configspec[entry])
2160
                except (KeyError, AttributeError):
2161
                    # No default or validator has no 'get_default_value' (e.g. SimpleVal)
2162
                    pass
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2163
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2164
                ret_false = False
2165
                out[entry] = True
2166
                if self.stringify or missing:
2167
                    # if we are doing type conversion
2168
                    # or the value is a supplied default
2169
                    if not self.stringify:
2170
                        if isinstance(check, (list, tuple)):
2171
                            # preserve lists
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2172
                            check = [self._str(item) for item in check]
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2173
                        elif missing and check is None:
2174
                            # convert the None from a default to a ''
2175
                            check = ''
2176
                        else:
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2177
                            check = self._str(check)
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2178
                    if (check != val) or missing:
2179
                        section[entry] = check
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2180
                if not copy and missing and entry not in section.defaults:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2181
                    section.defaults.append(entry)
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2182
            return ret_true, ret_false
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2183
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2184
        #
2185
        out = {}
2186
        ret_true = True
2187
        ret_false = True
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2188
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2189
        unvalidated = [k for k in section.scalars if k not in configspec]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2190
        incorrect_sections = [k for k in configspec.sections if k in section.scalars]
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2191
        incorrect_scalars = [k for k in configspec.scalars if k in section.sections]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2192
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2193
        for entry in configspec.scalars:
2194
            if entry in ('__many__', '___many___'):
2195
                # reserved names
2196
                continue
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2197
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2198
            if (not entry in section.scalars) or (entry in section.defaults):
2199
                # missing entries
2200
                # or entries from defaults
2201
                missing = True
2202
                val = None
2203
                if copy and not entry in section.scalars:
2204
                    # copy comments
2205
                    section.comments[entry] = (
2206
                        configspec.comments.get(entry, []))
2207
                    section.inline_comments[entry] = (
2208
                        configspec.inline_comments.get(entry, ''))
2209
                #
2210
            else:
2211
                missing = False
2212
                val = section[entry]
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2213
2214
            ret_true, ret_false = validate_entry(entry, configspec[entry], val,
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2215
                                                 missing, ret_true, ret_false)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2216
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2217
        many = None
2218
        if '__many__' in configspec.scalars:
2219
            many = configspec['__many__']
2220
        elif '___many___' in configspec.scalars:
2221
            many = configspec['___many___']
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2222
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2223
        if many is not None:
2224
            for entry in unvalidated:
2225
                val = section[entry]
2226
                ret_true, ret_false = validate_entry(entry, many, val, False,
2227
                                                     ret_true, ret_false)
2228
2229
        for entry in incorrect_scalars:
2230
            ret_true = False
2231
            if not preserve_errors:
2232
                out[entry] = False
2233
            else:
2234
                ret_false = False
2235
                msg = 'Value %r was provided as a section' % entry
2236
                out[entry] = validator.baseErrorClass(msg)
2237
        for entry in incorrect_sections:
2238
            ret_true = False
2239
            if not preserve_errors:
2240
                out[entry] = False
2241
            else:
2242
                ret_false = False
2243
                msg = 'Section %r was provided as a single value' % entry
2244
                out[entry] = validator.baseErrorClass(msg)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2245
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2246
        # Missing sections will have been created as empty ones when the
2247
        # configspec was read.
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2248
        for entry in section.sections:
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2249
            # FIXME: this means DEFAULT is not copied in copy mode
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2250
            if section is self and entry == 'DEFAULT':
2251
                continue
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2252
            if section[entry].configspec is None:
2253
                continue
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2254
            if copy:
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2255
                section.comments[entry] = configspec.comments.get(entry, [])
2256
                section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
2257
            check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry])
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2258
            out[entry] = check
2259
            if check == False:
2260
                ret_true = False
2261
            elif check == True:
2262
                ret_false = False
2263
            else:
2264
                ret_true = False
2265
                ret_false = False
2266
        #
2267
        if ret_true:
2268
            return True
2269
        elif ret_false:
2270
            return False
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2271
        return out
2272
2273
2274
    def reset(self):
2275
        """Clear ConfigObj instance and restore to 'freshly created' state."""
2276
        self.clear()
2277
        self._initialise()
2278
        # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload)
2279
        #        requires an empty dictionary
2280
        self.configspec = None
2281
        # Just to be sure ;-)
2282
        self._original_configspec = None
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2283
2284
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2285
    def reload(self):
2286
        """
2287
        Reload a ConfigObj from file.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2288
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2289
        This method raises a ``ReloadError`` if the ConfigObj doesn't have
2290
        a filename attribute pointing to a file.
2291
        """
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2292
        if not isinstance(self.filename, basestring):
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2293
            raise ReloadError()
2294
2295
        filename = self.filename
2296
        current_options = {}
2297
        for entry in OPTION_DEFAULTS:
2298
            if entry == 'configspec':
2299
                continue
2300
            current_options[entry] = getattr(self, entry)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2301
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2302
        configspec = self._original_configspec
2303
        current_options['configspec'] = configspec
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2304
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2305
        self.clear()
2306
        self._initialise(current_options)
2307
        self._load(filename, configspec)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2308
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2309
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2310
2311
class SimpleVal(object):
2312
    """
2313
    A simple validator.
2314
    Can be used to check that all members expected are present.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2315
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2316
    To use it, provide a configspec with all your members in (the value given
2317
    will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
2318
    method of your ``ConfigObj``. ``validate`` will return ``True`` if all
2319
    members are present, or a dictionary with True/False meaning
2320
    present/missing. (Whole missing sections will be replaced with ``False``)
2321
    """
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2322
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2323
    def __init__(self):
2324
        self.baseErrorClass = ConfigObjError
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2325
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2326
    def check(self, check, member, missing=False):
2327
        """A dummy check method, always returns the value unchanged."""
2328
        if missing:
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2329
            raise self.baseErrorClass()
1185.12.49 by Aaron Bentley
Switched to ConfigObj
2330
        return member
2331
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2332
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2333
# Check / processing functions for options
2334
def flatten_errors(cfg, res, levels=None, results=None):
2335
    """
2336
    An example function that will turn a nested dictionary of results
2337
    (as returned by ``ConfigObj.validate``) into a flat list.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2338
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2339
    ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
2340
    dictionary returned by ``validate``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2341
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2342
    (This is a recursive function, so you shouldn't use the ``levels`` or
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2343
    ``results`` arguments - they are used by the function.)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2344
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2345
    Returns a list of keys that failed. Each member of the list is a tuple :
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2346
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2347
    ::
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2348
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2349
        ([list of sections...], key, result)
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2350
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2351
    If ``validate`` was called with ``preserve_errors=False`` (the default)
2352
    then ``result`` will always be ``False``.
2353
2354
    *list of sections* is a flattened list of sections that the key was found
2355
    in.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2356
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2357
    If the section was missing (or a section was expected and a scalar provided
2358
    - or vice-versa) then key will be ``None``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2359
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2360
    If the value (or section) was missing then ``result`` will be ``False``.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2361
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2362
    If ``validate`` was called with ``preserve_errors=True`` and a value
2363
    was present, but failed the check, then ``result`` will be the exception
2364
    object returned. You can use this as a string that describes the failure.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2365
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2366
    For example *The value "3" is of the wrong type*.
4299.1.2 by Matt Nordhoff
Restore Bazaar's customizations to configobj.py:
2367
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2368
    >>> import validate
2369
    >>> vtor = validate.Validator()
2370
    >>> my_ini = '''
2371
    ...     option1 = True
2372
    ...     [section1]
2373
    ...     option1 = True
2374
    ...     [section2]
2375
    ...     another_option = Probably
2376
    ...     [section3]
2377
    ...     another_option = True
2378
    ...     [[section3b]]
2379
    ...     value = 3
2380
    ...     value2 = a
2381
    ...     value3 = 11
2382
    ...     '''
2383
    >>> my_cfg = '''
2384
    ...     option1 = boolean()
2385
    ...     option2 = boolean()
2386
    ...     option3 = boolean(default=Bad_value)
2387
    ...     [section1]
2388
    ...     option1 = boolean()
2389
    ...     option2 = boolean()
2390
    ...     option3 = boolean(default=Bad_value)
2391
    ...     [section2]
2392
    ...     another_option = boolean()
2393
    ...     [section3]
2394
    ...     another_option = boolean()
2395
    ...     [[section3b]]
2396
    ...     value = integer
2397
    ...     value2 = integer
2398
    ...     value3 = integer(0, 10)
2399
    ...         [[[section3b-sub]]]
2400
    ...         value = string
2401
    ...     [section4]
2402
    ...     another_option = boolean()
2403
    ...     '''
2404
    >>> cs = my_cfg.split('\\n')
2405
    >>> ini = my_ini.split('\\n')
2406
    >>> cfg = ConfigObj(ini, configspec=cs)
2407
    >>> res = cfg.validate(vtor, preserve_errors=True)
2408
    >>> errors = []
2409
    >>> for entry in flatten_errors(cfg, res):
2410
    ...     section_list, key, error = entry
2411
    ...     section_list.insert(0, '[root]')
2412
    ...     if key is not None:
2413
    ...        section_list.append(key)
2414
    ...     else:
2415
    ...         section_list.append('[missing]')
2416
    ...     section_string = ', '.join(section_list)
2417
    ...     errors.append((section_string, ' = ', error))
2418
    >>> errors.sort()
2419
    >>> for entry in errors:
2420
    ...     print entry[0], entry[1], (entry[2] or 0)
2421
    [root], option2  =  0
2422
    [root], option3  =  the value "Bad_value" is of the wrong type.
2423
    [root], section1, option2  =  0
2424
    [root], section1, option3  =  the value "Bad_value" is of the wrong type.
2425
    [root], section2, another_option  =  the value "Probably" is of the wrong type.
2426
    [root], section3, section3b, section3b-sub, [missing]  =  0
2427
    [root], section3, section3b, value2  =  the value "a" is of the wrong type.
2428
    [root], section3, section3b, value3  =  the value "11" is too big.
2429
    [root], section4, [missing]  =  0
2430
    """
2431
    if levels is None:
2432
        # first time called
2433
        levels = []
2434
        results = []
2435
    if res is True:
2436
        return results
4299.1.1 by Matt Nordhoff
Upgrade ConfigObj to 4.6.0.
2437
    if res is False or isinstance(res, Exception):
2438
        results.append((levels[:], None, res))
1556.2.1 by Aaron Bentley
Switched to ConfigObj 4.2.0
2439
        if levels:
2440
            levels.pop()
2441
        return results
2442
    for (key, val) in res.items():
2443
        if val == True:
2444
            continue
2445
        if isinstance(cfg.get(key), dict):
2446
            # Go down one level
2447
            levels.append(key)
2448
            flatten_errors(cfg[key], val, levels, results)
2449
            continue
2450
        results.append((levels[:], key, val))
2451
    #
2452
    # Go up one level
2453
    if levels:
2454
        levels.pop()
2455
    #
2456
    return results
2457
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
2458
2991.2.1 by Vincent Ladeuil
Update configobj to version 4.4.0:
2459
"""*A programming language is a medium of expression.* - Paul Graham"""