1 # -*- coding: utf-8 -*-
2 #modification pour python 3 : Laurent Mérat, 6x7 - mai 2020
4 """Configuration file parser.
6 A configuration file consists of sections, lead by a "[section]" header,
7 and followed by "name: value" entries, with continuations and such in
10 Intrinsic defaults can be specified by passing them into the
11 ConfigParser constructor as a dictionary.
15 ConfigParser -- responsible for parsing a list of
16 configuration files, and managing the parsed database.
20 __init__(defaults=None, dict_type=_default_dict, allow_no_value=False,
21 delimiters=('=', ':'), comment_prefixes=('#', ';'),
22 inline_comment_prefixes=None, strict=True,
23 empty_lines_in_values=True):
24 Create the parser. When `defaults' is given, it is initialized into the
25 dictionary or intrinsic defaults. The keys must be strings, the values
26 must be appropriate for %()s string interpolation.
28 When `dict_type' is given, it will be used to create the dictionary
29 objects for the list of sections, for the options within a section, and
30 for the default values.
32 When `delimiters' is given, it will be used as the set of substrings
33 that divide keys from values.
35 When `comment_prefixes' is given, it will be used as the set of
36 substrings that prefix comments in empty lines. Comments can be
39 When `inline_comment_prefixes' is given, it will be used as the set of
40 substrings that prefix comments in non-empty lines.
42 When `strict` is True, the parser won't allow for any section or option
43 duplicates while reading from a single source (file, string or
44 dictionary). Default is True.
46 When `empty_lines_in_values' is False (default: True), each empty line
47 marks the end of an option. Otherwise, internal empty lines of
48 a multiline option are kept as part of the value.
50 When `allow_no_value' is True (default: False), options without
51 values are accepted; the value presented for these is None.
54 Return all the configuration section names, sans DEFAULT.
57 Return whether the given section exists.
59 has_option(section, option)
60 Return whether the given option exists in the given section.
63 Return list of configuration options for the named section.
65 read(filenames, encoding=None)
66 Read and parse the list of named configuration files, given by
67 name. A single filename is also allowed. Non-existing files
68 are ignored. Return list of successfully read files.
70 read_file(f, filename=None)
71 Read and parse one configuration file, given as a file object.
72 The filename defaults to f.name; it is only used in error
73 messages (if f has no `name' attribute, the string `<???>' is used).
76 Read configuration from a given string.
79 Read configuration from a dictionary. Keys are section names,
80 values are dictionaries with keys and values that should be present
81 in the section. If the used dictionary type preserves order, sections
82 and their keys will be added in order. Values are automatically
85 get(section, option, raw=False, vars=None, fallback=_UNSET)
86 Return a string value for the named option. All % interpolations are
87 expanded in the return values, based on the defaults passed into the
88 constructor and the DEFAULT section. Additional substitutions may be
89 provided using the `vars' argument, which must be a dictionary whose
90 contents override any pre-existing defaults. If `option' is a key in
91 `vars', the value from `vars' is used.
93 getint(section, options, raw=False, vars=None, fallback=_UNSET)
94 Like get(), but convert value to an integer.
96 getfloat(section, options, raw=False, vars=None, fallback=_UNSET)
97 Like get(), but convert value to a float.
99 getboolean(section, options, raw=False, vars=None, fallback=_UNSET)
100 Like get(), but convert value to a boolean (currently case
101 insensitively defined as 0, false, no, off for False, and 1, true,
102 yes, on for True). Returns False or True.
104 items(section=_UNSET, raw=False, vars=None)
105 If section is given, return a list of tuples with (section_name,
106 section_proxy) for each section, including DEFAULTSECT. Otherwise,
107 return a list of tuples with (name, value) for each option
110 remove_section(section)
111 Remove the given file section and all its options.
113 remove_option(section, option)
114 Remove the given option from the given section.
116 set(section, option, value)
117 Set the given option.
119 write(fp, space_around_delimiters=True)
120 Write the configuration state in .ini format. If
121 `space_around_delimiters' is True (the default), delimiters
122 between keys and values are surrounded by spaces.
125 #------------------------------------
126 # import des modules python
127 #------------------------------------
128 from collections.abc import MutableMapping
135 #------------------------------------
136 # import des fichiers du projet
137 #------------------------------------
138 from configparser_helpers import _ChainMap
142 from collections import OrderedDict as _default_dict
144 from ordereddict import OrderedDict as _default_dict
148 __all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
149 "NoOptionError", "InterpolationError", "InterpolationDepthError",
150 "InterpolationSyntaxError", "ParsingError",
151 "MissingSectionHeaderError",
152 "ConfigParser", "SafeConfigParser", "RawConfigParser",
153 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
155 DEFAULTSECT = "DEFAULT"
157 MAX_INTERPOLATION_DEPTH = 10
162 class Error(Exception):
163 """Base class for ConfigParser exceptions."""
165 def _get_message(self):
166 """Getter for 'message'; needed only to override deprecation in
169 return self.__message
171 def _set_message(self, value):
172 """Setter for 'message'; needed only to override deprecation in
175 self.__message = value
177 # BaseException.message has been deprecated since Python 2.6. To prevent
178 # DeprecationWarning from popping up over this pre-existing attribute, use
179 # a new property that takes lookup precedence.
180 message = property(_get_message, _set_message)
182 def __init__(self, msg=''):
184 Exception.__init__(self, msg)
192 class NoSectionError(Error):
193 """Raised when no section matches a requested option."""
195 def __init__(self, section):
196 Error.__init__(self, 'No section: %r' % (section,))
197 self.section = section
198 self.args = (section, )
201 class DuplicateSectionError(Error):
202 """Raised when a section is repeated in an input source.
204 Possible repetitions that raise this exception are: multiple creation
205 using the API or in strict parsers when a section is found more than once
206 in a single input file, string or dictionary.
209 def __init__(self, section, source=None, lineno=None):
210 msg = [repr(section), " already exists"]
211 if source is not None:
212 message = ["While reading from ", source]
213 if lineno is not None:
214 message.append(" [line {0:2d}]".format(lineno))
215 message.append(": section ")
219 msg.insert(0, "Section ")
220 Error.__init__(self, "".join(msg))
221 self.section = section
224 self.args = (section, source, lineno)
227 class DuplicateOptionError(Error):
228 """Raised by strict parsers when an option is repeated in an input source.
230 Current implementation raises this exception only when an option is found
231 more than once in a single file, string or dictionary.
234 def __init__(self, section, option, source=None, lineno=None):
235 msg = [repr(option), " in section ", repr(section),
237 if source is not None:
238 message = ["While reading from ", source]
239 if lineno is not None:
240 message.append(" [line {0:2d}]".format(lineno))
241 message.append(": option ")
245 msg.insert(0, "Option ")
246 Error.__init__(self, "".join(msg))
247 self.section = section
251 self.args = (section, option, source, lineno)
254 class NoOptionError(Error):
255 """A requested option was not found."""
257 def __init__(self, option, section):
258 Error.__init__(self, "No option %r in section: %r" %
261 self.section = section
262 self.args = (option, section)
265 class InterpolationError(Error):
266 """Base class for interpolation-related exceptions."""
268 def __init__(self, option, section, msg):
269 Error.__init__(self, msg)
271 self.section = section
272 self.args = (option, section, msg)
275 class InterpolationMissingOptionError(InterpolationError):
276 """A string substitution required a setting which was not available."""
278 def __init__(self, option, section, rawval, reference):
279 msg = ("Bad value substitution:\n"
284 % (section, option, reference, rawval))
285 InterpolationError.__init__(self, option, section, msg)
286 self.reference = reference
287 self.args = (option, section, rawval, reference)
290 class InterpolationSyntaxError(InterpolationError):
291 """Raised when the source text contains invalid syntax.
293 Current implementation raises this exception when the source text into
294 which substitutions are made does not conform to the required syntax.
298 class InterpolationDepthError(InterpolationError):
299 """Raised when substitutions are nested too deeply."""
301 def __init__(self, option, section, rawval):
302 msg = ("Value interpolation too deeply recursive:\n"
306 % (section, option, rawval))
307 InterpolationError.__init__(self, option, section, msg)
308 self.args = (option, section, rawval)
311 class ParsingError(Error):
312 """Raised when a configuration file does not follow legal syntax."""
314 def __init__(self, source=None, filename=None):
315 # Exactly one of `source'/`filename' arguments has to be given.
316 # `filename' kept for compatibility.
317 if filename and source:
318 raise ValueError("Cannot specify both `filename' and `source'. "
320 elif not filename and not source:
321 raise ValueError("Required argument `source' not given.")
324 Error.__init__(self, 'Source contains parsing errors: %s' % source)
327 self.args = (source, )
331 """Deprecated, use `source'."""
333 "The 'filename' attribute will be removed in future versions. "
334 "Use 'source' instead.",
335 DeprecationWarning, stacklevel=2
340 def filename(self, value):
341 """Deprecated, user `source'."""
343 "The 'filename' attribute will be removed in future versions. "
344 "Use 'source' instead.",
345 DeprecationWarning, stacklevel=2
349 def append(self, lineno, line):
350 self.errors.append((lineno, line))
351 self.message += '\n\t[line %2d]: %s' % (lineno, line)
354 class MissingSectionHeaderError(ParsingError):
355 """Raised when a key-value pair is found before any section header."""
357 def __init__(self, filename, lineno, line):
360 'File contains no section headers.\nfile: %s, line: %d\n%r' %
361 (filename, lineno, line))
362 self.source = filename
365 self.args = (filename, lineno, line)
368 # Used in parser getters to indicate the default behaviour when a specific
369 # option is not found it to raise an exception. Created to enable `None' as
370 # a valid fallback value.
374 class Interpolation(object):
375 """Dummy interpolation that passes the value through with no changes."""
377 def before_get(self, parser, section, option, value, defaults):
380 def before_set(self, parser, section, option, value):
383 def before_read(self, parser, section, option, value):
386 def before_write(self, parser, section, option, value):
390 class BasicInterpolation(Interpolation):
391 """Interpolation as implemented in the classic ConfigParser.
393 The option values can contain format strings which refer to other values in
394 the same section, or values in the special default section.
398 something: %(dir)s/whatever
400 would resolve the "%(dir)s" to the value of dir. All reference
401 expansions are done late, on demand. If a user needs to use a bare % in
402 a configuration file, she can escape it by writing %%. Other other % usage
403 is considered a user error and raises `InterpolationSyntaxError'."""
405 _KEYCRE = re.compile(r"%\(([^)]+)\)s")
407 def before_get(self, parser, section, option, value, defaults):
409 self._interpolate_some(parser, option, L, value, section, defaults, 1)
412 def before_set(self, parser, section, option, value):
413 tmp_value = value.replace('%%', '') # escaped percent signs
414 tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
416 raise ValueError("invalid interpolation syntax in %r at "
417 "position %d" % (value, tmp_value.find('%')))
420 def _interpolate_some(self, parser, option, accum, rest, section, map,
422 if depth > MAX_INTERPOLATION_DEPTH:
423 raise InterpolationDepthError(option, section, rest)
430 accum.append(rest[:p])
432 # p is no longer used
438 m = self._KEYCRE.match(rest)
440 raise InterpolationSyntaxError(option, section,
441 "bad interpolation variable reference %r" % rest)
442 var = parser.optionxform(m.group(1))
443 rest = rest[m.end():]
447 raise InterpolationMissingOptionError(
448 option, section, rest, var)
450 self._interpolate_some(parser, option, accum, v,
451 section, map, depth + 1)
455 raise InterpolationSyntaxError(
457 "'%%' must be followed by '%%' or '(', "
458 "found: %r" % (rest,))
461 class ExtendedInterpolation(Interpolation):
462 """Advanced variant of interpolation, supports the syntax used by
463 `zc.buildout'. Enables interpolation between sections."""
465 _KEYCRE = re.compile(r"\$\{([^}]+)\}")
467 def before_get(self, parser, section, option, value, defaults):
469 self._interpolate_some(parser, option, L, value, section, defaults, 1)
472 def before_set(self, parser, section, option, value):
473 tmp_value = value.replace('$$', '') # escaped dollar signs
474 tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
476 raise ValueError("invalid interpolation syntax in %r at "
477 "position %d" % (value, tmp_value.find('%')))
480 def _interpolate_some(self, parser, option, accum, rest, section, map,
482 if depth > MAX_INTERPOLATION_DEPTH:
483 raise InterpolationDepthError(option, section, rest)
490 accum.append(rest[:p])
492 # p is no longer used
498 m = self._KEYCRE.match(rest)
500 raise InterpolationSyntaxError(option, section,
501 "bad interpolation variable reference %r" % rest)
502 path = m.group(1).split(':')
503 rest = rest[m.end():]
508 opt = parser.optionxform(path[0])
512 opt = parser.optionxform(path[1])
513 v = parser.get(sect, opt, raw=True)
515 raise InterpolationSyntaxError(
517 "More than one ':' found: %r" % (rest,))
518 except (KeyError, NoSectionError, NoOptionError):
519 raise InterpolationMissingOptionError(
520 option, section, rest, ":".join(path))
522 self._interpolate_some(parser, opt, accum, v, sect,
523 dict(parser.items(sect, raw=True)),
528 raise InterpolationSyntaxError(
530 "'$' must be followed by '$' or '{', "
531 "found: %r" % (rest,))
534 class LegacyInterpolation(Interpolation):
535 """Deprecated interpolation used in old versions of ConfigParser.
536 Use BasicInterpolation or ExtendedInterpolation instead."""
538 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
540 def before_get(self, parser, section, option, value, vars):
542 depth = MAX_INTERPOLATION_DEPTH
543 while depth: # Loop through this until it's done
545 if value and "%(" in value:
546 replace = functools.partial(self._interpolation_replace,
548 value = self._KEYCRE.sub(replace, value)
551 except KeyError as e:
552 raise InterpolationMissingOptionError(
553 option, section, rawval, e.args[0])
556 if value and "%(" in value:
557 raise InterpolationDepthError(option, section, rawval)
560 def before_set(self, parser, section, option, value):
564 def _interpolation_replace(match, parser):
569 return "%%(%s)s" % parser.optionxform(s)
572 class RawConfigParser(MutableMapping):
573 """ConfigParser that does not do interpolation."""
575 # Regular expressions for parsing section headers and options
578 (?P<header>[^]]+) # very permissive!
582 (?P<option>.*?) # very permissive!
583 \s*(?P<vi>{delim})\s* # any number of space/tab,
584 # followed by any of the
585 # allowed delimiters,
586 # followed by any space/tab
587 (?P<value>.*)$ # everything up to eol
590 (?P<option>.*?) # very permissive!
591 \s*(?: # any number of space/tab,
592 (?P<vi>{delim})\s* # optionally followed by
594 # delimiters, followed by any
596 (?P<value>.*))?$ # everything up to eol
598 # Interpolation algorithm to be used if the user does not specify another
599 _DEFAULT_INTERPOLATION = Interpolation()
600 # Compiled regular expression for matching sections
601 SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE)
602 # Compiled regular expression for matching options with typical separators
603 OPTCRE = re.compile(_OPT_TMPL.format(delim="=|:"), re.VERBOSE)
604 # Compiled regular expression for matching options with optional values
605 # delimited using typical separators
606 OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE)
607 # Compiled regular expression for matching leading whitespace in a line
608 NONSPACECRE = re.compile(r"\S")
609 # Possible boolean values in the configuration.
610 BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
611 '0': False, 'no': False, 'false': False, 'off': False}
613 def __init__(self, defaults=None, dict_type=_default_dict,
614 allow_no_value=False, **_3to2kwargs):
616 if 'interpolation' in _3to2kwargs: interpolation = _3to2kwargs['interpolation']; del _3to2kwargs['interpolation']
617 else: interpolation = _UNSET
618 if 'default_section' in _3to2kwargs: default_section = _3to2kwargs['default_section']; del _3to2kwargs['default_section']
619 else: default_section = DEFAULTSECT
620 if 'empty_lines_in_values' in _3to2kwargs: empty_lines_in_values = _3to2kwargs['empty_lines_in_values']; del _3to2kwargs['empty_lines_in_values']
621 else: empty_lines_in_values = True
622 if 'strict' in _3to2kwargs: strict = _3to2kwargs['strict']; del _3to2kwargs['strict']
624 if 'inline_comment_prefixes' in _3to2kwargs: inline_comment_prefixes = _3to2kwargs['inline_comment_prefixes']; del _3to2kwargs['inline_comment_prefixes']
625 else: inline_comment_prefixes = None
626 if 'comment_prefixes' in _3to2kwargs: comment_prefixes = _3to2kwargs['comment_prefixes']; del _3to2kwargs['comment_prefixes']
627 else: comment_prefixes = ('#', ';')
628 if 'delimiters' in _3to2kwargs: delimiters = _3to2kwargs['delimiters']; del _3to2kwargs['delimiters']
629 else: delimiters = ('=', ':')
630 self._dict = dict_type
631 self._sections = self._dict()
632 self._defaults = self._dict()
633 self._proxies = self._dict()
634 self._proxies[default_section] = SectionProxy(self, default_section)
636 for key, value in list(defaults.items()):
637 self._defaults[self.optionxform(key)] = value
638 self._delimiters = tuple(delimiters)
639 if delimiters == ('=', ':'):
640 self._optcre = self.OPTCRE_NV if allow_no_value else self.OPTCRE
642 d = "|".join(re.escape(d) for d in delimiters)
644 self._optcre = re.compile(self._OPT_NV_TMPL.format(delim=d),
647 self._optcre = re.compile(self._OPT_TMPL.format(delim=d),
649 self._comment_prefixes = tuple(comment_prefixes or ())
650 self._inline_comment_prefixes = tuple(inline_comment_prefixes or ())
651 self._strict = strict
652 self._allow_no_value = allow_no_value
653 self._empty_lines_in_values = empty_lines_in_values
654 self.default_section=default_section
655 self._interpolation = interpolation
656 if self._interpolation is _UNSET:
657 self._interpolation = self._DEFAULT_INTERPOLATION
658 if self._interpolation is None:
659 self._interpolation = Interpolation()
662 return self._defaults
665 """Return a list of section names, excluding [DEFAULT]"""
666 # self._sections will never have [DEFAULT] in it
667 return list(self._sections.keys())
669 def add_section(self, section):
670 """Create a new section in the configuration.
672 Raise DuplicateSectionError if a section by the specified name
673 already exists. Raise ValueError if name is DEFAULT.
675 if section == self.default_section:
676 raise ValueError('Invalid section name: %r' % section)
678 if section in self._sections:
679 raise DuplicateSectionError(section)
680 self._sections[section] = self._dict()
681 self._proxies[section] = SectionProxy(self, section)
683 def has_section(self, section):
684 """Indicate whether the named section is present in the configuration.
686 The DEFAULT section is not acknowledged.
688 return section in self._sections
690 def options(self, section):
691 """Return a list of option names for the given section name."""
693 opts = self._sections[section].copy()
695 raise NoSectionError(section)
696 opts.update(self._defaults)
697 return list(opts.keys())
699 def read(self, filenames, encoding=None):
700 """Read and parse a filename or a list of filenames.
702 Files that cannot be opened are silently ignored; this is
703 designed so that you can specify a list of potential
704 configuration file locations (e.g. current directory, user's
705 home directory, systemwide directory), and all existing
706 configuration files in the list will be read. A single
707 filename may also be given.
709 Return list of successfully read files.
711 if isinstance(filenames, str):
712 filenames = [filenames]
714 for filename in filenames:
716 with open(filename, encoding='utf8') as fp:
717 self._read(fp, filename)
720 read_ok.append(filename)
723 def read_file(self, f, source=None):
724 """Like read() but the argument must be a file-like object.
726 The `f' argument must be iterable, returning one line at a time.
727 Optional second argument is the `source' specifying the name of the
728 file being read. If not given, it is taken from f.name. If `f' has no
729 `name' attribute, `<???>' is used.
734 except AttributeError:
736 self._read(f, source)
738 def read_string(self, string, source='<string>'):
739 """Read configuration from a given string."""
740 sfile = io.StringIO(string)
741 self.read_file(sfile, source)
743 def read_dict(self, dictionary, source='<dict>'):
744 """Read configuration from a dictionary.
746 Keys are section names, values are dictionaries with keys and values
747 that should be present in the section. If the used dictionary type
748 preserves order, sections and their keys will be added in order.
750 All types held in the dictionary are converted to strings during
751 reading, including section names, option names and keys.
753 Optional second argument is the `source' specifying the name of the
754 dictionary being read.
756 elements_added = set()
757 for section, keys in list(dictionary.items()):
758 section = str(section) #???
760 self.add_section(section)
761 except (DuplicateSectionError, ValueError):
762 if self._strict and section in elements_added:
764 elements_added.add(section)
765 for key, value in list(keys.items()):
766 key = self.optionxform(str(key))#???
767 if value is not None:
768 value = str(value) #???
769 if self._strict and (section, key) in elements_added:
770 raise DuplicateOptionError(section, key, source)
771 elements_added.add((section, key))
772 self.set(section, key, value)
774 def readfp(self, fp, filename=None):
775 """Deprecated, use read_file instead."""
777 "This method will be removed in future versions. "
778 "Use 'parser.read_file()' instead.",
779 DeprecationWarning, stacklevel=2
781 self.read_file(fp, source=filename)
783 def get(self, section, option, **_3to2kwargs):
784 if 'fallback' in _3to2kwargs: fallback = _3to2kwargs['fallback']; del _3to2kwargs['fallback']
785 else: fallback = _UNSET
786 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
788 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
790 """Get an option value for a given section.
792 If `vars' is provided, it must be a dictionary. The option is looked up
793 in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
794 If the key is not found and `fallback' is provided, it is used as
795 a fallback value. `None' can be provided as a `fallback' value.
797 If interpolation is enabled and the optional argument `raw' is False,
798 all interpolations are expanded in the return values.
800 Arguments `raw', `vars', and `fallback' are keyword only.
802 The section DEFAULT is special.
805 d = self._unify_values(section, vars)
806 except NoSectionError:
807 if fallback is _UNSET:
811 option = self.optionxform(option)
815 if fallback is _UNSET:
816 raise NoOptionError(option, section)
820 if raw or value is None:
823 return self._interpolation.before_get(self, section, option, value,
826 def _get(self, section, conv, option, **kwargs):
827 return conv(self.get(section, option, **kwargs))
829 def getint(self, section, option, **_3to2kwargs):
830 if 'fallback' in _3to2kwargs: fallback = _3to2kwargs['fallback']; del _3to2kwargs['fallback']
831 else: fallback = _UNSET
832 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
834 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
837 return self._get(section, int, option, raw=raw, vars=vars)
838 except (NoSectionError, NoOptionError):
839 if fallback is _UNSET:
844 def getfloat(self, section, option, **_3to2kwargs):
845 if 'fallback' in _3to2kwargs: fallback = _3to2kwargs['fallback']; del _3to2kwargs['fallback']
846 else: fallback = _UNSET
847 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
849 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
852 return self._get(section, float, option, raw=raw, vars=vars)
853 except (NoSectionError, NoOptionError):
854 if fallback is _UNSET:
859 def getboolean(self, section, option, **_3to2kwargs):
860 if 'fallback' in _3to2kwargs: fallback = _3to2kwargs['fallback']; del _3to2kwargs['fallback']
861 else: fallback = _UNSET
862 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
864 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
867 return self._get(section, self._convert_to_boolean, option,
869 except (NoSectionError, NoOptionError):
870 if fallback is _UNSET:
875 def items(self, section=_UNSET, raw=False, vars=None):
876 """Return a list of (name, value) tuples for each option in a section.
878 All % interpolations are expanded in the return values, based on the
879 defaults passed into the constructor, unless the optional argument
880 `raw' is true. Additional substitutions may be provided using the
881 `vars' argument, which must be a dictionary whose contents overrides
882 any pre-existing defaults.
884 The section DEFAULT is special.
886 if section is _UNSET:
887 return list(super(RawConfigParser, self).items())
888 d = self._defaults.copy()
890 d.update(self._sections[section])
892 if section != self.default_section:
893 raise NoSectionError(section)
894 # Update with the entry specific variables
896 for key, value in list(vars.items()):
897 d[self.optionxform(key)] = value
898 value_getter = lambda option: self._interpolation.before_get(self,
899 section, option, d[option], d)
901 value_getter = lambda option: d[option]
902 return [(option, value_getter(option)) for option in list(d.keys())]
904 def optionxform(self, optionstr):
905 return optionstr.lower()
907 def has_option(self, section, option):
908 """Check for the existence of a given option in a given section.
909 If the specified `section' is None or an empty string, DEFAULT is
910 assumed. If the specified `section' does not exist, returns False."""
911 if not section or section == self.default_section:
912 option = self.optionxform(option)
913 return option in self._defaults
914 elif section not in self._sections:
917 option = self.optionxform(option)
918 return (option in self._sections[section]
919 or option in self._defaults)
921 def set(self, section, option, value=None):
924 value = self._interpolation.before_set(self, section, option,
926 if not section or section == self.default_section:
927 sectdict = self._defaults
930 sectdict = self._sections[section]
932 raise NoSectionError(section)
933 sectdict[self.optionxform(option)] = value
935 def write(self, fp, space_around_delimiters=True):
936 """Write an .ini-format representation of the configuration state.
938 If `space_around_delimiters' is True (the default), delimiters
939 between keys and values are surrounded by spaces.
941 if space_around_delimiters:
942 d = " {0} ".format(self._delimiters[0])
944 d = self._delimiters[0]
946 self._write_section(fp, self.default_section,
947 list(self._defaults.items()), d)
948 for section in self._sections:
949 self._write_section(fp, section,
950 list(self._sections[section].items()), d)
952 def _write_section(self, fp, section_name, section_items, delimiter):
953 """Write a single section to the specified `fp'."""
954 fp.write("[{0}]\n".format(section_name))
955 for key, value in section_items:
956 value = self._interpolation.before_write(self, section_name, key,
958 if value is not None or not self._allow_no_value:
959 value = delimiter + str(value).replace('\n', '\n\t') #???
962 fp.write("{0}{1}\n".format(key, value))
965 def remove_option(self, section, option):
966 """Remove an option."""
967 if not section or section == self.default_section:
968 sectdict = self._defaults
971 sectdict = self._sections[section]
973 raise NoSectionError(section)
974 option = self.optionxform(option)
975 existed = option in sectdict
980 def remove_section(self, section):
981 """Remove a file section."""
982 existed = section in self._sections
984 del self._sections[section]
985 del self._proxies[section]
988 def __getitem__(self, key):
989 if key != self.default_section and not self.has_section(key):
991 return self._proxies[key]
993 def __setitem__(self, key, value):
994 # To conform with the mapping protocol, overwrites existing values in
997 # XXX this is not atomic if read_dict fails at any point. Then again,
998 # no update method in configparser is atomic in this implementation.
999 self.remove_section(key)
1000 self.read_dict({key: value})
1002 def __delitem__(self, key):
1003 if key == self.default_section:
1004 raise ValueError("Cannot remove the default section.")
1005 if not self.has_section(key):
1007 self.remove_section(key)
1009 def __contains__(self, key):
1010 return key == self.default_section or self.has_section(key)
1013 return len(self._sections) + 1 # the default section
1016 # XXX does it break when underlying container state changed?
1017 return itertools.chain((self.default_section,), list(self._sections.keys()))
1019 def _read(self, fp, fpname):
1020 """Parse a sectioned configuration file.
1022 Each section in a configuration file contains a header, indicated by
1023 a name in square brackets (`[]'), plus key/value options, indicated by
1024 `name' and `value' delimited with a specific substring (`=' or `:' by
1027 Values can span multiple lines, as long as they are indented deeper
1028 than the first line of the value. Depending on the parser's mode, blank
1029 lines may be treated as parts of multiline values or ignored.
1031 Configuration files may include comments, prefixed by specific
1032 characters (`#' and `;' by default). Comments may appear on their own
1033 in an otherwise empty line or may be entered in lines holding values or
1036 elements_added = set()
1037 cursect = None # None, or a dictionary
1042 e = None # None, or an exception
1043 for lineno, line in enumerate(fp, start=1):
1044 comment_start = None
1045 # strip inline comments
1046 for prefix in self._inline_comment_prefixes:
1047 index = line.find(prefix)
1048 if index == 0 or (index > 0 and line[index-1].isspace()):
1049 comment_start = index
1051 # strip full line comments
1052 for prefix in self._comment_prefixes:
1053 if line.strip().startswith(prefix):
1056 value = line[:comment_start].strip()
1058 if self._empty_lines_in_values:
1059 # add empty line to the value, but only if there was no
1060 # comment on the line
1061 if (comment_start is None and
1062 cursect is not None and
1064 cursect[optname] is not None):
1065 cursect[optname].append('') # newlines added at join
1067 # empty line marks end of value
1068 indent_level = sys.maxsize
1070 # continuation line?
1071 first_nonspace = self.NONSPACECRE.search(line)
1072 cur_indent_level = first_nonspace.start() if first_nonspace else 0
1073 if (cursect is not None and optname and
1074 cur_indent_level > indent_level):
1075 cursect[optname].append(value)
1076 # a section header or option header?
1078 indent_level = cur_indent_level
1079 # is it a section header?
1080 mo = self.SECTCRE.match(value)
1082 sectname = mo.group('header')
1083 if sectname in self._sections:
1084 if self._strict and sectname in elements_added:
1085 raise DuplicateSectionError(sectname, fpname,
1087 cursect = self._sections[sectname]
1088 elements_added.add(sectname)
1089 elif sectname == self.default_section:
1090 cursect = self._defaults
1092 cursect = self._dict()
1093 self._sections[sectname] = cursect
1094 self._proxies[sectname] = SectionProxy(self, sectname)
1095 elements_added.add(sectname)
1096 # So sections can't start with a continuation line
1098 # no section header in the file?
1099 elif cursect is None:
1100 raise MissingSectionHeaderError(fpname, lineno, line)
1103 mo = self._optcre.match(value)
1105 optname, vi, optval = mo.group('option', 'vi', 'value')
1107 e = self._handle_error(e, fpname, lineno, line)
1108 optname = self.optionxform(optname.rstrip())
1109 if (self._strict and
1110 (sectname, optname) in elements_added):
1111 raise DuplicateOptionError(sectname, optname,
1113 elements_added.add((sectname, optname))
1114 # This check is fine because the OPTCRE cannot
1115 # match if it would set optval to None
1116 if optval is not None:
1117 optval = optval.strip()
1118 cursect[optname] = [optval]
1120 # valueless option handling
1121 cursect[optname] = None
1123 # a non-fatal parsing error occurred. set up the
1124 # exception but keep going. the exception will be
1125 # raised at the end of the file and will contain a
1126 # list of all bogus lines
1127 e = self._handle_error(e, fpname, lineno, line)
1128 # if any parsing errors occurred, raise an exception
1131 self._join_multiline_values()
1133 def _join_multiline_values(self):
1134 defaults = self.default_section, self._defaults
1135 all_sections = itertools.chain((defaults,),
1136 list(self._sections.items()))
1137 for section, options in all_sections:
1138 for name, val in list(options.items()):
1139 if isinstance(val, list):
1140 val = '\n'.join(val).rstrip()
1141 options[name] = self._interpolation.before_read(self,
1145 def _handle_error(self, exc, fpname, lineno, line):
1147 exc = ParsingError(fpname)
1148 exc.append(lineno, repr(line))
1151 def _unify_values(self, section, vars):
1152 """Create a sequence of lookups with 'vars' taking priority over
1153 the 'section' which takes priority over the DEFAULTSECT.
1158 sectiondict = self._sections[section]
1160 if section != self.default_section:
1161 raise NoSectionError(section)
1162 # Update with the entry specific variables
1165 for key, value in list(vars.items()):
1166 if value is not None:
1167 value = str(value) #???
1168 vardict[self.optionxform(key)] = value
1169 return _ChainMap(vardict, sectiondict, self._defaults)
1171 def _convert_to_boolean(self, value):
1172 """Return a boolean value translating from other types if necessary.
1174 if value.lower() not in self.BOOLEAN_STATES:
1175 raise ValueError('Not a boolean: %s' % value)
1176 return self.BOOLEAN_STATES[value.lower()]
1178 def _validate_value_types(self, **_3to2kwargs):
1179 if 'value' in _3to2kwargs: value = _3to2kwargs['value']; del _3to2kwargs['value']
1181 if 'option' in _3to2kwargs: option = _3to2kwargs['option']; del _3to2kwargs['option']
1183 if 'section' in _3to2kwargs: section = _3to2kwargs['section']; del _3to2kwargs['section']
1185 """Raises a TypeError for non-string values.
1187 The only legal non-string value if we allow valueless
1188 options is None, so we need to check if the value is a
1190 - we do not allow valueless options, or
1191 - we allow valueless options but the value is not None
1193 For compatibility reasons this method is not used in classic set()
1194 for RawConfigParsers. It is invoked in every case for mapping protocol
1195 access and in ConfigParser.set().
1197 if not isinstance(section, str):
1198 raise TypeError("section names must be strings")
1199 if not isinstance(option, str):
1200 raise TypeError("option keys must be strings")
1201 if not self._allow_no_value or value:
1202 if not isinstance(value, str):
1203 raise TypeError("option values must be strings")
1204 return (str(section), str(option), (value if value is None
1205 else str(value))) #???
1208 class ConfigParser(RawConfigParser):
1209 """ConfigParser implementing interpolation."""
1211 _DEFAULT_INTERPOLATION = BasicInterpolation()
1213 def set(self, section, option, value=None):
1214 """Set an option. Extends RawConfigParser.set by validating type and
1215 interpolation syntax on the value."""
1216 _, option, value = self._validate_value_types(option=option, value=value)
1217 super(ConfigParser, self).set(section, option, value)
1219 def add_section(self, section):
1220 """Create a new section in the configuration. Extends
1221 RawConfigParser.add_section by validating if the section name is
1223 section, _, _ = self._validate_value_types(section=section)
1224 super(ConfigParser, self).add_section(section)
1227 class SafeConfigParser(ConfigParser):
1228 """ConfigParser alias for backwards compatibility purposes."""
1230 def __init__(self, *args, **kwargs):
1231 super(SafeConfigParser, self).__init__(*args, **kwargs)
1233 "The SafeConfigParser class has been renamed to ConfigParser "
1234 "in Python 3.2. This alias will be removed in future versions."
1235 " Use ConfigParser directly instead.",
1236 DeprecationWarning, stacklevel=2
1240 class SectionProxy(MutableMapping):
1241 """A proxy for a single section from a parser."""
1243 def __init__(self, parser, name):
1244 """Creates a view on a section of the specified `name` in `parser`."""
1245 self._parser = parser
1249 return '<Section: {0}>'.format(self._name)
1251 def __getitem__(self, key):
1252 if not self._parser.has_option(self._name, key):
1254 return self._parser.get(self._name, key)
1256 def __setitem__(self, key, value):
1257 _, key, value = self._parser._validate_value_types(option=key, value=value)
1258 return self._parser.set(self._name, key, value)
1260 def __delitem__(self, key):
1261 if not (self._parser.has_option(self._name, key) and
1262 self._parser.remove_option(self._name, key)):
1265 def __contains__(self, key):
1266 return self._parser.has_option(self._name, key)
1269 return len(self._options())
1272 return self._options().__iter__()
1275 if self._name != self._parser.default_section:
1276 return self._parser.options(self._name)
1278 return self._parser.defaults()
1280 def get(self, option, fallback=None, **_3to2kwargs):
1281 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
1283 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
1285 return self._parser.get(self._name, option, raw=raw, vars=vars,
1288 def getint(self, option, fallback=None, **_3to2kwargs):
1289 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
1291 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
1293 return self._parser.getint(self._name, option, raw=raw, vars=vars,
1296 def getfloat(self, option, fallback=None, **_3to2kwargs):
1297 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
1299 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
1301 return self._parser.getfloat(self._name, option, raw=raw, vars=vars,
1304 def getboolean(self, option, fallback=None, **_3to2kwargs):
1305 if 'vars' in _3to2kwargs: vars = _3to2kwargs['vars']; del _3to2kwargs['vars']
1307 if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
1309 return self._parser.getboolean(self._name, option, raw=raw, vars=vars,
1314 # The parser object of the proxy is read-only.
1319 # The name of the section on a proxy is read-only.