1"""Configuration file parser.
2
3A configuration file consists of sections, lead by a "[section]" header,
4and followed by "name: value" entries, with continuations and such in
5the style of RFC 822.
6
7Intrinsic defaults can be specified by passing them into the
8ConfigParser constructor as a dictionary.
9
10class:
11
12ConfigParser -- responsible for parsing a list of
13                    configuration files, and managing the parsed database.
14
15    methods:
16
17    __init__(defaults=None, dict_type=_default_dict, allow_no_value=False,
18             delimiters=('=', ':'), comment_prefixes=('#', ';'),
19             inline_comment_prefixes=None, strict=True,
20             empty_lines_in_values=True, default_section='DEFAULT',
21             interpolation=<unset>, converters=<unset>):
22        Create the parser. When `defaults' is given, it is initialized into the
23        dictionary or intrinsic defaults. The keys must be strings, the values
24        must be appropriate for %()s string interpolation.
25
26        When `dict_type' is given, it will be used to create the dictionary
27        objects for the list of sections, for the options within a section, and
28        for the default values.
29
30        When `delimiters' is given, it will be used as the set of substrings
31        that divide keys from values.
32
33        When `comment_prefixes' is given, it will be used as the set of
34        substrings that prefix comments in empty lines. Comments can be
35        indented.
36
37        When `inline_comment_prefixes' is given, it will be used as the set of
38        substrings that prefix comments in non-empty lines.
39
40        When `strict` is True, the parser won't allow for any section or option
41        duplicates while reading from a single source (file, string or
42        dictionary). Default is True.
43
44        When `empty_lines_in_values' is False (default: True), each empty line
45        marks the end of an option. Otherwise, internal empty lines of
46        a multiline option are kept as part of the value.
47
48        When `allow_no_value' is True (default: False), options without
49        values are accepted; the value presented for these is None.
50
51        When `default_section' is given, the name of the special section is
52        named accordingly. By default it is called ``"DEFAULT"`` but this can
53        be customized to point to any other valid section name. Its current
54        value can be retrieved using the ``parser_instance.default_section``
55        attribute and may be modified at runtime.
56
57        When `interpolation` is given, it should be an Interpolation subclass
58        instance. It will be used as the handler for option value
59        pre-processing when using getters. RawConfigParser objects don't do
60        any sort of interpolation, whereas ConfigParser uses an instance of
61        BasicInterpolation. The library also provides a ``zc.buildbot``
62        inspired ExtendedInterpolation implementation.
63
64        When `converters` is given, it should be a dictionary where each key
65        represents the name of a type converter and each value is a callable
66        implementing the conversion from string to the desired datatype. Every
67        converter gets its corresponding get*() method on the parser object and
68        section proxies.
69
70    sections()
71        Return all the configuration section names, sans DEFAULT.
72
73    has_section(section)
74        Return whether the given section exists.
75
76    has_option(section, option)
77        Return whether the given option exists in the given section.
78
79    options(section)
80        Return list of configuration options for the named section.
81
82    read(filenames, encoding=None)
83        Read and parse the iterable of named configuration files, given by
84        name.  A single filename is also allowed.  Non-existing files
85        are ignored.  Return list of successfully read files.
86
87    read_file(f, filename=None)
88        Read and parse one configuration file, given as a file object.
89        The filename defaults to f.name; it is only used in error
90        messages (if f has no `name' attribute, the string `<???>' is used).
91
92    read_string(string)
93        Read configuration from a given string.
94
95    read_dict(dictionary)
96        Read configuration from a dictionary. Keys are section names,
97        values are dictionaries with keys and values that should be present
98        in the section. If the used dictionary type preserves order, sections
99        and their keys will be added in order. Values are automatically
100        converted to strings.
101
102    get(section, option, raw=False, vars=None, fallback=_UNSET)
103        Return a string value for the named option.  All % interpolations are
104        expanded in the return values, based on the defaults passed into the
105        constructor and the DEFAULT section.  Additional substitutions may be
106        provided using the `vars' argument, which must be a dictionary whose
107        contents override any pre-existing defaults. If `option' is a key in
108        `vars', the value from `vars' is used.
109
110    getint(section, options, raw=False, vars=None, fallback=_UNSET)
111        Like get(), but convert value to an integer.
112
113    getfloat(section, options, raw=False, vars=None, fallback=_UNSET)
114        Like get(), but convert value to a float.
115
116    getboolean(section, options, raw=False, vars=None, fallback=_UNSET)
117        Like get(), but convert value to a boolean (currently case
118        insensitively defined as 0, false, no, off for False, and 1, true,
119        yes, on for True).  Returns False or True.
120
121    items(section=_UNSET, raw=False, vars=None)
122        If section is given, return a list of tuples with (name, value) for
123        each option in the section. Otherwise, return a list of tuples with
124        (section_name, section_proxy) for each section, including DEFAULTSECT.
125
126    remove_section(section)
127        Remove the given file section and all its options.
128
129    remove_option(section, option)
130        Remove the given option from the given section.
131
132    set(section, option, value)
133        Set the given option.
134
135    write(fp, space_around_delimiters=True)
136        Write the configuration state in .ini format. If
137        `space_around_delimiters' is True (the default), delimiters
138        between keys and values are surrounded by spaces.
139"""
140
141from collections.abc import MutableMapping
142from collections import ChainMap as _ChainMap
143import functools
144import io
145import itertools
146import os
147import re
148import sys
149import warnings
150
151__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
152           "NoOptionError", "InterpolationError", "InterpolationDepthError",
153           "InterpolationMissingOptionError", "InterpolationSyntaxError",
154           "ParsingError", "MissingSectionHeaderError",
155           "ConfigParser", "SafeConfigParser", "RawConfigParser",
156           "Interpolation", "BasicInterpolation",  "ExtendedInterpolation",
157           "LegacyInterpolation", "SectionProxy", "ConverterMapping",
158           "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
159
160_default_dict = dict
161DEFAULTSECT = "DEFAULT"
162
163MAX_INTERPOLATION_DEPTH = 10
164
165
166
167# exception classes
168class Error(Exception):
169    """Base class for ConfigParser exceptions."""
170
171    def __init__(self, msg=''):
172        self.message = msg
173        Exception.__init__(self, msg)
174
175    def __repr__(self):
176        return self.message
177
178    __str__ = __repr__
179
180
181class NoSectionError(Error):
182    """Raised when no section matches a requested option."""
183
184    def __init__(self, section):
185        Error.__init__(self, 'No section: %r' % (section,))
186        self.section = section
187        self.args = (section, )
188
189
190class DuplicateSectionError(Error):
191    """Raised when a section is repeated in an input source.
192
193    Possible repetitions that raise this exception are: multiple creation
194    using the API or in strict parsers when a section is found more than once
195    in a single input file, string or dictionary.
196    """
197
198    def __init__(self, section, source=None, lineno=None):
199        msg = [repr(section), " already exists"]
200        if source is not None:
201            message = ["While reading from ", repr(source)]
202            if lineno is not None:
203                message.append(" [line {0:2d}]".format(lineno))
204            message.append(": section ")
205            message.extend(msg)
206            msg = message
207        else:
208            msg.insert(0, "Section ")
209        Error.__init__(self, "".join(msg))
210        self.section = section
211        self.source = source
212        self.lineno = lineno
213        self.args = (section, source, lineno)
214
215
216class DuplicateOptionError(Error):
217    """Raised by strict parsers when an option is repeated in an input source.
218
219    Current implementation raises this exception only when an option is found
220    more than once in a single file, string or dictionary.
221    """
222
223    def __init__(self, section, option, source=None, lineno=None):
224        msg = [repr(option), " in section ", repr(section),
225               " already exists"]
226        if source is not None:
227            message = ["While reading from ", repr(source)]
228            if lineno is not None:
229                message.append(" [line {0:2d}]".format(lineno))
230            message.append(": option ")
231            message.extend(msg)
232            msg = message
233        else:
234            msg.insert(0, "Option ")
235        Error.__init__(self, "".join(msg))
236        self.section = section
237        self.option = option
238        self.source = source
239        self.lineno = lineno
240        self.args = (section, option, source, lineno)
241
242
243class NoOptionError(Error):
244    """A requested option was not found."""
245
246    def __init__(self, option, section):
247        Error.__init__(self, "No option %r in section: %r" %
248                       (option, section))
249        self.option = option
250        self.section = section
251        self.args = (option, section)
252
253
254class InterpolationError(Error):
255    """Base class for interpolation-related exceptions."""
256
257    def __init__(self, option, section, msg):
258        Error.__init__(self, msg)
259        self.option = option
260        self.section = section
261        self.args = (option, section, msg)
262
263
264class InterpolationMissingOptionError(InterpolationError):
265    """A string substitution required a setting which was not available."""
266
267    def __init__(self, option, section, rawval, reference):
268        msg = ("Bad value substitution: option {!r} in section {!r} contains "
269               "an interpolation key {!r} which is not a valid option name. "
270               "Raw value: {!r}".format(option, section, reference, rawval))
271        InterpolationError.__init__(self, option, section, msg)
272        self.reference = reference
273        self.args = (option, section, rawval, reference)
274
275
276class InterpolationSyntaxError(InterpolationError):
277    """Raised when the source text contains invalid syntax.
278
279    Current implementation raises this exception when the source text into
280    which substitutions are made does not conform to the required syntax.
281    """
282
283
284class InterpolationDepthError(InterpolationError):
285    """Raised when substitutions are nested too deeply."""
286
287    def __init__(self, option, section, rawval):
288        msg = ("Recursion limit exceeded in value substitution: option {!r} "
289               "in section {!r} contains an interpolation key which "
290               "cannot be substituted in {} steps. Raw value: {!r}"
291               "".format(option, section, MAX_INTERPOLATION_DEPTH,
292                         rawval))
293        InterpolationError.__init__(self, option, section, msg)
294        self.args = (option, section, rawval)
295
296
297class ParsingError(Error):
298    """Raised when a configuration file does not follow legal syntax."""
299
300    def __init__(self, source=None, filename=None):
301        # Exactly one of `source'/`filename' arguments has to be given.
302        # `filename' kept for compatibility.
303        if filename and source:
304            raise ValueError("Cannot specify both `filename' and `source'. "
305                             "Use `source'.")
306        elif not filename and not source:
307            raise ValueError("Required argument `source' not given.")
308        elif filename:
309            source = filename
310        Error.__init__(self, 'Source contains parsing errors: %r' % source)
311        self.source = source
312        self.errors = []
313        self.args = (source, )
314
315    @property
316    def filename(self):
317        """Deprecated, use `source'."""
318        warnings.warn(
319            "The 'filename' attribute will be removed in future versions.  "
320            "Use 'source' instead.",
321            DeprecationWarning, stacklevel=2
322        )
323        return self.source
324
325    @filename.setter
326    def filename(self, value):
327        """Deprecated, user `source'."""
328        warnings.warn(
329            "The 'filename' attribute will be removed in future versions.  "
330            "Use 'source' instead.",
331            DeprecationWarning, stacklevel=2
332        )
333        self.source = value
334
335    def append(self, lineno, line):
336        self.errors.append((lineno, line))
337        self.message += '\n\t[line %2d]: %s' % (lineno, line)
338
339
340class MissingSectionHeaderError(ParsingError):
341    """Raised when a key-value pair is found before any section header."""
342
343    def __init__(self, filename, lineno, line):
344        Error.__init__(
345            self,
346            'File contains no section headers.\nfile: %r, line: %d\n%r' %
347            (filename, lineno, line))
348        self.source = filename
349        self.lineno = lineno
350        self.line = line
351        self.args = (filename, lineno, line)
352
353
354# Used in parser getters to indicate the default behaviour when a specific
355# option is not found it to raise an exception. Created to enable `None' as
356# a valid fallback value.
357_UNSET = object()
358
359
360class Interpolation:
361    """Dummy interpolation that passes the value through with no changes."""
362
363    def before_get(self, parser, section, option, value, defaults):
364        return value
365
366    def before_set(self, parser, section, option, value):
367        return value
368
369    def before_read(self, parser, section, option, value):
370        return value
371
372    def before_write(self, parser, section, option, value):
373        return value
374
375
376class BasicInterpolation(Interpolation):
377    """Interpolation as implemented in the classic ConfigParser.
378
379    The option values can contain format strings which refer to other values in
380    the same section, or values in the special default section.
381
382    For example:
383
384        something: %(dir)s/whatever
385
386    would resolve the "%(dir)s" to the value of dir.  All reference
387    expansions are done late, on demand. If a user needs to use a bare % in
388    a configuration file, she can escape it by writing %%. Other % usage
389    is considered a user error and raises `InterpolationSyntaxError'."""
390
391    _KEYCRE = re.compile(r"%\(([^)]+)\)s")
392
393    def before_get(self, parser, section, option, value, defaults):
394        L = []
395        self._interpolate_some(parser, option, L, value, section, defaults, 1)
396        return ''.join(L)
397
398    def before_set(self, parser, section, option, value):
399        tmp_value = value.replace('%%', '') # escaped percent signs
400        tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
401        if '%' in tmp_value:
402            raise ValueError("invalid interpolation syntax in %r at "
403                             "position %d" % (value, tmp_value.find('%')))
404        return value
405
406    def _interpolate_some(self, parser, option, accum, rest, section, map,
407                          depth):
408        rawval = parser.get(section, option, raw=True, fallback=rest)
409        if depth > MAX_INTERPOLATION_DEPTH:
410            raise InterpolationDepthError(option, section, rawval)
411        while rest:
412            p = rest.find("%")
413            if p < 0:
414                accum.append(rest)
415                return
416            if p > 0:
417                accum.append(rest[:p])
418                rest = rest[p:]
419            # p is no longer used
420            c = rest[1:2]
421            if c == "%":
422                accum.append("%")
423                rest = rest[2:]
424            elif c == "(":
425                m = self._KEYCRE.match(rest)
426                if m is None:
427                    raise InterpolationSyntaxError(option, section,
428                        "bad interpolation variable reference %r" % rest)
429                var = parser.optionxform(m.group(1))
430                rest = rest[m.end():]
431                try:
432                    v = map[var]
433                except KeyError:
434                    raise InterpolationMissingOptionError(
435                        option, section, rawval, var) from None
436                if "%" in v:
437                    self._interpolate_some(parser, option, accum, v,
438                                           section, map, depth + 1)
439                else:
440                    accum.append(v)
441            else:
442                raise InterpolationSyntaxError(
443                    option, section,
444                    "'%%' must be followed by '%%' or '(', "
445                    "found: %r" % (rest,))
446
447
448class ExtendedInterpolation(Interpolation):
449    """Advanced variant of interpolation, supports the syntax used by
450    `zc.buildout'. Enables interpolation between sections."""
451
452    _KEYCRE = re.compile(r"\$\{([^}]+)\}")
453
454    def before_get(self, parser, section, option, value, defaults):
455        L = []
456        self._interpolate_some(parser, option, L, value, section, defaults, 1)
457        return ''.join(L)
458
459    def before_set(self, parser, section, option, value):
460        tmp_value = value.replace('$$', '') # escaped dollar signs
461        tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
462        if '$' in tmp_value:
463            raise ValueError("invalid interpolation syntax in %r at "
464                             "position %d" % (value, tmp_value.find('$')))
465        return value
466
467    def _interpolate_some(self, parser, option, accum, rest, section, map,
468                          depth):
469        rawval = parser.get(section, option, raw=True, fallback=rest)
470        if depth > MAX_INTERPOLATION_DEPTH:
471            raise InterpolationDepthError(option, section, rawval)
472        while rest:
473            p = rest.find("$")
474            if p < 0:
475                accum.append(rest)
476                return
477            if p > 0:
478                accum.append(rest[:p])
479                rest = rest[p:]
480            # p is no longer used
481            c = rest[1:2]
482            if c == "$":
483                accum.append("$")
484                rest = rest[2:]
485            elif c == "{":
486                m = self._KEYCRE.match(rest)
487                if m is None:
488                    raise InterpolationSyntaxError(option, section,
489                        "bad interpolation variable reference %r" % rest)
490                path = m.group(1).split(':')
491                rest = rest[m.end():]
492                sect = section
493                opt = option
494                try:
495                    if len(path) == 1:
496                        opt = parser.optionxform(path[0])
497                        v = map[opt]
498                    elif len(path) == 2:
499                        sect = path[0]
500                        opt = parser.optionxform(path[1])
501                        v = parser.get(sect, opt, raw=True)
502                    else:
503                        raise InterpolationSyntaxError(
504                            option, section,
505                            "More than one ':' found: %r" % (rest,))
506                except (KeyError, NoSectionError, NoOptionError):
507                    raise InterpolationMissingOptionError(
508                        option, section, rawval, ":".join(path)) from None
509                if "$" in v:
510                    self._interpolate_some(parser, opt, accum, v, sect,
511                                           dict(parser.items(sect, raw=True)),
512                                           depth + 1)
513                else:
514                    accum.append(v)
515            else:
516                raise InterpolationSyntaxError(
517                    option, section,
518                    "'$' must be followed by '$' or '{', "
519                    "found: %r" % (rest,))
520
521
522class LegacyInterpolation(Interpolation):
523    """Deprecated interpolation used in old versions of ConfigParser.
524    Use BasicInterpolation or ExtendedInterpolation instead."""
525
526    _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
527
528    def before_get(self, parser, section, option, value, vars):
529        rawval = value
530        depth = MAX_INTERPOLATION_DEPTH
531        while depth:                    # Loop through this until it's done
532            depth -= 1
533            if value and "%(" in value:
534                replace = functools.partial(self._interpolation_replace,
535                                            parser=parser)
536                value = self._KEYCRE.sub(replace, value)
537                try:
538                    value = value % vars
539                except KeyError as e:
540                    raise InterpolationMissingOptionError(
541                        option, section, rawval, e.args[0]) from None
542            else:
543                break
544        if value and "%(" in value:
545            raise InterpolationDepthError(option, section, rawval)
546        return value
547
548    def before_set(self, parser, section, option, value):
549        return value
550
551    @staticmethod
552    def _interpolation_replace(match, parser):
553        s = match.group(1)
554        if s is None:
555            return match.group()
556        else:
557            return "%%(%s)s" % parser.optionxform(s)
558
559
560class RawConfigParser(MutableMapping):
561    """ConfigParser that does not do interpolation."""
562
563    # Regular expressions for parsing section headers and options
564    _SECT_TMPL = r"""
565        \[                                 # [
566        (?P<header>[^]]+)                  # very permissive!
567        \]                                 # ]
568        """
569    _OPT_TMPL = r"""
570        (?P<option>.*?)                    # very permissive!
571        \s*(?P<vi>{delim})\s*              # any number of space/tab,
572                                           # followed by any of the
573                                           # allowed delimiters,
574                                           # followed by any space/tab
575        (?P<value>.*)$                     # everything up to eol
576        """
577    _OPT_NV_TMPL = r"""
578        (?P<option>.*?)                    # very permissive!
579        \s*(?:                             # any number of space/tab,
580        (?P<vi>{delim})\s*                 # optionally followed by
581                                           # any of the allowed
582                                           # delimiters, followed by any
583                                           # space/tab
584        (?P<value>.*))?$                   # everything up to eol
585        """
586    # Interpolation algorithm to be used if the user does not specify another
587    _DEFAULT_INTERPOLATION = Interpolation()
588    # Compiled regular expression for matching sections
589    SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE)
590    # Compiled regular expression for matching options with typical separators
591    OPTCRE = re.compile(_OPT_TMPL.format(delim="=|:"), re.VERBOSE)
592    # Compiled regular expression for matching options with optional values
593    # delimited using typical separators
594    OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE)
595    # Compiled regular expression for matching leading whitespace in a line
596    NONSPACECRE = re.compile(r"\S")
597    # Possible boolean values in the configuration.
598    BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
599                      '0': False, 'no': False, 'false': False, 'off': False}
600
601    def __init__(self, defaults=None, dict_type=_default_dict,
602                 allow_no_value=False, *, delimiters=('=', ':'),
603                 comment_prefixes=('#', ';'), inline_comment_prefixes=None,
604                 strict=True, empty_lines_in_values=True,
605                 default_section=DEFAULTSECT,
606                 interpolation=_UNSET, converters=_UNSET):
607
608        self._dict = dict_type
609        self._sections = self._dict()
610        self._defaults = self._dict()
611        self._converters = ConverterMapping(self)
612        self._proxies = self._dict()
613        self._proxies[default_section] = SectionProxy(self, default_section)
614        self._delimiters = tuple(delimiters)
615        if delimiters == ('=', ':'):
616            self._optcre = self.OPTCRE_NV if allow_no_value else self.OPTCRE
617        else:
618            d = "|".join(re.escape(d) for d in delimiters)
619            if allow_no_value:
620                self._optcre = re.compile(self._OPT_NV_TMPL.format(delim=d),
621                                          re.VERBOSE)
622            else:
623                self._optcre = re.compile(self._OPT_TMPL.format(delim=d),
624                                          re.VERBOSE)
625        self._comment_prefixes = tuple(comment_prefixes or ())
626        self._inline_comment_prefixes = tuple(inline_comment_prefixes or ())
627        self._strict = strict
628        self._allow_no_value = allow_no_value
629        self._empty_lines_in_values = empty_lines_in_values
630        self.default_section=default_section
631        self._interpolation = interpolation
632        if self._interpolation is _UNSET:
633            self._interpolation = self._DEFAULT_INTERPOLATION
634        if self._interpolation is None:
635            self._interpolation = Interpolation()
636        if converters is not _UNSET:
637            self._converters.update(converters)
638        if defaults:
639            self._read_defaults(defaults)
640
641    def defaults(self):
642        return self._defaults
643
644    def sections(self):
645        """Return a list of section names, excluding [DEFAULT]"""
646        # self._sections will never have [DEFAULT] in it
647        return list(self._sections.keys())
648
649    def add_section(self, section):
650        """Create a new section in the configuration.
651
652        Raise DuplicateSectionError if a section by the specified name
653        already exists. Raise ValueError if name is DEFAULT.
654        """
655        if section == self.default_section:
656            raise ValueError('Invalid section name: %r' % section)
657
658        if section in self._sections:
659            raise DuplicateSectionError(section)
660        self._sections[section] = self._dict()
661        self._proxies[section] = SectionProxy(self, section)
662
663    def has_section(self, section):
664        """Indicate whether the named section is present in the configuration.
665
666        The DEFAULT section is not acknowledged.
667        """
668        return section in self._sections
669
670    def options(self, section):
671        """Return a list of option names for the given section name."""
672        try:
673            opts = self._sections[section].copy()
674        except KeyError:
675            raise NoSectionError(section) from None
676        opts.update(self._defaults)
677        return list(opts.keys())
678
679    def read(self, filenames, encoding=None):
680        """Read and parse a filename or an iterable of filenames.
681
682        Files that cannot be opened are silently ignored; this is
683        designed so that you can specify an iterable of potential
684        configuration file locations (e.g. current directory, user's
685        home directory, systemwide directory), and all existing
686        configuration files in the iterable will be read.  A single
687        filename may also be given.
688
689        Return list of successfully read files.
690        """
691        if isinstance(filenames, (str, bytes, os.PathLike)):
692            filenames = [filenames]
693        read_ok = []
694        for filename in filenames:
695            try:
696                with open(filename, encoding=encoding) as fp:
697                    self._read(fp, filename)
698            except OSError:
699                continue
700            if isinstance(filename, os.PathLike):
701                filename = os.fspath(filename)
702            read_ok.append(filename)
703        return read_ok
704
705    def read_file(self, f, source=None):
706        """Like read() but the argument must be a file-like object.
707
708        The `f' argument must be iterable, returning one line at a time.
709        Optional second argument is the `source' specifying the name of the
710        file being read. If not given, it is taken from f.name. If `f' has no
711        `name' attribute, `<???>' is used.
712        """
713        if source is None:
714            try:
715                source = f.name
716            except AttributeError:
717                source = '<???>'
718        self._read(f, source)
719
720    def read_string(self, string, source='<string>'):
721        """Read configuration from a given string."""
722        sfile = io.StringIO(string)
723        self.read_file(sfile, source)
724
725    def read_dict(self, dictionary, source='<dict>'):
726        """Read configuration from a dictionary.
727
728        Keys are section names, values are dictionaries with keys and values
729        that should be present in the section. If the used dictionary type
730        preserves order, sections and their keys will be added in order.
731
732        All types held in the dictionary are converted to strings during
733        reading, including section names, option names and keys.
734
735        Optional second argument is the `source' specifying the name of the
736        dictionary being read.
737        """
738        elements_added = set()
739        for section, keys in dictionary.items():
740            section = str(section)
741            try:
742                self.add_section(section)
743            except (DuplicateSectionError, ValueError):
744                if self._strict and section in elements_added:
745                    raise
746            elements_added.add(section)
747            for key, value in keys.items():
748                key = self.optionxform(str(key))
749                if value is not None:
750                    value = str(value)
751                if self._strict and (section, key) in elements_added:
752                    raise DuplicateOptionError(section, key, source)
753                elements_added.add((section, key))
754                self.set(section, key, value)
755
756    def readfp(self, fp, filename=None):
757        """Deprecated, use read_file instead."""
758        warnings.warn(
759            "This method will be removed in future versions.  "
760            "Use 'parser.read_file()' instead.",
761            DeprecationWarning, stacklevel=2
762        )
763        self.read_file(fp, source=filename)
764
765    def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET):
766        """Get an option value for a given section.
767
768        If `vars' is provided, it must be a dictionary. The option is looked up
769        in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
770        If the key is not found and `fallback' is provided, it is used as
771        a fallback value. `None' can be provided as a `fallback' value.
772
773        If interpolation is enabled and the optional argument `raw' is False,
774        all interpolations are expanded in the return values.
775
776        Arguments `raw', `vars', and `fallback' are keyword only.
777
778        The section DEFAULT is special.
779        """
780        try:
781            d = self._unify_values(section, vars)
782        except NoSectionError:
783            if fallback is _UNSET:
784                raise
785            else:
786                return fallback
787        option = self.optionxform(option)
788        try:
789            value = d[option]
790        except KeyError:
791            if fallback is _UNSET:
792                raise NoOptionError(option, section)
793            else:
794                return fallback
795
796        if raw or value is None:
797            return value
798        else:
799            return self._interpolation.before_get(self, section, option, value,
800                                                  d)
801
802    def _get(self, section, conv, option, **kwargs):
803        return conv(self.get(section, option, **kwargs))
804
805    def _get_conv(self, section, option, conv, *, raw=False, vars=None,
806                  fallback=_UNSET, **kwargs):
807        try:
808            return self._get(section, conv, option, raw=raw, vars=vars,
809                             **kwargs)
810        except (NoSectionError, NoOptionError):
811            if fallback is _UNSET:
812                raise
813            return fallback
814
815    # getint, getfloat and getboolean provided directly for backwards compat
816    def getint(self, section, option, *, raw=False, vars=None,
817               fallback=_UNSET, **kwargs):
818        return self._get_conv(section, option, int, raw=raw, vars=vars,
819                              fallback=fallback, **kwargs)
820
821    def getfloat(self, section, option, *, raw=False, vars=None,
822                 fallback=_UNSET, **kwargs):
823        return self._get_conv(section, option, float, raw=raw, vars=vars,
824                              fallback=fallback, **kwargs)
825
826    def getboolean(self, section, option, *, raw=False, vars=None,
827                   fallback=_UNSET, **kwargs):
828        return self._get_conv(section, option, self._convert_to_boolean,
829                              raw=raw, vars=vars, fallback=fallback, **kwargs)
830
831    def items(self, section=_UNSET, raw=False, vars=None):
832        """Return a list of (name, value) tuples for each option in a section.
833
834        All % interpolations are expanded in the return values, based on the
835        defaults passed into the constructor, unless the optional argument
836        `raw' is true.  Additional substitutions may be provided using the
837        `vars' argument, which must be a dictionary whose contents overrides
838        any pre-existing defaults.
839
840        The section DEFAULT is special.
841        """
842        if section is _UNSET:
843            return super().items()
844        d = self._defaults.copy()
845        try:
846            d.update(self._sections[section])
847        except KeyError:
848            if section != self.default_section:
849                raise NoSectionError(section)
850        orig_keys = list(d.keys())
851        # Update with the entry specific variables
852        if vars:
853            for key, value in vars.items():
854                d[self.optionxform(key)] = value
855        value_getter = lambda option: self._interpolation.before_get(self,
856            section, option, d[option], d)
857        if raw:
858            value_getter = lambda option: d[option]
859        return [(option, value_getter(option)) for option in orig_keys]
860
861    def popitem(self):
862        """Remove a section from the parser and return it as
863        a (section_name, section_proxy) tuple. If no section is present, raise
864        KeyError.
865
866        The section DEFAULT is never returned because it cannot be removed.
867        """
868        for key in self.sections():
869            value = self[key]
870            del self[key]
871            return key, value
872        raise KeyError
873
874    def optionxform(self, optionstr):
875        return optionstr.lower()
876
877    def has_option(self, section, option):
878        """Check for the existence of a given option in a given section.
879        If the specified `section' is None or an empty string, DEFAULT is
880        assumed. If the specified `section' does not exist, returns False."""
881        if not section or section == self.default_section:
882            option = self.optionxform(option)
883            return option in self._defaults
884        elif section not in self._sections:
885            return False
886        else:
887            option = self.optionxform(option)
888            return (option in self._sections[section]
889                    or option in self._defaults)
890
891    def set(self, section, option, value=None):
892        """Set an option."""
893        if value:
894            value = self._interpolation.before_set(self, section, option,
895                                                   value)
896        if not section or section == self.default_section:
897            sectdict = self._defaults
898        else:
899            try:
900                sectdict = self._sections[section]
901            except KeyError:
902                raise NoSectionError(section) from None
903        sectdict[self.optionxform(option)] = value
904
905    def write(self, fp, space_around_delimiters=True):
906        """Write an .ini-format representation of the configuration state.
907
908        If `space_around_delimiters' is True (the default), delimiters
909        between keys and values are surrounded by spaces.
910        """
911        if space_around_delimiters:
912            d = " {} ".format(self._delimiters[0])
913        else:
914            d = self._delimiters[0]
915        if self._defaults:
916            self._write_section(fp, self.default_section,
917                                    self._defaults.items(), d)
918        for section in self._sections:
919            self._write_section(fp, section,
920                                self._sections[section].items(), d)
921
922    def _write_section(self, fp, section_name, section_items, delimiter):
923        """Write a single section to the specified `fp'."""
924        fp.write("[{}]\n".format(section_name))
925        for key, value in section_items:
926            value = self._interpolation.before_write(self, section_name, key,
927                                                     value)
928            if value is not None or not self._allow_no_value:
929                value = delimiter + str(value).replace('\n', '\n\t')
930            else:
931                value = ""
932            fp.write("{}{}\n".format(key, value))
933        fp.write("\n")
934
935    def remove_option(self, section, option):
936        """Remove an option."""
937        if not section or section == self.default_section:
938            sectdict = self._defaults
939        else:
940            try:
941                sectdict = self._sections[section]
942            except KeyError:
943                raise NoSectionError(section) from None
944        option = self.optionxform(option)
945        existed = option in sectdict
946        if existed:
947            del sectdict[option]
948        return existed
949
950    def remove_section(self, section):
951        """Remove a file section."""
952        existed = section in self._sections
953        if existed:
954            del self._sections[section]
955            del self._proxies[section]
956        return existed
957
958    def __getitem__(self, key):
959        if key != self.default_section and not self.has_section(key):
960            raise KeyError(key)
961        return self._proxies[key]
962
963    def __setitem__(self, key, value):
964        # To conform with the mapping protocol, overwrites existing values in
965        # the section.
966        if key in self and self[key] is value:
967            return
968        # XXX this is not atomic if read_dict fails at any point. Then again,
969        # no update method in configparser is atomic in this implementation.
970        if key == self.default_section:
971            self._defaults.clear()
972        elif key in self._sections:
973            self._sections[key].clear()
974        self.read_dict({key: value})
975
976    def __delitem__(self, key):
977        if key == self.default_section:
978            raise ValueError("Cannot remove the default section.")
979        if not self.has_section(key):
980            raise KeyError(key)
981        self.remove_section(key)
982
983    def __contains__(self, key):
984        return key == self.default_section or self.has_section(key)
985
986    def __len__(self):
987        return len(self._sections) + 1 # the default section
988
989    def __iter__(self):
990        # XXX does it break when underlying container state changed?
991        return itertools.chain((self.default_section,), self._sections.keys())
992
993    def _read(self, fp, fpname):
994        """Parse a sectioned configuration file.
995
996        Each section in a configuration file contains a header, indicated by
997        a name in square brackets (`[]'), plus key/value options, indicated by
998        `name' and `value' delimited with a specific substring (`=' or `:' by
999        default).
1000
1001        Values can span multiple lines, as long as they are indented deeper
1002        than the first line of the value. Depending on the parser's mode, blank
1003        lines may be treated as parts of multiline values or ignored.
1004
1005        Configuration files may include comments, prefixed by specific
1006        characters (`#' and `;' by default). Comments may appear on their own
1007        in an otherwise empty line or may be entered in lines holding values or
1008        section names.
1009        """
1010        elements_added = set()
1011        cursect = None                        # None, or a dictionary
1012        sectname = None
1013        optname = None
1014        lineno = 0
1015        indent_level = 0
1016        e = None                              # None, or an exception
1017        for lineno, line in enumerate(fp, start=1):
1018            comment_start = sys.maxsize
1019            # strip inline comments
1020            inline_prefixes = {p: -1 for p in self._inline_comment_prefixes}
1021            while comment_start == sys.maxsize and inline_prefixes:
1022                next_prefixes = {}
1023                for prefix, index in inline_prefixes.items():
1024                    index = line.find(prefix, index+1)
1025                    if index == -1:
1026                        continue
1027                    next_prefixes[prefix] = index
1028                    if index == 0 or (index > 0 and line[index-1].isspace()):
1029                        comment_start = min(comment_start, index)
1030                inline_prefixes = next_prefixes
1031            # strip full line comments
1032            for prefix in self._comment_prefixes:
1033                if line.strip().startswith(prefix):
1034                    comment_start = 0
1035                    break
1036            if comment_start == sys.maxsize:
1037                comment_start = None
1038            value = line[:comment_start].strip()
1039            if not value:
1040                if self._empty_lines_in_values:
1041                    # add empty line to the value, but only if there was no
1042                    # comment on the line
1043                    if (comment_start is None and
1044                        cursect is not None and
1045                        optname and
1046                        cursect[optname] is not None):
1047                        cursect[optname].append('') # newlines added at join
1048                else:
1049                    # empty line marks end of value
1050                    indent_level = sys.maxsize
1051                continue
1052            # continuation line?
1053            first_nonspace = self.NONSPACECRE.search(line)
1054            cur_indent_level = first_nonspace.start() if first_nonspace else 0
1055            if (cursect is not None and optname and
1056                cur_indent_level > indent_level):
1057                cursect[optname].append(value)
1058            # a section header or option header?
1059            else:
1060                indent_level = cur_indent_level
1061                # is it a section header?
1062                mo = self.SECTCRE.match(value)
1063                if mo:
1064                    sectname = mo.group('header')
1065                    if sectname in self._sections:
1066                        if self._strict and sectname in elements_added:
1067                            raise DuplicateSectionError(sectname, fpname,
1068                                                        lineno)
1069                        cursect = self._sections[sectname]
1070                        elements_added.add(sectname)
1071                    elif sectname == self.default_section:
1072                        cursect = self._defaults
1073                    else:
1074                        cursect = self._dict()
1075                        self._sections[sectname] = cursect
1076                        self._proxies[sectname] = SectionProxy(self, sectname)
1077                        elements_added.add(sectname)
1078                    # So sections can't start with a continuation line
1079                    optname = None
1080                # no section header in the file?
1081                elif cursect is None:
1082                    raise MissingSectionHeaderError(fpname, lineno, line)
1083                # an option line?
1084                else:
1085                    mo = self._optcre.match(value)
1086                    if mo:
1087                        optname, vi, optval = mo.group('option', 'vi', 'value')
1088                        if not optname:
1089                            e = self._handle_error(e, fpname, lineno, line)
1090                        optname = self.optionxform(optname.rstrip())
1091                        if (self._strict and
1092                            (sectname, optname) in elements_added):
1093                            raise DuplicateOptionError(sectname, optname,
1094                                                       fpname, lineno)
1095                        elements_added.add((sectname, optname))
1096                        # This check is fine because the OPTCRE cannot
1097                        # match if it would set optval to None
1098                        if optval is not None:
1099                            optval = optval.strip()
1100                            cursect[optname] = [optval]
1101                        else:
1102                            # valueless option handling
1103                            cursect[optname] = None
1104                    else:
1105                        # a non-fatal parsing error occurred. set up the
1106                        # exception but keep going. the exception will be
1107                        # raised at the end of the file and will contain a
1108                        # list of all bogus lines
1109                        e = self._handle_error(e, fpname, lineno, line)
1110        self._join_multiline_values()
1111        # if any parsing errors occurred, raise an exception
1112        if e:
1113            raise e
1114
1115    def _join_multiline_values(self):
1116        defaults = self.default_section, self._defaults
1117        all_sections = itertools.chain((defaults,),
1118                                       self._sections.items())
1119        for section, options in all_sections:
1120            for name, val in options.items():
1121                if isinstance(val, list):
1122                    val = '\n'.join(val).rstrip()
1123                options[name] = self._interpolation.before_read(self,
1124                                                                section,
1125                                                                name, val)
1126
1127    def _read_defaults(self, defaults):
1128        """Read the defaults passed in the initializer.
1129        Note: values can be non-string."""
1130        for key, value in defaults.items():
1131            self._defaults[self.optionxform(key)] = value
1132
1133    def _handle_error(self, exc, fpname, lineno, line):
1134        if not exc:
1135            exc = ParsingError(fpname)
1136        exc.append(lineno, repr(line))
1137        return exc
1138
1139    def _unify_values(self, section, vars):
1140        """Create a sequence of lookups with 'vars' taking priority over
1141        the 'section' which takes priority over the DEFAULTSECT.
1142
1143        """
1144        sectiondict = {}
1145        try:
1146            sectiondict = self._sections[section]
1147        except KeyError:
1148            if section != self.default_section:
1149                raise NoSectionError(section) from None
1150        # Update with the entry specific variables
1151        vardict = {}
1152        if vars:
1153            for key, value in vars.items():
1154                if value is not None:
1155                    value = str(value)
1156                vardict[self.optionxform(key)] = value
1157        return _ChainMap(vardict, sectiondict, self._defaults)
1158
1159    def _convert_to_boolean(self, value):
1160        """Return a boolean value translating from other types if necessary.
1161        """
1162        if value.lower() not in self.BOOLEAN_STATES:
1163            raise ValueError('Not a boolean: %s' % value)
1164        return self.BOOLEAN_STATES[value.lower()]
1165
1166    def _validate_value_types(self, *, section="", option="", value=""):
1167        """Raises a TypeError for non-string values.
1168
1169        The only legal non-string value if we allow valueless
1170        options is None, so we need to check if the value is a
1171        string if:
1172        - we do not allow valueless options, or
1173        - we allow valueless options but the value is not None
1174
1175        For compatibility reasons this method is not used in classic set()
1176        for RawConfigParsers. It is invoked in every case for mapping protocol
1177        access and in ConfigParser.set().
1178        """
1179        if not isinstance(section, str):
1180            raise TypeError("section names must be strings")
1181        if not isinstance(option, str):
1182            raise TypeError("option keys must be strings")
1183        if not self._allow_no_value or value:
1184            if not isinstance(value, str):
1185                raise TypeError("option values must be strings")
1186
1187    @property
1188    def converters(self):
1189        return self._converters
1190
1191
1192class ConfigParser(RawConfigParser):
1193    """ConfigParser implementing interpolation."""
1194
1195    _DEFAULT_INTERPOLATION = BasicInterpolation()
1196
1197    def set(self, section, option, value=None):
1198        """Set an option.  Extends RawConfigParser.set by validating type and
1199        interpolation syntax on the value."""
1200        self._validate_value_types(option=option, value=value)
1201        super().set(section, option, value)
1202
1203    def add_section(self, section):
1204        """Create a new section in the configuration.  Extends
1205        RawConfigParser.add_section by validating if the section name is
1206        a string."""
1207        self._validate_value_types(section=section)
1208        super().add_section(section)
1209
1210    def _read_defaults(self, defaults):
1211        """Reads the defaults passed in the initializer, implicitly converting
1212        values to strings like the rest of the API.
1213
1214        Does not perform interpolation for backwards compatibility.
1215        """
1216        try:
1217            hold_interpolation = self._interpolation
1218            self._interpolation = Interpolation()
1219            self.read_dict({self.default_section: defaults})
1220        finally:
1221            self._interpolation = hold_interpolation
1222
1223
1224class SafeConfigParser(ConfigParser):
1225    """ConfigParser alias for backwards compatibility purposes."""
1226
1227    def __init__(self, *args, **kwargs):
1228        super().__init__(*args, **kwargs)
1229        warnings.warn(
1230            "The SafeConfigParser class has been renamed to ConfigParser "
1231            "in Python 3.2. This alias will be removed in future versions."
1232            " Use ConfigParser directly instead.",
1233            DeprecationWarning, stacklevel=2
1234        )
1235
1236
1237class SectionProxy(MutableMapping):
1238    """A proxy for a single section from a parser."""
1239
1240    def __init__(self, parser, name):
1241        """Creates a view on a section of the specified `name` in `parser`."""
1242        self._parser = parser
1243        self._name = name
1244        for conv in parser.converters:
1245            key = 'get' + conv
1246            getter = functools.partial(self.get, _impl=getattr(parser, key))
1247            setattr(self, key, getter)
1248
1249    def __repr__(self):
1250        return '<Section: {}>'.format(self._name)
1251
1252    def __getitem__(self, key):
1253        if not self._parser.has_option(self._name, key):
1254            raise KeyError(key)
1255        return self._parser.get(self._name, key)
1256
1257    def __setitem__(self, key, value):
1258        self._parser._validate_value_types(option=key, value=value)
1259        return self._parser.set(self._name, key, value)
1260
1261    def __delitem__(self, key):
1262        if not (self._parser.has_option(self._name, key) and
1263                self._parser.remove_option(self._name, key)):
1264            raise KeyError(key)
1265
1266    def __contains__(self, key):
1267        return self._parser.has_option(self._name, key)
1268
1269    def __len__(self):
1270        return len(self._options())
1271
1272    def __iter__(self):
1273        return self._options().__iter__()
1274
1275    def _options(self):
1276        if self._name != self._parser.default_section:
1277            return self._parser.options(self._name)
1278        else:
1279            return self._parser.defaults()
1280
1281    @property
1282    def parser(self):
1283        # The parser object of the proxy is read-only.
1284        return self._parser
1285
1286    @property
1287    def name(self):
1288        # The name of the section on a proxy is read-only.
1289        return self._name
1290
1291    def get(self, option, fallback=None, *, raw=False, vars=None,
1292            _impl=None, **kwargs):
1293        """Get an option value.
1294
1295        Unless `fallback` is provided, `None` will be returned if the option
1296        is not found.
1297
1298        """
1299        # If `_impl` is provided, it should be a getter method on the parser
1300        # object that provides the desired type conversion.
1301        if not _impl:
1302            _impl = self._parser.get
1303        return _impl(self._name, option, raw=raw, vars=vars,
1304                     fallback=fallback, **kwargs)
1305
1306
1307class ConverterMapping(MutableMapping):
1308    """Enables reuse of get*() methods between the parser and section proxies.
1309
1310    If a parser class implements a getter directly, the value for the given
1311    key will be ``None``. The presence of the converter name here enables
1312    section proxies to find and use the implementation on the parser class.
1313    """
1314
1315    GETTERCRE = re.compile(r"^get(?P<name>.+)$")
1316
1317    def __init__(self, parser):
1318        self._parser = parser
1319        self._data = {}
1320        for getter in dir(self._parser):
1321            m = self.GETTERCRE.match(getter)
1322            if not m or not callable(getattr(self._parser, getter)):
1323                continue
1324            self._data[m.group('name')] = None   # See class docstring.
1325
1326    def __getitem__(self, key):
1327        return self._data[key]
1328
1329    def __setitem__(self, key, value):
1330        try:
1331            k = 'get' + key
1332        except TypeError:
1333            raise ValueError('Incompatible key: {} (type: {})'
1334                             ''.format(key, type(key)))
1335        if k == 'get':
1336            raise ValueError('Incompatible key: cannot use "" as a name')
1337        self._data[key] = value
1338        func = functools.partial(self._parser._get_conv, conv=value)
1339        func.converter = value
1340        setattr(self._parser, k, func)
1341        for proxy in self._parser.values():
1342            getter = functools.partial(proxy.get, _impl=func)
1343            setattr(proxy, k, getter)
1344
1345    def __delitem__(self, key):
1346        try:
1347            k = 'get' + (key or None)
1348        except TypeError:
1349            raise KeyError(key)
1350        del self._data[key]
1351        for inst in itertools.chain((self._parser,), self._parser.values()):
1352            try:
1353                delattr(inst, k)
1354            except AttributeError:
1355                # don't raise since the entry was present in _data, silently
1356                # clean up
1357                continue
1358
1359    def __iter__(self):
1360        return iter(self._data)
1361
1362    def __len__(self):
1363        return len(self._data)
1364