add consistent support for the vars and default arguments on all
configuration parser classes (http://bugs.python.org/issue9421)
This commit is contained in:
parent
c934f32e0a
commit
cc645b9a59
|
@ -135,7 +135,7 @@ keys within each section.
|
|||
*empty_lines_in_values* were added.
|
||||
|
||||
|
||||
.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), strict=False, empty_lines_in_values=True)
|
||||
.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True)
|
||||
|
||||
Derived class of :class:`ConfigParser` that implements a sane variant of the
|
||||
magical interpolation feature. This implementation is more predictable as it
|
||||
|
@ -155,7 +155,7 @@ keys within each section.
|
|||
*empty_lines_in_values* were added.
|
||||
|
||||
|
||||
.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), strict=False, empty_lines_in_values=True)
|
||||
.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True)
|
||||
|
||||
Derived class of :class:`RawConfigParser` that implements the magical
|
||||
interpolation feature and adds optional arguments to the :meth:`get` and
|
||||
|
@ -366,39 +366,44 @@ RawConfigParser Objects
|
|||
Load configuration from a dictionary. Keys are section names, values are
|
||||
dictionaries with keys and values that should be present in the section. If
|
||||
the used dictionary type preserves order, sections and their keys will be
|
||||
added in order.
|
||||
added in order. Values are automatically converted to strings.
|
||||
|
||||
Optional argument *source* specifies a context-specific name of the
|
||||
dictionary passed. If not given, ``<dict>`` is used.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. method:: RawConfigParser.get(section, option, [vars, default])
|
||||
|
||||
.. method:: RawConfigParser.get(section, option)
|
||||
|
||||
Get an *option* value for the named *section*.
|
||||
Get an *option* value for the named *section*. If *vars* is provided, it
|
||||
must be a dictionary. The *option* is looked up in *vars* (if provided),
|
||||
*section*, and in *DEFAULTSECT* in that order. If the key is not found and
|
||||
*default* is provided, it is used as a fallback value. ``None`` can be
|
||||
provided as a *default* value.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.getint(section, option)
|
||||
.. method:: RawConfigParser.getint(section, option, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section* to an
|
||||
integer.
|
||||
A convenience method which coerces the *option* in the specified *section* to
|
||||
an integer. See :meth:`get` for explanation of *vars* and *default*.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.getfloat(section, option)
|
||||
.. method:: RawConfigParser.getfloat(section, option, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section* to a
|
||||
floating point number.
|
||||
A convenience method which coerces the *option* in the specified *section* to
|
||||
a floating point number. See :meth:`get` for explanation of *vars* and
|
||||
*default*.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.getboolean(section, option)
|
||||
.. method:: RawConfigParser.getboolean(section, option, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section* to a
|
||||
Boolean value. Note that the accepted values for the option are ``"1"``,
|
||||
``"yes"``, ``"true"``, and ``"on"``, which cause this method to return ``True``,
|
||||
and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which cause it to return
|
||||
``False``. These string values are checked in a case-insensitive manner. Any
|
||||
other value will cause it to raise :exc:`ValueError`.
|
||||
A convenience method which coerces the *option* in the specified *section*
|
||||
to a Boolean value. Note that the accepted values for the option are
|
||||
``"1"``, ``"yes"``, ``"true"``, and ``"on"``, which cause this method to
|
||||
return ``True``, and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which
|
||||
cause it to return ``False``. These string values are checked in
|
||||
a case-insensitive manner. Any other value will cause it to raise
|
||||
:exc:`ValueError`. See :meth:`get` for explanation of *vars* and *default*.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.items(section)
|
||||
|
@ -475,17 +480,44 @@ can, consider using :class:`SafeConfigParser` which adds validation and escaping
|
|||
for the interpolation.
|
||||
|
||||
|
||||
.. method:: ConfigParser.get(section, option, raw=False, vars=None)
|
||||
.. method:: ConfigParser.get(section, option, raw=False, [vars, default])
|
||||
|
||||
Get an *option* value for the named *section*. If *vars* is provided, it
|
||||
must be a dictionary. The *option* is looked up in *vars* (if provided),
|
||||
*section*, and in *defaults* in that order.
|
||||
*section*, and in *DEFAULTSECT* in that order. If the key is not found and
|
||||
*default* is provided, it is used as a fallback value. ``None`` can be
|
||||
provided as a *default* value.
|
||||
|
||||
All the ``'%'`` interpolations are expanded in the return values, unless the
|
||||
*raw* argument is true. Values for interpolation keys are looked up in the
|
||||
same manner as the option.
|
||||
|
||||
|
||||
.. method:: ConfigParser.getint(section, option, raw=False, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section* to
|
||||
an integer. See :meth:`get` for explanation of *raw*, *vars* and *default*.
|
||||
|
||||
|
||||
.. method:: ConfigParser.getfloat(section, option, raw=False, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section* to
|
||||
a floating point number. See :meth:`get` for explanation of *raw*, *vars*
|
||||
and *default*.
|
||||
|
||||
|
||||
.. method:: ConfigParser.getboolean(section, option, raw=False, [vars, default])
|
||||
|
||||
A convenience method which coerces the *option* in the specified *section*
|
||||
to a Boolean value. Note that the accepted values for the option are
|
||||
``"1"``, ``"yes"``, ``"true"``, and ``"on"``, which cause this method to
|
||||
return ``True``, and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which
|
||||
cause it to return ``False``. These string values are checked in
|
||||
a case-insensitive manner. Any other value will cause it to raise
|
||||
:exc:`ValueError`. See :meth:`get` for explanation of *raw*, *vars* and
|
||||
*default*.
|
||||
|
||||
|
||||
.. method:: ConfigParser.items(section, raw=False, vars=None)
|
||||
|
||||
Return a list of ``(name, value)`` pairs for each option in the given
|
||||
|
|
|
@ -24,9 +24,9 @@ ConfigParser -- responsible for parsing a list of
|
|||
|
||||
methods:
|
||||
|
||||
__init__(defaults=None, dict_type=_default_dict,
|
||||
delimiters=('=', ':'), comment_prefixes=('#', ';'),
|
||||
strict=False, empty_lines_in_values=True, allow_no_value=False):
|
||||
__init__(defaults=None, dict_type=_default_dict, allow_no_value=False,
|
||||
delimiters=('=', ':'), comment_prefixes=_COMPATIBLE,
|
||||
strict=False, empty_lines_in_values=True):
|
||||
Create the parser. When `defaults' is given, it is initialized into the
|
||||
dictionary or intrinsic defaults. The keys must be strings, the values
|
||||
must be appropriate for %()s string interpolation. Note that `__name__'
|
||||
|
@ -82,22 +82,24 @@ ConfigParser -- responsible for parsing a list of
|
|||
Read configuration from a dictionary. Keys are section names,
|
||||
values are dictionaries with keys and values that should be present
|
||||
in the section. If the used dictionary type preserves order, sections
|
||||
and their keys will be added in order.
|
||||
and their keys will be added in order. Values are automatically
|
||||
converted to strings.
|
||||
|
||||
get(section, option, raw=False, vars=None)
|
||||
get(section, option, raw=False, vars=None, default=_UNSET)
|
||||
Return a string value for the named option. All % interpolations are
|
||||
expanded in the return values, based on the defaults passed into the
|
||||
constructor and the DEFAULT section. Additional substitutions may be
|
||||
provided using the `vars' argument, which must be a dictionary whose
|
||||
contents override any pre-existing defaults.
|
||||
contents override any pre-existing defaults. If `option' is a key in
|
||||
`vars', the value from `vars' is used.
|
||||
|
||||
getint(section, options)
|
||||
getint(section, options, raw=False, vars=None, default=_UNSET)
|
||||
Like get(), but convert value to an integer.
|
||||
|
||||
getfloat(section, options)
|
||||
getfloat(section, options, raw=False, vars=None, default=_UNSET)
|
||||
Like get(), but convert value to a float.
|
||||
|
||||
getboolean(section, options)
|
||||
getboolean(section, options, raw=False, vars=None, default=_UNSET)
|
||||
Like get(), but convert value to a boolean (currently case
|
||||
insensitively defined as 0, false, no, off for False, and 1, true,
|
||||
yes, on for True). Returns False or True.
|
||||
|
@ -353,6 +355,17 @@ class MissingSectionHeaderError(ParsingError):
|
|||
self.args = (filename, lineno, line)
|
||||
|
||||
|
||||
# Used in parsers to denote selecting a backwards-compatible inline comment
|
||||
# character behavior (; and # are comments at the start of a line, but ; only
|
||||
# inline)
|
||||
_COMPATIBLE = object()
|
||||
|
||||
# Used in parser getters to indicate the default behaviour when a specific
|
||||
# option is not found it to raise an exception. Created to enable `None' as
|
||||
# a valid fallback value.
|
||||
_UNSET = object()
|
||||
|
||||
|
||||
class RawConfigParser:
|
||||
"""ConfigParser that does not do interpolation."""
|
||||
|
||||
|
@ -389,9 +402,9 @@ class RawConfigParser:
|
|||
OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE)
|
||||
# Compiled regular expression for matching leading whitespace in a line
|
||||
NONSPACECRE = re.compile(r"\S")
|
||||
# Select backwards-compatible inline comment character behavior
|
||||
# (; and # are comments at the start of a line, but ; only inline)
|
||||
_COMPATIBLE = object()
|
||||
# Possible boolean values in the configuration.
|
||||
BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
|
||||
'0': False, 'no': False, 'false': False, 'off': False}
|
||||
|
||||
def __init__(self, defaults=None, dict_type=_default_dict,
|
||||
allow_no_value=False, *, delimiters=('=', ':'),
|
||||
|
@ -414,7 +427,7 @@ class RawConfigParser:
|
|||
else:
|
||||
self._optcre = re.compile(self._OPT_TMPL.format(delim=d),
|
||||
re.VERBOSE)
|
||||
if comment_prefixes is self._COMPATIBLE:
|
||||
if comment_prefixes is _COMPATIBLE:
|
||||
self._startonly_comment_prefixes = ('#',)
|
||||
self._comment_prefixes = (';',)
|
||||
else:
|
||||
|
@ -528,6 +541,8 @@ class RawConfigParser:
|
|||
elements_added.add(section)
|
||||
for key, value in keys.items():
|
||||
key = self.optionxform(key)
|
||||
if value is not None:
|
||||
value = str(value)
|
||||
if self._strict and (section, key) in elements_added:
|
||||
raise DuplicateOptionError(section, key, source)
|
||||
elements_added.add((section, key))
|
||||
|
@ -542,21 +557,29 @@ class RawConfigParser:
|
|||
)
|
||||
self.read_file(fp, source=filename)
|
||||
|
||||
def get(self, section, option):
|
||||
opt = self.optionxform(option)
|
||||
if section not in self._sections:
|
||||
if section != DEFAULTSECT:
|
||||
raise NoSectionError(section)
|
||||
if opt in self._defaults:
|
||||
return self._defaults[opt]
|
||||
def get(self, section, option, vars=None, default=_UNSET):
|
||||
"""Get an option value for a given section.
|
||||
|
||||
If `vars' is provided, it must be a dictionary. The option is looked up
|
||||
in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
|
||||
If the key is not found and `default' is provided, it is used as
|
||||
a fallback value. `None' can be provided as a `default' value.
|
||||
"""
|
||||
try:
|
||||
d = self._unify_values(section, vars)
|
||||
except NoSectionError:
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
option = self.optionxform(option)
|
||||
try:
|
||||
return d[option]
|
||||
except KeyError:
|
||||
if default is _UNSET:
|
||||
raise NoOptionError(option, section)
|
||||
elif opt in self._sections[section]:
|
||||
return self._sections[section][opt]
|
||||
elif opt in self._defaults:
|
||||
return self._defaults[opt]
|
||||
else:
|
||||
raise NoOptionError(option, section)
|
||||
else:
|
||||
return default
|
||||
|
||||
def items(self, section):
|
||||
try:
|
||||
|
@ -571,23 +594,35 @@ class RawConfigParser:
|
|||
del d["__name__"]
|
||||
return d.items()
|
||||
|
||||
def _get(self, section, conv, option):
|
||||
return conv(self.get(section, option))
|
||||
def _get(self, section, conv, option, *args, **kwargs):
|
||||
return conv(self.get(section, option, *args, **kwargs))
|
||||
|
||||
def getint(self, section, option):
|
||||
return self._get(section, int, option)
|
||||
def getint(self, section, option, vars=None, default=_UNSET):
|
||||
try:
|
||||
return self._get(section, int, option, vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
def getfloat(self, section, option):
|
||||
return self._get(section, float, option)
|
||||
def getfloat(self, section, option, vars=None, default=_UNSET):
|
||||
try:
|
||||
return self._get(section, float, option, vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
|
||||
'0': False, 'no': False, 'false': False, 'off': False}
|
||||
|
||||
def getboolean(self, section, option):
|
||||
v = self.get(section, option)
|
||||
if v.lower() not in self._boolean_states:
|
||||
raise ValueError('Not a boolean: %s' % v)
|
||||
return self._boolean_states[v.lower()]
|
||||
def getboolean(self, section, option, vars=None, default=_UNSET):
|
||||
try:
|
||||
return self._get(section, self._convert_to_boolean, option, vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
def optionxform(self, optionstr):
|
||||
return optionstr.lower()
|
||||
|
@ -797,21 +832,10 @@ class RawConfigParser:
|
|||
exc.append(lineno, repr(line))
|
||||
return exc
|
||||
|
||||
|
||||
class ConfigParser(RawConfigParser):
|
||||
"""ConfigParser implementing interpolation."""
|
||||
|
||||
def get(self, section, option, raw=False, vars=None):
|
||||
"""Get an option value for a given section.
|
||||
|
||||
If `vars' is provided, it must be a dictionary. The option is looked up
|
||||
in `vars' (if provided), `section', and in `defaults' in that order.
|
||||
|
||||
All % interpolations are expanded in the return values, unless the
|
||||
optional argument `raw' is true. Values for interpolation keys are
|
||||
looked up in the same manner as the option.
|
||||
|
||||
The section DEFAULT is special.
|
||||
def _unify_values(self, section, vars):
|
||||
"""Create a copy of the DEFAULTSECT with values from a specific
|
||||
`section' and the `vars' dictionary. If provided, values in `vars'
|
||||
take precendence.
|
||||
"""
|
||||
d = self._defaults.copy()
|
||||
try:
|
||||
|
@ -822,18 +846,86 @@ class ConfigParser(RawConfigParser):
|
|||
# Update with the entry specific variables
|
||||
if vars:
|
||||
for key, value in vars.items():
|
||||
if value is not None:
|
||||
value = str(value)
|
||||
d[self.optionxform(key)] = value
|
||||
return d
|
||||
|
||||
def _convert_to_boolean(self, value):
|
||||
"""Return a boolean value translating from other types if necessary.
|
||||
"""
|
||||
if value.lower() not in self.BOOLEAN_STATES:
|
||||
raise ValueError('Not a boolean: %s' % value)
|
||||
return self.BOOLEAN_STATES[value.lower()]
|
||||
|
||||
|
||||
class ConfigParser(RawConfigParser):
|
||||
"""ConfigParser implementing interpolation."""
|
||||
|
||||
def get(self, section, option, raw=False, vars=None, default=_UNSET):
|
||||
"""Get an option value for a given section.
|
||||
|
||||
If `vars' is provided, it must be a dictionary. The option is looked up
|
||||
in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
|
||||
If the key is not found and `default' is provided, it is used as
|
||||
a fallback value. `None' can be provided as a `default' value.
|
||||
|
||||
All % interpolations are expanded in the return values, unless the
|
||||
optional argument `raw' is true. Values for interpolation keys are
|
||||
looked up in the same manner as the option.
|
||||
|
||||
The section DEFAULT is special.
|
||||
"""
|
||||
try:
|
||||
d = self._unify_values(section, vars)
|
||||
except NoSectionError:
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
option = self.optionxform(option)
|
||||
try:
|
||||
value = d[option]
|
||||
except KeyError:
|
||||
raise NoOptionError(option, section)
|
||||
if default is _UNSET:
|
||||
raise NoOptionError(option, section)
|
||||
else:
|
||||
return default
|
||||
|
||||
if raw or value is None:
|
||||
return value
|
||||
else:
|
||||
return self._interpolate(section, option, value, d)
|
||||
|
||||
def getint(self, section, option, raw=False, vars=None, default=_UNSET):
|
||||
try:
|
||||
return self._get(section, int, option, raw, vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
def getfloat(self, section, option, raw=False, vars=None, default=_UNSET):
|
||||
try:
|
||||
return self._get(section, float, option, raw, vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
def getboolean(self, section, option, raw=False, vars=None,
|
||||
default=_UNSET):
|
||||
try:
|
||||
return self._get(section, self._convert_to_boolean, option, raw,
|
||||
vars)
|
||||
except (NoSectionError, NoOptionError):
|
||||
if default is _UNSET:
|
||||
raise
|
||||
else:
|
||||
return default
|
||||
|
||||
def items(self, section, raw=False, vars=None):
|
||||
"""Return a list of (name, value) tuples for each option in a section.
|
||||
|
||||
|
|
|
@ -62,9 +62,10 @@ class BasicTestCase(CfgParserTestCaseClass):
|
|||
'Spaces',
|
||||
'Spacey Bar',
|
||||
'Spacey Bar From The Beginning',
|
||||
'Types',
|
||||
]
|
||||
if self.allow_no_value:
|
||||
E.append(r'NoValue')
|
||||
E.append('NoValue')
|
||||
E.sort()
|
||||
eq = self.assertEqual
|
||||
eq(L, E)
|
||||
|
@ -80,9 +81,43 @@ class BasicTestCase(CfgParserTestCaseClass):
|
|||
eq(cf.get('Commented Bar', 'baz'), 'qwe')
|
||||
eq(cf.get('Spaces', 'key with spaces'), 'value')
|
||||
eq(cf.get('Spaces', 'another with spaces'), 'splat!')
|
||||
eq(cf.getint('Types', 'int'), 42)
|
||||
eq(cf.get('Types', 'int'), "42")
|
||||
self.assertAlmostEqual(cf.getfloat('Types', 'float'), 0.44)
|
||||
eq(cf.get('Types', 'float'), "0.44")
|
||||
eq(cf.getboolean('Types', 'boolean'), False)
|
||||
if self.allow_no_value:
|
||||
eq(cf.get('NoValue', 'option-without-value'), None)
|
||||
|
||||
# test vars= and default=
|
||||
eq(cf.get('Foo Bar', 'foo', default='baz'), 'bar')
|
||||
eq(cf.get('Foo Bar', 'foo', vars={'foo': 'baz'}), 'baz')
|
||||
with self.assertRaises(configparser.NoSectionError):
|
||||
cf.get('No Such Foo Bar', 'foo')
|
||||
with self.assertRaises(configparser.NoOptionError):
|
||||
cf.get('Foo Bar', 'no-such-foo')
|
||||
eq(cf.get('No Such Foo Bar', 'foo', default='baz'), 'baz')
|
||||
eq(cf.get('Foo Bar', 'no-such-foo', default='baz'), 'baz')
|
||||
eq(cf.get('Spacey Bar', 'foo', default=None), 'bar')
|
||||
eq(cf.get('No Such Spacey Bar', 'foo', default=None), None)
|
||||
eq(cf.getint('Types', 'int', default=18), 42)
|
||||
eq(cf.getint('Types', 'no-such-int', default=18), 18)
|
||||
eq(cf.getint('Types', 'no-such-int', default="18"), "18") # sic!
|
||||
self.assertAlmostEqual(cf.getfloat('Types', 'float',
|
||||
default=0.0), 0.44)
|
||||
self.assertAlmostEqual(cf.getfloat('Types', 'no-such-float',
|
||||
default=0.0), 0.0)
|
||||
eq(cf.getfloat('Types', 'no-such-float', default="0.0"), "0.0") # sic!
|
||||
eq(cf.getboolean('Types', 'boolean', default=True), False)
|
||||
eq(cf.getboolean('Types', 'no-such-boolean', default="yes"),
|
||||
"yes") # sic!
|
||||
eq(cf.getboolean('Types', 'no-such-boolean', default=True), True)
|
||||
eq(cf.getboolean('No Such Types', 'boolean', default=True), True)
|
||||
if self.allow_no_value:
|
||||
eq(cf.get('NoValue', 'option-without-value', default=False), None)
|
||||
eq(cf.get('NoValue', 'no-such-option-without-value',
|
||||
default=False), False)
|
||||
|
||||
self.assertNotIn('__name__', cf.options("Foo Bar"),
|
||||
'__name__ "option" should not be exposed by the API!')
|
||||
|
||||
|
@ -127,6 +162,10 @@ foo[de]{0[0]}Deutsch
|
|||
[Spaces]
|
||||
key with spaces {0[1]} value
|
||||
another with spaces {0[0]} splat!
|
||||
[Types]
|
||||
int {0[1]} 42
|
||||
float {0[0]} 0.44
|
||||
boolean {0[0]} NO
|
||||
""".format(self.delimiters, self.comment_prefixes)
|
||||
if self.allow_no_value:
|
||||
config_string += (
|
||||
|
@ -194,7 +233,12 @@ another with spaces {0[0]} splat!
|
|||
"Spaces": {
|
||||
"key with spaces": "value",
|
||||
"another with spaces": "splat!",
|
||||
}
|
||||
},
|
||||
"Types": {
|
||||
"int": 42,
|
||||
"float": 0.44,
|
||||
"boolean": False,
|
||||
},
|
||||
}
|
||||
if self.allow_no_value:
|
||||
config.update({
|
||||
|
@ -732,8 +776,11 @@ class SafeConfigParserTestCaseTrickyFile(CfgParserTestCaseClass):
|
|||
'no values here',
|
||||
'tricky interpolation',
|
||||
'more interpolation'])
|
||||
#self.assertEqual(cf.getint('DEFAULT', 'go', vars={'interpolate': '-1'}),
|
||||
# -1)
|
||||
self.assertEqual(cf.getint('DEFAULT', 'go',
|
||||
vars={'interpolate': '-1'}), -1)
|
||||
with self.assertRaises(ValueError):
|
||||
# no interpolation will happen
|
||||
cf.getint('DEFAULT', 'go', raw=True, vars={'interpolate': '-1'})
|
||||
self.assertEqual(len(cf.get('strange', 'other').split('\n')), 4)
|
||||
self.assertEqual(len(cf.get('corruption', 'value').split('\n')), 10)
|
||||
longname = 'yeah, sections can be indented as well'
|
||||
|
@ -808,7 +855,7 @@ class SortedTestCase(RawConfigParserTestCase):
|
|||
|
||||
class CompatibleTestCase(CfgParserTestCaseClass):
|
||||
config_class = configparser.RawConfigParser
|
||||
comment_prefixes = configparser.RawConfigParser._COMPATIBLE
|
||||
comment_prefixes = configparser._COMPATIBLE
|
||||
|
||||
def test_comment_handling(self):
|
||||
config_string = textwrap.dedent("""\
|
||||
|
|
|
@ -158,6 +158,9 @@ Library
|
|||
- Issue #9753: Fixed socket.dup, which did not always work correctly
|
||||
on Windows.
|
||||
|
||||
- Issue #9421: Made the get<type> methods consistently accept the vars
|
||||
and default arguments on all parser classes.
|
||||
|
||||
- Issue #7005: Fixed output of None values for RawConfigParser.write and
|
||||
ConfigParser.write.
|
||||
|
||||
|
|
Loading…
Reference in New Issue