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