489
def __newobj__(cls, *args):
491
return cls.__new__(cls, *args)
493
495
class Section(dict):
495
497
A dictionary-like object that represents a section in a config file.
497
499
It does string interpolation if the 'interpolation' attribute
498
500
of the 'main' object is set to True.
500
502
Interpolation is tried first from this object, then from the 'DEFAULT'
501
503
section of this object, next from the parent and its 'DEFAULT' section,
502
504
and so on until the main object is reached.
504
506
A Section will behave like an ordered dictionary - following the
505
507
order of the ``scalars`` and ``sections`` attributes.
506
508
You can use this to change the order of members.
508
510
Iteration follows the order: scalars, then sections.
512
def __setstate__(self, state):
513
dict.update(self, state[0])
514
self.__dict__.update(state[1])
516
def __reduce__(self):
517
state = (dict(self), self.__dict__)
518
return (__newobj__, (self.__class__,), state)
521
513
def __init__(self, parent, depth, main, indict=None, name=None):
523
515
* parent is the section above
593
590
def __setitem__(self, key, value, unrepr=False):
595
592
Correctly set a value.
597
594
Making dictionary values Section instances.
598
595
(We have to special case 'Section' instances - which are also dicts)
600
597
Keys must be strings.
601
598
Values need only be strings (or lists of strings) if
602
599
``main.stringify`` is set.
604
``unrepr`` must be set when setting a value to a dictionary, without
601
`unrepr`` must be set when setting a value to a dictionary, without
605
602
creating a new sub-section.
607
if not isinstance(key, basestring):
604
if not isinstance(key, StringTypes):
608
605
raise ValueError('The key "%s" is not a string.' % key)
610
607
# add the comment
611
if key not in self.comments:
608
if not self.comments.has_key(key):
612
609
self.comments[key] = []
613
610
self.inline_comments[key] = ''
614
611
# remove the entry from defaults
863
860
call_on_sections=False, **keywargs):
865
862
Walk every member and call a function on the keyword and value.
867
864
Return a dictionary of the return values
869
866
If the function raises an exception, raise the errror
870
867
unless ``raise_errors=False``, in which case set the return value to
873
870
Any unrecognised keyword arguments you pass to walk, will be pased on
874
871
to the function you pass in.
876
873
Note: if ``call_on_sections`` is ``True`` then - on encountering a
877
874
subsection, *first* the function is called for the *whole* subsection,
878
875
and then recurses into it's members. This means your function must be
879
876
able to handle strings, dictionaries and lists. This allows you
880
877
to change the key of subsections as well as for ordinary members. The
881
878
return value when called on the whole subsection has to be discarded.
883
880
See the encode and decode methods for examples, including functions.
885
.. admonition:: caution
887
884
You can use ``walk`` to transform the names of members of a section
888
885
but you mustn't add or delete members.
890
887
>>> config = '''[XXXXsection]
891
888
... XXXXkey = XXXXvalue'''.splitlines()
892
889
>>> cfg = ConfigObj(config)
894
ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}})
891
{'XXXXsection': {'XXXXkey': 'XXXXvalue'}}
895
892
>>> def transform(section, key):
896
893
... val = section[key]
897
894
... newkey = key.replace('XXXX', 'CLIENT1')
944
def decode(self, encoding):
946
Decode all strings and values to unicode, using the specified encoding.
948
Works with subsections and list values.
950
Uses the ``walk`` method.
952
Testing ``encode`` and ``decode``.
954
>>> m.decode('ascii')
955
>>> def testuni(val):
956
... for entry in val:
957
... if not isinstance(entry, unicode):
958
... print >> sys.stderr, type(entry)
959
... raise AssertionError, 'decode failed.'
960
... if isinstance(val[entry], dict):
961
... testuni(val[entry])
962
... elif not isinstance(val[entry], unicode):
963
... raise AssertionError, 'decode failed.'
965
>>> m.encode('ascii')
969
warn('use of ``decode`` is deprecated.', DeprecationWarning)
970
def decode(section, key, encoding=encoding, warn=True):
973
if isinstance(val, (list, tuple)):
976
newval.append(entry.decode(encoding))
977
elif isinstance(val, dict):
980
newval = val.decode(encoding)
981
newkey = key.decode(encoding)
982
section.rename(key, newkey)
983
section[newkey] = newval
984
# using ``call_on_sections`` allows us to modify section names
985
self.walk(decode, call_on_sections=True)
988
def encode(self, encoding):
990
Encode all strings and values from unicode,
991
using the specified encoding.
993
Works with subsections and list values.
994
Uses the ``walk`` method.
996
warn('use of ``encode`` is deprecated.', DeprecationWarning)
997
def encode(section, key, encoding=encoding):
1000
if isinstance(val, (list, tuple)):
1003
newval.append(entry.encode(encoding))
1004
elif isinstance(val, dict):
1007
newval = val.encode(encoding)
1008
newkey = key.encode(encoding)
1009
section.rename(key, newkey)
1010
section[newkey] = newval
1011
self.walk(encode, call_on_sections=True)
1014
def istrue(self, key):
1015
"""A deprecated version of ``as_bool``."""
1016
warn('use of ``istrue`` is deprecated. Use ``as_bool`` method '
1017
'instead.', DeprecationWarning)
1018
return self.as_bool(key)
947
1021
def as_bool(self, key):
949
1023
Accepts a key as input. The corresponding value must be a string or
950
1024
the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
951
1025
retain compatibility with Python 2.2.
953
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
956
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
959
1033
``as_bool`` is not case sensitive.
961
1035
Any other input will raise a ``ValueError``.
963
1037
>>> a = ConfigObj()
964
1038
>>> a['a'] = 'fish'
965
1039
>>> a.as_bool('a')
1194
def __init__(self, infile=None, options=None, _inspec=False, **kwargs):
1246
def __init__(self, infile=None, options=None, **kwargs):
1196
1248
Parse a config file or create a config file object.
1198
1250
``ConfigObj(infile=None, options=None, **kwargs)``
1200
self._inspec = _inspec
1201
1252
# init the superclass
1202
1253
Section.__init__(self, self, 0, self)
1204
infile = infile or []
1205
options = dict(options or {})
1260
options = dict(options)
1207
1262
# keyword arguments take precedence over an options dictionary
1208
1263
options.update(kwargs)
1210
options['list_values'] = False
1212
1265
defaults = OPTION_DEFAULTS.copy()
1213
1266
# TODO: check the values too.
1214
1267
for entry in options:
1215
1268
if entry not in defaults:
1216
1269
raise TypeError('Unrecognised option "%s".' % entry)
1218
1271
# Add any explicit options to the defaults
1219
1272
defaults.update(options)
1220
1273
self._initialise(defaults)
1221
1274
configspec = defaults['configspec']
1222
1275
self._original_configspec = configspec
1223
1276
self._load(infile, configspec)
1226
1279
def _load(self, infile, configspec):
1227
if isinstance(infile, basestring):
1280
if isinstance(infile, StringTypes):
1228
1281
self.filename = infile
1229
1282
if os.path.isfile(infile):
1230
1283
h = open(infile, 'rb')
1246
1299
elif isinstance(infile, (list, tuple)):
1247
1300
infile = list(infile)
1249
1302
elif isinstance(infile, dict):
1250
1303
# initialise self
1251
1304
# the Section class handles creating subsections
1252
1305
if isinstance(infile, ConfigObj):
1253
1306
# get a copy of our ConfigObj
1254
1307
infile = infile.dict()
1256
1309
for entry in infile:
1257
1310
self[entry] = infile[entry]
1258
1311
del self._errors
1260
1313
if configspec is not None:
1261
1314
self._handle_configspec(configspec)
1263
1316
self.configspec = None
1266
elif getattr(infile, 'read', MISSING) is not MISSING:
1319
elif getattr(infile, 'read', None) is not None:
1267
1320
# This supports file like objects
1268
1321
infile = infile.read() or []
1269
1322
# needs splitting into lines - but needs doing *after* decoding
1270
1323
# in case it's not an 8 bit encoding
1272
1325
raise TypeError('infile must be a filename, file like object, or list of lines.')
1275
1328
# don't do it for the empty ConfigObj
1276
1329
infile = self._handle_bom(infile)
1333
1386
self.newlines = None
1334
1387
self.write_empty_values = options['write_empty_values']
1335
1388
self.unrepr = options['unrepr']
1337
1390
self.initial_comment = []
1338
1391
self.final_comment = []
1339
self.configspec = None
1342
self.list_values = False
1392
self.configspec = {}
1344
1394
# Clear section attributes as well
1345
1395
Section._initialise(self)
1348
1398
def __repr__(self):
1349
return ('ConfigObj({%s})' %
1350
', '.join([('%s: %s' % (repr(key), repr(self[key])))
1399
return ('ConfigObj({%s})' %
1400
', '.join([('%s: %s' % (repr(key), repr(self[key])))
1351
1401
for key in (self.scalars + self.sections)]))
1354
1404
def _handle_bom(self, infile):
1356
1406
Handle any BOM, and decode if necessary.
1358
1408
If an encoding is specified, that *must* be used - but the BOM should
1359
1409
still be removed (and the BOM attribute set).
1361
1411
(If the encoding is wrongly specified, then a BOM for an alternative
1362
1412
encoding won't be discovered or removed.)
1364
1414
If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
1365
1415
removed. The BOM attribute will be set. UTF16 will be decoded to
1368
1418
NOTE: This method must not be called with an empty ``infile``.
1370
1420
Specifying the *wrong* encoding is likely to cause a
1371
1421
``UnicodeDecodeError``.
1373
1423
``infile`` must always be returned as a list of lines, but may be
1374
1424
passed in as a single string.
1715
1765
def _quote(self, value, multiline=True):
1717
1767
Return a safely quoted version of a value.
1719
1769
Raise a ConfigObjError if the value cannot be safely quoted.
1720
1770
If multiline is ``True`` (default) then use triple quotes
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.
1773
Don't quote values that don't need it.
1774
Recursively quote members of a list and return a comma joined list.
1775
Multiline is ``False`` for lists.
1776
Obey list syntax for empty and single member lists.
1728
1778
If ``list_values=False`` then the value is only quoted if it contains
1729
a ``\\n`` (is multiline) or '#'.
1779
a ``\n`` (is multiline) or '#'.
1731
1781
If ``write_empty_values`` is set, and the value is an empty string, it
1732
1782
won't be quoted.
1888
1935
def _handle_configspec(self, configspec):
1889
1936
"""Parse the configspec."""
1890
# FIXME: Should we check that the configspec was created with the
1937
# FIXME: Should we check that the configspec was created with the
1891
1938
# correct settings ? (i.e. ``list_values=False``)
1892
1939
if not isinstance(configspec, ConfigObj):
1894
1941
configspec = ConfigObj(configspec,
1895
1942
raise_errors=True,
1896
1943
file_error=True,
1898
1945
except ConfigObjError, e:
1899
1946
# FIXME: Should these errors have a reference
1900
1947
# to the already parsed ConfigObj ?
1901
1948
raise ConfigspecError('Parsing configspec failed: %s' % e)
1902
1949
except IOError, e:
1903
1950
raise IOError('Reading configspec failed: %s' % e)
1905
self.configspec = configspec
1909
def _set_configspec(self, section, copy):
1911
Called by validate. Handles setting the configspec on subsections
1912
including sections to be validated by __many__
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
1952
self._set_configspec_value(configspec, self)
1955
def _set_configspec_value(self, configspec, section):
1956
"""Used to recursively set configspec values."""
1957
if '__many__' in configspec.sections:
1958
section.configspec['__many__'] = configspec['__many__']
1959
if len(configspec.sections) > 1:
1960
# FIXME: can we supply any useful information here ?
1961
raise RepeatSectionError()
1963
if getattr(configspec, 'initial_comment', None) is not None:
1964
section._configspec_initial_comment = configspec.initial_comment
1965
section._configspec_final_comment = configspec.final_comment
1966
section._configspec_encoding = configspec.encoding
1967
section._configspec_BOM = configspec.BOM
1968
section._configspec_newlines = configspec.newlines
1969
section._configspec_indent_type = configspec.indent_type
1971
for entry in configspec.scalars:
1972
section._configspec_comments[entry] = configspec.comments[entry]
1973
section._configspec_inline_comments[entry] = configspec.inline_comments[entry]
1974
section.configspec[entry] = configspec[entry]
1975
section._order.append(entry)
1921
1977
for entry in configspec.sections:
1922
1978
if entry == '__many__':
1924
if entry not in section:
1928
section.comments[entry] = configspec.comments.get(entry, [])
1929
section.inline_comments[entry] = configspec.inline_comments.get(entry, '')
1931
# Could be a scalar when we expect a section
1932
if isinstance(section[entry], Section):
1933
section[entry].configspec = configspec[entry]
1981
section._cs_section_comments[entry] = configspec.comments[entry]
1982
section._cs_section_inline_comments[entry] = configspec.inline_comments[entry]
1983
if not section.has_key(entry):
1985
self._set_configspec_value(configspec[entry], section[entry])
1988
def _handle_repeat(self, section, configspec):
1989
"""Dynamically assign configspec for repeated section."""
1991
section_keys = configspec.sections
1992
scalar_keys = configspec.scalars
1993
except AttributeError:
1994
section_keys = [entry for entry in configspec
1995
if isinstance(configspec[entry], dict)]
1996
scalar_keys = [entry for entry in configspec
1997
if not isinstance(configspec[entry], dict)]
1999
if '__many__' in section_keys and len(section_keys) > 1:
2000
# FIXME: can we supply any useful information here ?
2001
raise RepeatSectionError()
2005
for entry in scalar_keys:
2006
val = configspec[entry]
2007
scalars[entry] = val
2008
for entry in section_keys:
2009
val = configspec[entry]
2010
if entry == '__many__':
2011
scalars[entry] = val
2013
sections[entry] = val
2015
section.configspec = scalars
2016
for entry in sections:
2017
if not section.has_key(entry):
2019
self._handle_repeat(section[entry], sections[entry])
1936
2022
def _write_line(self, indent_string, entry, this_entry, comment):
2078
2164
Test the ConfigObj against a configspec.
2080
2166
It uses the ``validator`` object from *validate.py*.
2082
2168
To run ``validate`` on the current ConfigObj, call: ::
2084
2170
test = config.validate(validator)
2086
2172
(Normally having previously passed in the configspec when the ConfigObj
2087
2173
was created - you can dynamically assign a dictionary of checks to the
2088
2174
``configspec`` attribute of a section though).
2090
2176
It returns ``True`` if everything passes, or a dictionary of
2091
2177
pass/fails (True/False). If every member of a subsection passes, it
2092
2178
will just have the value ``True``. (It also returns ``False`` if all
2095
2181
In addition, it converts the values from strings to their native
2096
2182
types if their checks pass (and ``stringify`` is set).
2098
2184
If ``preserve_errors`` is ``True`` (``False`` is default) then instead
2099
2185
of a marking a fail with a ``False``, it will preserve the actual
2100
2186
exception object. This can contain info about the reason for failure.
2101
2187
For example the ``VdtValueTooSmallError`` indicates that the value
2102
2188
supplied was too small. If a value (or section) is missing it will
2103
2189
still be marked as ``False``.
2105
2191
You must have the validate module to use ``preserve_errors=True``.
2107
2193
You can then use the ``flatten_errors`` function to turn your nested
2108
2194
results dictionary into a flattened list of failures - useful for
2109
2195
displaying meaningful error messages.
2116
2202
# Which makes importing configobj faster
2117
2203
from validate import VdtMissingValue
2118
2204
self._vdtMissingValue = VdtMissingValue
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
2131
configspec = section.configspec
2132
self._set_configspec(section, copy)
2134
def validate_entry(entry, spec, val, missing, ret_true, ret_false):
2207
spec_section = section.configspec
2208
if copy and getattr(section, '_configspec_initial_comment', None) is not None:
2209
section.initial_comment = section._configspec_initial_comment
2210
section.final_comment = section._configspec_final_comment
2211
section.encoding = section._configspec_encoding
2212
section.BOM = section._configspec_BOM
2213
section.newlines = section._configspec_newlines
2214
section.indent_type = section._configspec_indent_type
2216
if '__many__' in section.configspec:
2217
many = spec_section['__many__']
2218
# dynamically assign the configspecs
2219
# for the sections below
2220
for entry in section.sections:
2221
self._handle_repeat(section[entry], many)
2226
order = [k for k in section._order if k in spec_section]
2227
order += [k for k in spec_section if k not in order]
2229
if entry == '__many__':
2231
if (not entry in section.scalars) or (entry in section.defaults):
2233
# or entries from defaults
2236
if copy and not entry in section.scalars:
2238
section.comments[entry] = (
2239
section._configspec_comments.get(entry, []))
2240
section.inline_comments[entry] = (
2241
section._configspec_inline_comments.get(entry, ''))
2245
val = section[entry]
2136
check = validator.check(spec,
2247
check = validator.check(spec_section[entry],
2138
2249
missing=missing
2179
2291
section[entry] = check
2180
2292
if not copy and missing and entry not in section.defaults:
2181
2293
section.defaults.append(entry)
2182
return ret_true, ret_false
2189
unvalidated = [k for k in section.scalars if k not in configspec]
2190
incorrect_sections = [k for k in configspec.sections if k in section.scalars]
2191
incorrect_scalars = [k for k in configspec.scalars if k in section.sections]
2193
for entry in configspec.scalars:
2194
if entry in ('__many__', '___many___'):
2198
if (not entry in section.scalars) or (entry in section.defaults):
2200
# or entries from defaults
2203
if copy and not entry in section.scalars:
2205
section.comments[entry] = (
2206
configspec.comments.get(entry, []))
2207
section.inline_comments[entry] = (
2208
configspec.inline_comments.get(entry, ''))
2212
val = section[entry]
2214
ret_true, ret_false = validate_entry(entry, configspec[entry], val,
2215
missing, ret_true, ret_false)
2218
if '__many__' in configspec.scalars:
2219
many = configspec['__many__']
2220
elif '___many___' in configspec.scalars:
2221
many = configspec['___many___']
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)
2229
for entry in incorrect_scalars:
2231
if not preserve_errors:
2235
msg = 'Value %r was provided as a section' % entry
2236
out[entry] = validator.baseErrorClass(msg)
2237
for entry in incorrect_sections:
2239
if not preserve_errors:
2243
msg = 'Section %r was provided as a single value' % entry
2244
out[entry] = validator.baseErrorClass(msg)
2246
2294
# Missing sections will have been created as empty ones when the
2247
2295
# configspec was read.
2248
2296
for entry in section.sections:
2249
2297
# FIXME: this means DEFAULT is not copied in copy mode
2250
2298
if section is self and entry == 'DEFAULT':
2252
if section[entry].configspec is None:
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])
2301
section.comments[entry] = section._cs_section_comments[entry]
2302
section.inline_comments[entry] = (
2303
section._cs_section_inline_comments[entry])
2304
check = self.validate(validator, preserve_errors=preserve_errors,
2305
copy=copy, section=section[entry])
2258
2306
out[entry] = check
2259
2307
if check == False:
2260
2308
ret_true = False
2298
2346
if entry == 'configspec':
2300
2348
current_options[entry] = getattr(self, entry)
2302
2350
configspec = self._original_configspec
2303
2351
current_options['configspec'] = configspec
2306
2354
self._initialise(current_options)
2307
2355
self._load(filename, configspec)
2311
2359
class SimpleVal(object):
2313
2361
A simple validator.
2314
2362
Can be used to check that all members expected are present.
2316
2364
To use it, provide a configspec with all your members in (the value given
2317
2365
will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
2318
2366
method of your ``ConfigObj``. ``validate`` will return ``True`` if all
2319
2367
members are present, or a dictionary with True/False meaning
2320
2368
present/missing. (Whole missing sections will be replaced with ``False``)
2323
2371
def __init__(self):
2324
2372
self.baseErrorClass = ConfigObjError
2326
2374
def check(self, check, member, missing=False):
2327
2375
"""A dummy check method, always returns the value unchanged."""
2336
2384
An example function that will turn a nested dictionary of results
2337
2385
(as returned by ``ConfigObj.validate``) into a flat list.
2339
2387
``cfg`` is the ConfigObj instance being checked, ``res`` is the results
2340
2388
dictionary returned by ``validate``.
2342
2390
(This is a recursive function, so you shouldn't use the ``levels`` or
2343
``results`` arguments - they are used by the function.)
2391
``results`` arguments - they are used by the function.
2345
2393
Returns a list of keys that failed. Each member of the list is a tuple :
2349
2396
([list of sections...], key, result)
2351
2398
If ``validate`` was called with ``preserve_errors=False`` (the default)
2352
2399
then ``result`` will always be ``False``.
2354
2401
*list of sections* is a flattened list of sections that the key was found
2357
If the section was missing (or a section was expected and a scalar provided
2358
- or vice-versa) then key will be ``None``.
2404
If the section was missing then key will be ``None``.
2360
2406
If the value (or section) was missing then ``result`` will be ``False``.
2362
2408
If ``validate`` was called with ``preserve_errors=True`` and a value
2363
2409
was present, but failed the check, then ``result`` will be the exception
2364
2410
object returned. You can use this as a string that describes the failure.
2366
2412
For example *The value "3" is of the wrong type*.
2368
2414
>>> import validate
2369
2415
>>> vtor = validate.Validator()
2370
2416
>>> my_ini = '''