186
186
class Builder(object):
188
188
def build(self, o):
189
189
m = getattr(self, 'build_' + o.__class__.__name__, None)
191
191
raise UnknownType(o.__class__.__name__)
194
194
def build_List(self, o):
195
195
return map(self.build, o.getChildren())
197
197
def build_Const(self, o):
200
200
def build_Dict(self, o):
202
202
i = iter(map(self.build, o.getChildren()))
207
207
def build_Tuple(self, o):
208
208
return tuple(self.build_List(o))
210
210
def build_Name(self, o):
211
211
if o.name == 'None':
227
227
if not isinstance(imag, complex) or imag.real != 0.0:
228
228
raise UnknownType('Add')
231
231
def build_Getattr(self, o):
232
232
parent = self.build(o.expr)
233
233
return getattr(parent, o.attrname)
235
235
def build_UnarySub(self, o):
236
236
return -self.build_Const(o.getChildren()[0])
238
238
def build_UnaryAdd(self, o):
239
239
return self.build_Const(o.getChildren()[0])
495
495
class Section(dict):
497
497
A dictionary-like object that represents a section in a config file.
499
499
It does string interpolation if the 'interpolation' attribute
500
500
of the 'main' object is set to True.
502
502
Interpolation is tried first from this object, then from the 'DEFAULT'
503
503
section of this object, next from the parent and its 'DEFAULT' section,
504
504
and so on until the main object is reached.
506
506
A Section will behave like an ordered dictionary - following the
507
507
order of the ``scalars`` and ``sections`` attributes.
508
508
You can use this to change the order of members.
510
510
Iteration follows the order: scalars, then sections.
590
590
def __setitem__(self, key, value, unrepr=False):
592
592
Correctly set a value.
594
594
Making dictionary values Section instances.
595
595
(We have to special case 'Section' instances - which are also dicts)
597
597
Keys must be strings.
598
598
Values need only be strings (or lists of strings) if
599
599
``main.stringify`` is set.
601
601
`unrepr`` must be set when setting a value to a dictionary, without
602
602
creating a new sub-section.
604
604
if not isinstance(key, StringTypes):
605
605
raise ValueError('The key "%s" is not a string.' % key)
607
607
# add the comment
608
608
if not self.comments.has_key(key):
609
609
self.comments[key] = []
822
822
if (key in self and isinstance(self[key], dict) and
823
823
isinstance(val, dict)):
824
824
self[key].merge(val)
829
829
def rename(self, oldkey, newkey):
831
831
Change a keyname to another, without changing position in sequence.
833
833
Implemented so that transformations can be made on keys,
834
834
as well as on values. (used by encode and decode)
836
836
Also renames comments.
838
838
if oldkey in self.scalars:
860
860
call_on_sections=False, **keywargs):
862
862
Walk every member and call a function on the keyword and value.
864
864
Return a dictionary of the return values
866
866
If the function raises an exception, raise the errror
867
867
unless ``raise_errors=False``, in which case set the return value to
870
870
Any unrecognised keyword arguments you pass to walk, will be pased on
871
871
to the function you pass in.
873
873
Note: if ``call_on_sections`` is ``True`` then - on encountering a
874
874
subsection, *first* the function is called for the *whole* subsection,
875
875
and then recurses into it's members. This means your function must be
876
876
able to handle strings, dictionaries and lists. This allows you
877
877
to change the key of subsections as well as for ordinary members. The
878
878
return value when called on the whole subsection has to be discarded.
880
880
See the encode and decode methods for examples, including functions.
884
884
You can use ``walk`` to transform the names of members of a section
885
885
but you mustn't add or delete members.
887
887
>>> config = '''[XXXXsection]
888
888
... XXXXkey = XXXXvalue'''.splitlines()
889
889
>>> cfg = ConfigObj(config)
944
944
def decode(self, encoding):
946
946
Decode all strings and values to unicode, using the specified encoding.
948
948
Works with subsections and list values.
950
950
Uses the ``walk`` method.
952
952
Testing ``encode`` and ``decode``.
953
953
>>> m = ConfigObj(a)
954
954
>>> m.decode('ascii')
990
990
Encode all strings and values from unicode,
991
991
using the specified encoding.
993
993
Works with subsections and list values.
994
994
Uses the ``walk`` method.
1023
1023
Accepts a key as input. The corresponding value must be a string or
1024
1024
the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
1025
1025
retain compatibility with Python 2.2.
1027
If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns
1027
If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns
1030
If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns
1030
If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns
1033
1033
``as_bool`` is not case sensitive.
1035
1035
Any other input will raise a ``ValueError``.
1037
1037
>>> a = ConfigObj()
1038
1038
>>> a['a'] = 'fish'
1039
1039
>>> a.as_bool('a')
1110
1110
def restore_default(self, key):
1112
1112
Restore (and return) default value for the specified key.
1114
1114
This method will only work for a ConfigObj that was created
1115
1115
with a configspec and has been validated.
1117
1117
If there is no default value for this key, ``KeyError`` is raised.
1119
1119
default = self.default_values[key]
1122
1122
self.defaults.append(key)
1126
1126
def restore_defaults(self):
1128
1128
Recursively restore default values to all members
1129
1129
that have them.
1131
1131
This method will only work for a ConfigObj that was created
1132
1132
with a configspec and has been validated.
1134
1134
It doesn't delete or modify entries without default values.
1136
1136
for key in self.default_values:
1137
1137
self.restore_default(key)
1139
1139
for section in self.sections:
1140
1140
self[section].restore_defaults()
1246
1246
def __init__(self, infile=None, options=None, **kwargs):
1248
1248
Parse a config file or create a config file object.
1250
1250
``ConfigObj(infile=None, options=None, **kwargs)``
1252
1252
# init the superclass
1253
1253
Section.__init__(self, self, 0, self)
1255
1255
if infile is None:
1257
1257
if options is None:
1260
1260
options = dict(options)
1262
1262
# keyword arguments take precedence over an options dictionary
1263
1263
options.update(kwargs)
1265
1265
defaults = OPTION_DEFAULTS.copy()
1266
1266
# TODO: check the values too.
1267
1267
for entry in options:
1268
1268
if entry not in defaults:
1269
1269
raise TypeError('Unrecognised option "%s".' % entry)
1271
1271
# Add any explicit options to the defaults
1272
1272
defaults.update(options)
1273
1273
self._initialise(defaults)
1274
1274
configspec = defaults['configspec']
1275
1275
self._original_configspec = configspec
1276
1276
self._load(infile, configspec)
1279
1279
def _load(self, infile, configspec):
1280
1280
if isinstance(infile, StringTypes):
1281
1281
self.filename = infile
1299
1299
elif isinstance(infile, (list, tuple)):
1300
1300
infile = list(infile)
1302
1302
elif isinstance(infile, dict):
1303
1303
# initialise self
1304
1304
# the Section class handles creating subsections
1305
1305
if isinstance(infile, ConfigObj):
1306
1306
# get a copy of our ConfigObj
1307
1307
infile = infile.dict()
1309
1309
for entry in infile:
1310
1310
self[entry] = infile[entry]
1311
1311
del self._errors
1313
1313
if configspec is not None:
1314
1314
self._handle_configspec(configspec)
1316
1316
self.configspec = None
1319
1319
elif getattr(infile, 'read', None) is not None:
1320
1320
# This supports file like objects
1321
1321
infile = infile.read() or []
1323
1323
# in case it's not an 8 bit encoding
1325
1325
raise TypeError('infile must be a filename, file like object, or list of lines.')
1328
1328
# don't do it for the empty ConfigObj
1329
1329
infile = self._handle_bom(infile)
1360
1360
# delete private attributes
1361
1361
del self._errors
1363
1363
if configspec is None:
1364
1364
self.configspec = None
1366
1366
self._handle_configspec(configspec)
1369
1369
def _initialise(self, options=None):
1370
1370
if options is None:
1371
1371
options = OPTION_DEFAULTS
1373
1373
# initialise a few variables
1374
1374
self.filename = None
1375
1375
self._errors = []
1386
1386
self.newlines = None
1387
1387
self.write_empty_values = options['write_empty_values']
1388
1388
self.unrepr = options['unrepr']
1390
1390
self.initial_comment = []
1391
1391
self.final_comment = []
1392
1392
self.configspec = {}
1394
1394
# Clear section attributes as well
1395
1395
Section._initialise(self)
1398
1398
def __repr__(self):
1399
return ('ConfigObj({%s})' %
1400
', '.join([('%s: %s' % (repr(key), repr(self[key])))
1399
return ('ConfigObj({%s})' %
1400
', '.join([('%s: %s' % (repr(key), repr(self[key])))
1401
1401
for key in (self.scalars + self.sections)]))
1404
1404
def _handle_bom(self, infile):
1406
1406
Handle any BOM, and decode if necessary.
1408
1408
If an encoding is specified, that *must* be used - but the BOM should
1409
1409
still be removed (and the BOM attribute set).
1411
1411
(If the encoding is wrongly specified, then a BOM for an alternative
1412
1412
encoding won't be discovered or removed.)
1414
1414
If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
1415
1415
removed. The BOM attribute will be set. UTF16 will be decoded to
1418
1418
NOTE: This method must not be called with an empty ``infile``.
1420
1420
Specifying the *wrong* encoding is likely to cause a
1421
1421
``UnicodeDecodeError``.
1423
1423
``infile`` must always be returned as a list of lines, but may be
1424
1424
passed in as a single string.
1429
1429
# the encoding specified doesn't have one
1431
1431
return self._decode(infile, self.encoding)
1433
1433
if isinstance(infile, (list, tuple)):
1434
1434
line = infile[0]
1451
1451
##self.BOM = True
1452
1452
# Don't need to remove BOM
1453
1453
return self._decode(infile, encoding)
1455
1455
# If we get this far, will *probably* raise a DecodeError
1456
1456
# As it doesn't appear to start with a BOM
1457
1457
return self._decode(infile, self.encoding)
1460
1460
BOM = BOM_SET[enc]
1461
1461
if not line.startswith(BOM):
1462
1462
return self._decode(infile, self.encoding)
1464
1464
newline = line[len(BOM):]
1467
1467
if isinstance(infile, (list, tuple)):
1468
1468
infile[0] = newline
1470
1470
infile = newline
1471
1471
self.BOM = True
1472
1472
return self._decode(infile, self.encoding)
1474
1474
# No encoding specified - so we need to check for UTF8/UTF16
1475
1475
for BOM, (encoding, final_encoding) in BOMS.items():
1476
1476
if not line.startswith(BOM):
1495
1495
# UTF16 - have to decode
1496
1496
return self._decode(infile, encoding)
1498
1498
# No BOM discovered and no encoding specified, just return
1499
1499
if isinstance(infile, StringTypes):
1500
1500
# infile read from a file will be a single string
1513
1513
def _decode(self, infile, encoding):
1515
1515
Decode infile to unicode. Using the specified encoding.
1517
1517
if is a string, it also needs converting to a list.
1519
1519
if isinstance(infile, StringTypes):
1573
1573
reset_comment = False
1574
1574
comment_list.append(line)
1577
1577
if not done_start:
1578
1578
# preserve initial comment
1579
1579
self.initial_comment = comment_list
1580
1580
comment_list = []
1581
1581
done_start = True
1583
1583
reset_comment = True
1584
1584
# first we check if it's a section marker
1585
1585
mat = self._sectionmarker.match(line)
1593
1593
self._handle_error("Cannot compute the section depth at line %s.",
1594
1594
NestingError, infile, cur_index)
1597
1597
if cur_depth < this_section.depth:
1598
1598
# the new section is dropping back to a previous level
1613
1613
self._handle_error("Section too nested at line %s.",
1614
1614
NestingError, infile, cur_index)
1616
1616
sect_name = self._unquote(sect_name)
1617
1617
if parent.has_key(sect_name):
1618
1618
self._handle_error('Duplicate section name at line %s.',
1619
1619
DuplicateError, infile, cur_index)
1622
1622
# create the new section
1623
1623
this_section = Section(
1739
1739
def _handle_error(self, text, ErrorClass, infile, cur_index):
1741
1741
Handle an error according to the error settings.
1743
1743
Either raise the error or store it.
1744
1744
The error will have occured at ``cur_index``
1765
1765
def _quote(self, value, multiline=True):
1767
1767
Return a safely quoted version of a value.
1769
1769
Raise a ConfigObjError if the value cannot be safely quoted.
1770
1770
If multiline is ``True`` (default) then use triple quotes
1773
1773
Don't quote values that don't need it.
1774
1774
Recursively quote members of a list and return a comma joined list.
1775
1775
Multiline is ``False`` for lists.
1776
1776
Obey list syntax for empty and single member lists.
1778
1778
If ``list_values=False`` then the value is only quoted if it contains
1779
1779
a ``\n`` (is multiline) or '#'.
1781
1781
If ``write_empty_values`` is set, and the value is an empty string, it
1782
1782
won't be quoted.
1785
1785
# Only if multiline is set, so that it is used for values not
1786
1786
# keys, and not values that are part of a list
1789
1789
if multiline and isinstance(value, (list, tuple)):
1805
1805
no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value
1806
1806
need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))
1807
1807
hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)
1808
1808
check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote
1810
1810
if check_for_single:
1811
1811
if not self.list_values:
1812
1812
# we don't quote if ``list_values=False``
1825
1825
# if value has '\n' or "'" *and* '"', it will need triple quotes
1826
1826
quot = self._get_triple_quote(value)
1828
1828
if quot == noquot and '#' in value and self.list_values:
1829
1829
quot = self._get_single_quote(value)
1831
1831
return quot % value
1834
1834
def _get_single_quote(self, value):
1835
1835
if ("'" in value) and ('"' in value):
1836
1836
raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
1844
1844
def _get_triple_quote(self, value):
1845
1845
if (value.find('"""') != -1) and (value.find("'''") != -1):
1846
1846
raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)
1847
1847
if value.find('"""') == -1:
1935
1935
def _handle_configspec(self, configspec):
1936
1936
"""Parse the configspec."""
1937
# FIXME: Should we check that the configspec was created with the
1937
# FIXME: Should we check that the configspec was created with the
1938
1938
# correct settings ? (i.e. ``list_values=False``)
1939
1939
if not isinstance(configspec, ConfigObj):
1959
1959
if len(configspec.sections) > 1:
1960
1960
# FIXME: can we supply any useful information here ?
1961
1961
raise RepeatSectionError()
1963
1963
if getattr(configspec, 'initial_comment', None) is not None:
1964
1964
section._configspec_initial_comment = configspec.initial_comment
1965
1965
section._configspec_final_comment = configspec.final_comment
1967
1967
section._configspec_BOM = configspec.BOM
1968
1968
section._configspec_newlines = configspec.newlines
1969
1969
section._configspec_indent_type = configspec.indent_type
1971
1971
for entry in configspec.scalars:
1972
1972
section._configspec_comments[entry] = configspec.comments[entry]
1973
1973
section._configspec_inline_comments[entry] = configspec.inline_comments[entry]
1974
1974
section.configspec[entry] = configspec[entry]
1975
1975
section._order.append(entry)
1977
1977
for entry in configspec.sections:
1978
1978
if entry == '__many__':
1981
1981
section._cs_section_comments[entry] = configspec.comments[entry]
1982
1982
section._cs_section_inline_comments[entry] = configspec.inline_comments[entry]
1983
1983
if not section.has_key(entry):
1991
1991
section_keys = configspec.sections
1992
1992
scalar_keys = configspec.scalars
1993
1993
except AttributeError:
1994
section_keys = [entry for entry in configspec
1994
section_keys = [entry for entry in configspec
1995
1995
if isinstance(configspec[entry], dict)]
1996
scalar_keys = [entry for entry in configspec
1996
scalar_keys = [entry for entry in configspec
1997
1997
if not isinstance(configspec[entry], dict)]
1999
1999
if '__many__' in section_keys and len(section_keys) > 1:
2000
2000
# FIXME: can we supply any useful information here ?
2001
2001
raise RepeatSectionError()
2005
2005
for entry in scalar_keys:
2057
2057
def write(self, outfile=None, section=None):
2059
2059
Write the current ConfigObj as a file
2061
2061
tekNico: FIXME: use StringIO instead of real files
2063
2063
>>> filename = a.filename
2064
2064
>>> a.filename = 'test.ini'
2097
2097
out.append(indent_string + comment_line)
2098
2098
this_entry = section[entry]
2099
2099
comment = self._handle_comment(section.inline_comments[entry])
2101
2101
if isinstance(this_entry, dict):
2103
2103
out.append(self._write_marker(
2139
2139
out[0] = BOM_UTF8 + out[0]
2142
2142
# Turn the list to a string, joined with correct newlines
2143
2143
newline = self.newlines or os.linesep
2144
2144
output = self._a_to_u(newline).join(out)
2164
2164
Test the ConfigObj against a configspec.
2166
2166
It uses the ``validator`` object from *validate.py*.
2168
2168
To run ``validate`` on the current ConfigObj, call: ::
2170
2170
test = config.validate(validator)
2172
2172
(Normally having previously passed in the configspec when the ConfigObj
2173
2173
was created - you can dynamically assign a dictionary of checks to the
2174
2174
``configspec`` attribute of a section though).
2176
2176
It returns ``True`` if everything passes, or a dictionary of
2177
2177
pass/fails (True/False). If every member of a subsection passes, it
2178
2178
will just have the value ``True``. (It also returns ``False`` if all
2181
2181
In addition, it converts the values from strings to their native
2182
2182
types if their checks pass (and ``stringify`` is set).
2184
2184
If ``preserve_errors`` is ``True`` (``False`` is default) then instead
2185
2185
of a marking a fail with a ``False``, it will preserve the actual
2186
2186
exception object. This can contain info about the reason for failure.
2187
2187
For example the ``VdtValueTooSmallError`` indicates that the value
2188
2188
supplied was too small. If a value (or section) is missing it will
2189
2189
still be marked as ``False``.
2191
2191
You must have the validate module to use ``preserve_errors=True``.
2193
2193
You can then use the ``flatten_errors`` function to turn your nested
2194
2194
results dictionary into a flattened list of failures - useful for
2195
2195
displaying meaningful error messages.
2212
2212
section.BOM = section._configspec_BOM
2213
2213
section.newlines = section._configspec_newlines
2214
2214
section.indent_type = section._configspec_indent_type
2216
2216
if '__many__' in section.configspec:
2217
2217
many = spec_section['__many__']
2218
2218
# dynamically assign the configspecs
2257
2257
ret_false = False
2258
2258
ret_true = False
2261
2261
section.default_values.pop(entry, None)
2262
except AttributeError:
2262
except AttributeError:
2263
2263
# For Python 2.2 compatibility
2265
2265
del section.default_values[entry]
2266
2266
except KeyError:
2269
2269
if getattr(validator, 'get_default_value', None) is not None:
2271
2271
section.default_values[entry] = validator.get_default_value(spec_section[entry])
2272
2272
except KeyError:
2276
2276
ret_false = False
2277
2277
out[entry] = True
2278
2278
if self.stringify or missing:
2346
2346
if entry == 'configspec':
2348
2348
current_options[entry] = getattr(self, entry)
2350
2350
configspec = self._original_configspec
2351
2351
current_options['configspec'] = configspec
2354
2354
self._initialise(current_options)
2355
2355
self._load(filename, configspec)
2359
2359
class SimpleVal(object):
2361
2361
A simple validator.
2362
2362
Can be used to check that all members expected are present.
2364
2364
To use it, provide a configspec with all your members in (the value given
2365
2365
will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
2366
2366
method of your ``ConfigObj``. ``validate`` will return ``True`` if all
2367
2367
members are present, or a dictionary with True/False meaning
2368
2368
present/missing. (Whole missing sections will be replaced with ``False``)
2371
2371
def __init__(self):
2372
2372
self.baseErrorClass = ConfigObjError
2374
2374
def check(self, check, member, missing=False):
2375
2375
"""A dummy check method, always returns the value unchanged."""
2384
2384
An example function that will turn a nested dictionary of results
2385
2385
(as returned by ``ConfigObj.validate``) into a flat list.
2387
2387
``cfg`` is the ConfigObj instance being checked, ``res`` is the results
2388
2388
dictionary returned by ``validate``.
2390
2390
(This is a recursive function, so you shouldn't use the ``levels`` or
2391
2391
``results`` arguments - they are used by the function.
2393
2393
Returns a list of keys that failed. Each member of the list is a tuple :
2396
2396
([list of sections...], key, result)
2398
2398
If ``validate`` was called with ``preserve_errors=False`` (the default)
2399
2399
then ``result`` will always be ``False``.
2401
2401
*list of sections* is a flattened list of sections that the key was found
2404
2404
If the section was missing then key will be ``None``.
2406
2406
If the value (or section) was missing then ``result`` will be ``False``.
2408
2408
If ``validate`` was called with ``preserve_errors=True`` and a value
2409
2409
was present, but failed the check, then ``result`` will be the exception
2410
2410
object returned. You can use this as a string that describes the failure.
2412
2412
For example *The value "3" is of the wrong type*.
2414
2414
>>> import validate
2415
2415
>>> vtor = validate.Validator()
2416
2416
>>> my_ini = '''