summaryrefslogtreecommitdiff
path: root/Lib/configparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/configparser.py')
-rw-r--r--Lib/configparser.py54
1 files changed, 24 insertions, 30 deletions
diff --git a/Lib/configparser.py b/Lib/configparser.py
index e5536a0024..aebf8a0fb9 100644
--- a/Lib/configparser.py
+++ b/Lib/configparser.py
@@ -118,7 +118,8 @@ ConfigParser -- responsible for parsing a list of
between keys and values are surrounded by spaces.
"""
-from collections import MutableMapping, OrderedDict as _default_dict, _ChainMap
+from collections.abc import MutableMapping
+from collections import OrderedDict as _default_dict, ChainMap as _ChainMap
import functools
import io
import itertools
@@ -143,23 +144,6 @@ MAX_INTERPOLATION_DEPTH = 10
class Error(Exception):
"""Base class for ConfigParser exceptions."""
- def _get_message(self):
- """Getter for 'message'; needed only to override deprecation in
- BaseException.
- """
- return self.__message
-
- def _set_message(self, value):
- """Setter for 'message'; needed only to override deprecation in
- BaseException.
- """
- self.__message = value
-
- # BaseException.message has been deprecated since Python 2.6. To prevent
- # DeprecationWarning from popping up over this pre-existing attribute, use
- # a new property that takes lookup precedence.
- message = property(_get_message, _set_message)
-
def __init__(self, msg=''):
self.message = msg
Exception.__init__(self, msg)
@@ -190,7 +174,7 @@ class DuplicateSectionError(Error):
def __init__(self, section, source=None, lineno=None):
msg = [repr(section), " already exists"]
if source is not None:
- message = ["While reading from ", source]
+ message = ["While reading from ", repr(source)]
if lineno is not None:
message.append(" [line {0:2d}]".format(lineno))
message.append(": section ")
@@ -216,7 +200,7 @@ class DuplicateOptionError(Error):
msg = [repr(option), " in section ", repr(section),
" already exists"]
if source is not None:
- message = ["While reading from ", source]
+ message = ["While reading from ", repr(source)]
if lineno is not None:
message.append(" [line {0:2d}]".format(lineno))
message.append(": option ")
@@ -302,7 +286,7 @@ class ParsingError(Error):
raise ValueError("Required argument `source' not given.")
elif filename:
source = filename
- Error.__init__(self, 'Source contains parsing errors: %s' % source)
+ Error.__init__(self, 'Source contains parsing errors: %r' % source)
self.source = source
self.errors = []
self.args = (source, )
@@ -338,7 +322,7 @@ class MissingSectionHeaderError(ParsingError):
def __init__(self, filename, lineno, line):
Error.__init__(
self,
- 'File contains no section headers.\nfile: %s, line: %d\n%r' %
+ 'File contains no section headers.\nfile: %r, line: %d\n%r' %
(filename, lineno, line))
self.source = filename
self.lineno = lineno
@@ -455,7 +439,7 @@ class ExtendedInterpolation(Interpolation):
tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
if '$' in tmp_value:
raise ValueError("invalid interpolation syntax in %r at "
- "position %d" % (value, tmp_value.find('%')))
+ "position %d" % (value, tmp_value.find('$')))
return value
def _interpolate_some(self, parser, option, accum, rest, section, map,
@@ -959,7 +943,9 @@ class RawConfigParser(MutableMapping):
# XXX this is not atomic if read_dict fails at any point. Then again,
# no update method in configparser is atomic in this implementation.
- if key in self._sections:
+ if key == self.default_section:
+ self._defaults.clear()
+ elif key in self._sections:
self._sections[key].clear()
self.read_dict({key: value})
@@ -1005,18 +991,26 @@ class RawConfigParser(MutableMapping):
indent_level = 0
e = None # None, or an exception
for lineno, line in enumerate(fp, start=1):
- comment_start = None
+ comment_start = sys.maxsize
# strip inline comments
- for prefix in self._inline_comment_prefixes:
- index = line.find(prefix)
- if index == 0 or (index > 0 and line[index-1].isspace()):
- comment_start = index
- break
+ inline_prefixes = {p: -1 for p in self._inline_comment_prefixes}
+ while comment_start == sys.maxsize and inline_prefixes:
+ next_prefixes = {}
+ for prefix, index in inline_prefixes.items():
+ index = line.find(prefix, index+1)
+ if index == -1:
+ continue
+ next_prefixes[prefix] = index
+ if index == 0 or (index > 0 and line[index-1].isspace()):
+ comment_start = min(comment_start, index)
+ inline_prefixes = next_prefixes
# strip full line comments
for prefix in self._comment_prefixes:
if line.strip().startswith(prefix):
comment_start = 0
break
+ if comment_start == sys.maxsize:
+ comment_start = None
value = line[:comment_start].strip()
if not value:
if self._empty_lines_in_values: