250
254
This is the base class for all errors that ConfigObj raises.
251
255
It is a subclass of SyntaxError.
253
def __init__(self, message='', line_number=None, line=''):
257
def __init__(self, msg='', line_number=None, line=''):
255
259
self.line_number = line_number
256
SyntaxError.__init__(self, message)
261
SyntaxError.__init__(self, msg)
259
264
class NestingError(ConfigObjError):
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
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
616
613
self.defaults.remove(key)
618
615
if isinstance(value, Section):
616
if not self.has_key(key):
620
617
self.sections.append(key)
621
618
dict.__setitem__(self, key, value)
622
619
elif isinstance(value, dict) and not unrepr:
623
620
# First create the new depth level,
624
621
# then create the section
622
if not self.has_key(key):
626
623
self.sections.append(key)
627
624
new_depth = self.depth + 1
628
625
dict.__setitem__(
635
if not self.has_key(key):
639
636
self.scalars.append(key)
640
637
if not self.main.stringify:
641
if isinstance(value, basestring):
638
if isinstance(value, StringTypes):
643
640
elif isinstance(value, (list, tuple)):
644
641
for entry in value:
645
if not isinstance(entry, basestring):
642
if not isinstance(entry, StringTypes):
646
643
raise TypeError('Value is not a string "%s".' % entry)
648
645
raise TypeError('Value is not a string "%s".' % value)
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
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.
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.
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):
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