The default *dict_type* is :class:`dict`, since it now preserves
insertion order.
+ .. versionchanged:: 3.13
+ Raise a :exc:`MultilineContinuationError` when *allow_no_value* is
+ ``True``, and a key without a value is continued with an indented line.
+
.. method:: defaults()
Return a dictionary containing the instance-wide defaults.
The ``filename`` attribute and :meth:`!__init__` constructor argument were
removed. They have been available using the name ``source`` since 3.2.
+.. exception:: MultilineContinuationError
+
+ Exception raised when a key without a corresponding value is continued with
+ an indented line.
+
+ .. versionadded:: 3.13
+
.. rubric:: Footnotes
.. [1] Config parsers allow for heavy customization. If you are interested in
"NoOptionError", "InterpolationError", "InterpolationDepthError",
"InterpolationMissingOptionError", "InterpolationSyntaxError",
"ParsingError", "MissingSectionHeaderError",
+ "MultilineContinuationError",
"ConfigParser", "RawConfigParser",
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
"SectionProxy", "ConverterMapping",
self.args = (filename, lineno, line)
+class MultilineContinuationError(ParsingError):
+ """Raised when a key without value is followed by continuation line"""
+ def __init__(self, filename, lineno, line):
+ Error.__init__(
+ self,
+ "Key without value continued with an indented line.\n"
+ "file: %r, line: %d\n%r"
+ %(filename, lineno, line))
+ self.source = filename
+ self.lineno = lineno
+ self.line = line
+ self.args = (filename, lineno, line)
+
# 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.
cur_indent_level = first_nonspace.start() if first_nonspace else 0
if (cursect is not None and optname and
cur_indent_level > indent_level):
+ if cursect[optname] is None:
+ raise MultilineContinuationError(fpname, lineno, line)
cursect[optname].append(value)
# a section header or option header?
else:
"'[badbad'"
)
+ def test_keys_without_value_with_extra_whitespace(self):
+ lines = [
+ '[SECT]\n',
+ 'KEY1\n',
+ ' KEY2 = VAL2\n', # note the Space before the key!
+ ]
+ parser = configparser.ConfigParser(
+ comment_prefixes="",
+ allow_no_value=True,
+ strict=False,
+ delimiters=('=',),
+ interpolation=None,
+ )
+ with self.assertRaises(configparser.MultilineContinuationError) as dse:
+ parser.read_file(lines)
+ self.assertEqual(
+ str(dse.exception),
+ "Key without value continued with an indented line.\n"
+ "file: '<???>', line: 3\n"
+ "' KEY2 = VAL2\\n'"
+ )
+
+
+
class CoverageOneHundredTestCase(unittest.TestCase):
"""Covers edge cases in the codebase."""