| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 1 | """Configuration file parser. | 
 | 2 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 3 | A configuration file consists of sections, lead by a "[section]" header, | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 4 | and followed by "name: value" entries, with continuations and such in | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 5 | the style of RFC 822. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 6 |  | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 7 | The option values can contain format strings which refer to other values in | 
 | 8 | the same section, or values in a special [DEFAULT] section. | 
 | 9 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 10 | For example: | 
 | 11 |  | 
 | 12 |     something: %(dir)s/whatever | 
 | 13 |  | 
 | 14 | would resolve the "%(dir)s" to the value of dir.  All reference | 
 | 15 | expansions are done late, on demand. | 
 | 16 |  | 
 | 17 | Intrinsic defaults can be specified by passing them into the | 
 | 18 | ConfigParser constructor as a dictionary. | 
 | 19 |  | 
 | 20 | class: | 
 | 21 |  | 
| Walter Dörwald | f0dfc7a | 2003-10-20 14:01:56 +0000 | [diff] [blame] | 22 | ConfigParser -- responsible for parsing a list of | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 23 |                 configuration files, and managing the parsed database. | 
 | 24 |  | 
 | 25 |     methods: | 
 | 26 |  | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 27 |     __init__(defaults=None, dict_type=_default_dict, allow_no_value=False, | 
 | 28 |              delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, | 
 | 29 |              strict=False, empty_lines_in_values=True): | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 30 |         Create the parser. When `defaults' is given, it is initialized into the | 
 | 31 |         dictionary or intrinsic defaults. The keys must be strings, the values | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 32 |         must be appropriate for %()s string interpolation. Note that `__name__' | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 33 |         is always an intrinsic default; its value is the section's name. | 
 | 34 |  | 
 | 35 |         When `dict_type' is given, it will be used to create the dictionary | 
 | 36 |         objects for the list of sections, for the options within a section, and | 
 | 37 |         for the default values. | 
 | 38 |  | 
 | 39 |         When `delimiters' is given, it will be used as the set of substrings | 
 | 40 |         that divide keys from values. | 
 | 41 |  | 
 | 42 |         When `comment_prefixes' is given, it will be used as the set of | 
 | 43 |         substrings that prefix comments in a line. | 
 | 44 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 45 |         When `strict` is True, the parser won't allow for any section or option | 
 | 46 |         duplicates while reading from a single source (file, string or | 
 | 47 |         dictionary). Default is False. | 
 | 48 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 49 |         When `empty_lines_in_values' is False (default: True), each empty line | 
 | 50 |         marks the end of an option. Otherwise, internal empty lines of | 
 | 51 |         a multiline option are kept as part of the value. | 
 | 52 |  | 
 | 53 |         When `allow_no_value' is True (default: False), options without | 
 | 54 |         values are accepted; the value presented for these is None. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 55 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 56 |     sections() | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 57 |         Return all the configuration section names, sans DEFAULT. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 58 |  | 
| Guido van Rossum | a5a24b7 | 1999-10-04 19:58:22 +0000 | [diff] [blame] | 59 |     has_section(section) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 60 |         Return whether the given section exists. | 
| Guido van Rossum | a5a24b7 | 1999-10-04 19:58:22 +0000 | [diff] [blame] | 61 |  | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 62 |     has_option(section, option) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 63 |         Return whether the given option exists in the given section. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 64 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 65 |     options(section) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 66 |         Return list of configuration options for the named section. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 67 |  | 
| Georg Brandl | 8dcaa73 | 2010-07-29 12:17:40 +0000 | [diff] [blame] | 68 |     read(filenames, encoding=None) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 69 |         Read and parse the list of named configuration files, given by | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 70 |         name.  A single filename is also allowed.  Non-existing files | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 71 |         are ignored.  Return list of successfully read files. | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 72 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 73 |     read_file(f, filename=None) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 74 |         Read and parse one configuration file, given as a file object. | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 75 |         The filename defaults to f.name; it is only used in error | 
 | 76 |         messages (if f has no `name' attribute, the string `<???>' is used). | 
 | 77 |  | 
 | 78 |     read_string(string) | 
 | 79 |         Read configuration from a given string. | 
 | 80 |  | 
 | 81 |     read_dict(dictionary) | 
 | 82 |         Read configuration from a dictionary. Keys are section names, | 
 | 83 |         values are dictionaries with keys and values that should be present | 
 | 84 |         in the section. If the used dictionary type preserves order, sections | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 85 |         and their keys will be added in order. Values are automatically | 
 | 86 |         converted to strings. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 87 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 88 |     get(section, option, raw=False, vars=None, fallback=_UNSET) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 89 |         Return a string value for the named option.  All % interpolations are | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 90 |         expanded in the return values, based on the defaults passed into the | 
 | 91 |         constructor and the DEFAULT section.  Additional substitutions may be | 
 | 92 |         provided using the `vars' argument, which must be a dictionary whose | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 93 |         contents override any pre-existing defaults. If `option' is a key in | 
 | 94 |         `vars', the value from `vars' is used. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 95 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 96 |     getint(section, options, raw=False, vars=None, fallback=_UNSET) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 97 |         Like get(), but convert value to an integer. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 98 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 99 |     getfloat(section, options, raw=False, vars=None, fallback=_UNSET) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 100 |         Like get(), but convert value to a float. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 101 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 102 |     getboolean(section, options, raw=False, vars=None, fallback=_UNSET) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 103 |         Like get(), but convert value to a boolean (currently case | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 104 |         insensitively defined as 0, false, no, off for False, and 1, true, | 
 | 105 |         yes, on for True).  Returns False or True. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 106 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 107 |     items(section, raw=False, vars=None) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 108 |         Return a list of tuples with (name, value) for each option | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 109 |         in the section. | 
 | 110 |  | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 111 |     remove_section(section) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 112 |         Remove the given file section and all its options. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 113 |  | 
 | 114 |     remove_option(section, option) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 115 |         Remove the given option from the given section. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 116 |  | 
 | 117 |     set(section, option, value) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 118 |         Set the given option. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 119 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 120 |     write(fp, space_around_delimiters=True) | 
 | 121 |         Write the configuration state in .ini format. If | 
 | 122 |         `space_around_delimiters' is True (the default), delimiters | 
 | 123 |         between keys and values are surrounded by spaces. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 124 | """ | 
 | 125 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 126 | from collections import MutableMapping, OrderedDict as _default_dict | 
 | 127 | import functools | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 128 | import io | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 129 | import itertools | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 130 | import re | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 131 | import sys | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 132 | import warnings | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 133 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 134 | __all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", | 
 | 135 |            "NoOptionError", "InterpolationError", "InterpolationDepthError", | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 136 |            "InterpolationSyntaxError", "ParsingError", | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 137 |            "MissingSectionHeaderError", | 
 | 138 |            "ConfigParser", "SafeConfigParser", "RawConfigParser", | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 139 |            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] | 
| Skip Montanaro | e99d5ea | 2001-01-20 19:54:20 +0000 | [diff] [blame] | 140 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 141 | DEFAULTSECT = "DEFAULT" | 
 | 142 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 143 | MAX_INTERPOLATION_DEPTH = 10 | 
 | 144 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 145 |  | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 146 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 147 | # exception classes | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 148 | class Error(Exception): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 149 |     """Base class for ConfigParser exceptions.""" | 
 | 150 |  | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 151 |     def _get_message(self): | 
 | 152 |         """Getter for 'message'; needed only to override deprecation in | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 153 |         BaseException. | 
 | 154 |         """ | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 155 |         return self.__message | 
 | 156 |  | 
 | 157 |     def _set_message(self, value): | 
 | 158 |         """Setter for 'message'; needed only to override deprecation in | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 159 |         BaseException. | 
 | 160 |         """ | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 161 |         self.__message = value | 
 | 162 |  | 
 | 163 |     # BaseException.message has been deprecated since Python 2.6.  To prevent | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 164 |     # DeprecationWarning from popping up over this pre-existing attribute, use | 
 | 165 |     # a new property that takes lookup precedence. | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 166 |     message = property(_get_message, _set_message) | 
 | 167 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 168 |     def __init__(self, msg=''): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 169 |         self.message = msg | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 170 |         Exception.__init__(self, msg) | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 171 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 172 |     def __repr__(self): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 173 |         return self.message | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 174 |  | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 175 |     __str__ = __repr__ | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 176 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 177 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 178 | class NoSectionError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 179 |     """Raised when no section matches a requested option.""" | 
 | 180 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 181 |     def __init__(self, section): | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 182 |         Error.__init__(self, 'No section: %r' % (section,)) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 183 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 184 |         self.args = (section, ) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 185 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 186 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 187 | class DuplicateSectionError(Error): | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 188 |     """Raised when a section is repeated in an input source. | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 189 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 190 |     Possible repetitions that raise this exception are: multiple creation | 
 | 191 |     using the API or in strict parsers when a section is found more than once | 
 | 192 |     in a single input file, string or dictionary. | 
 | 193 |     """ | 
 | 194 |  | 
 | 195 |     def __init__(self, section, source=None, lineno=None): | 
 | 196 |         msg = [repr(section), " already exists"] | 
 | 197 |         if source is not None: | 
 | 198 |             message = ["While reading from ", source] | 
 | 199 |             if lineno is not None: | 
 | 200 |                 message.append(" [line {0:2d}]".format(lineno)) | 
 | 201 |             message.append(": section ") | 
 | 202 |             message.extend(msg) | 
 | 203 |             msg = message | 
 | 204 |         else: | 
 | 205 |             msg.insert(0, "Section ") | 
 | 206 |         Error.__init__(self, "".join(msg)) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 207 |         self.section = section | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 208 |         self.source = source | 
 | 209 |         self.lineno = lineno | 
 | 210 |         self.args = (section, source, lineno) | 
 | 211 |  | 
 | 212 |  | 
 | 213 | class DuplicateOptionError(Error): | 
 | 214 |     """Raised by strict parsers when an option is repeated in an input source. | 
 | 215 |  | 
 | 216 |     Current implementation raises this exception only when an option is found | 
 | 217 |     more than once in a single file, string or dictionary. | 
 | 218 |     """ | 
 | 219 |  | 
 | 220 |     def __init__(self, section, option, source=None, lineno=None): | 
 | 221 |         msg = [repr(option), " in section ", repr(section), | 
 | 222 |                " already exists"] | 
 | 223 |         if source is not None: | 
 | 224 |             message = ["While reading from ", source] | 
 | 225 |             if lineno is not None: | 
 | 226 |                 message.append(" [line {0:2d}]".format(lineno)) | 
 | 227 |             message.append(": option ") | 
 | 228 |             message.extend(msg) | 
 | 229 |             msg = message | 
 | 230 |         else: | 
 | 231 |             msg.insert(0, "Option ") | 
 | 232 |         Error.__init__(self, "".join(msg)) | 
 | 233 |         self.section = section | 
 | 234 |         self.option = option | 
 | 235 |         self.source = source | 
 | 236 |         self.lineno = lineno | 
 | 237 |         self.args = (section, option, source, lineno) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 238 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 239 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 240 | class NoOptionError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 241 |     """A requested option was not found.""" | 
 | 242 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 243 |     def __init__(self, option, section): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 244 |         Error.__init__(self, "No option %r in section: %r" % | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 245 |                        (option, section)) | 
 | 246 |         self.option = option | 
 | 247 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 248 |         self.args = (option, section) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 249 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 250 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 251 | class InterpolationError(Error): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 252 |     """Base class for interpolation-related exceptions.""" | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 253 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 254 |     def __init__(self, option, section, msg): | 
 | 255 |         Error.__init__(self, msg) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 256 |         self.option = option | 
 | 257 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 258 |         self.args = (option, section, msg) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 259 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 260 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 261 | class InterpolationMissingOptionError(InterpolationError): | 
 | 262 |     """A string substitution required a setting which was not available.""" | 
 | 263 |  | 
 | 264 |     def __init__(self, option, section, rawval, reference): | 
 | 265 |         msg = ("Bad value substitution:\n" | 
 | 266 |                "\tsection: [%s]\n" | 
 | 267 |                "\toption : %s\n" | 
 | 268 |                "\tkey    : %s\n" | 
 | 269 |                "\trawval : %s\n" | 
 | 270 |                % (section, option, reference, rawval)) | 
 | 271 |         InterpolationError.__init__(self, option, section, msg) | 
 | 272 |         self.reference = reference | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 273 |         self.args = (option, section, rawval, reference) | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 274 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 275 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 276 | class InterpolationSyntaxError(InterpolationError): | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 277 |     """Raised when the source text contains invalid syntax. | 
 | 278 |  | 
 | 279 |     Current implementation raises this exception only for SafeConfigParser | 
 | 280 |     instances when the source text into which substitutions are made | 
 | 281 |     does not conform to the required syntax. | 
 | 282 |     """ | 
| Neal Norwitz | ce1d944 | 2002-12-30 23:38:47 +0000 | [diff] [blame] | 283 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 284 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 285 | class InterpolationDepthError(InterpolationError): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 286 |     """Raised when substitutions are nested too deeply.""" | 
 | 287 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 288 |     def __init__(self, option, section, rawval): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 289 |         msg = ("Value interpolation too deeply recursive:\n" | 
 | 290 |                "\tsection: [%s]\n" | 
 | 291 |                "\toption : %s\n" | 
 | 292 |                "\trawval : %s\n" | 
 | 293 |                % (section, option, rawval)) | 
 | 294 |         InterpolationError.__init__(self, option, section, msg) | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 295 |         self.args = (option, section, rawval) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 296 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 297 |  | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 298 | class ParsingError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 299 |     """Raised when a configuration file does not follow legal syntax.""" | 
 | 300 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 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: %s' % source) | 
 | 312 |         self.source = source | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 313 |         self.errors = [] | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 314 |         self.args = (source, ) | 
 | 315 |  | 
 | 316 |     @property | 
 | 317 |     def filename(self): | 
 | 318 |         """Deprecated, use `source'.""" | 
 | 319 |         warnings.warn( | 
 | 320 |             "This 'filename' attribute will be removed in future versions.  " | 
 | 321 |             "Use 'source' instead.", | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 322 |             DeprecationWarning, stacklevel=2 | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 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 future versions.  " | 
 | 331 |             "Use 'source' instead.", | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 332 |             DeprecationWarning, stacklevel=2 | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 333 |         ) | 
 | 334 |         self.source = value | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 335 |  | 
 | 336 |     def append(self, lineno, line): | 
 | 337 |         self.errors.append((lineno, line)) | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 338 |         self.message += '\n\t[line %2d]: %s' % (lineno, line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 339 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 340 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 341 | class MissingSectionHeaderError(ParsingError): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 342 |     """Raised when a key-value pair is found before any section header.""" | 
 | 343 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 344 |     def __init__(self, filename, lineno, line): | 
 | 345 |         Error.__init__( | 
 | 346 |             self, | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 347 |             'File contains no section headers.\nfile: %s, line: %d\n%r' % | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 348 |             (filename, lineno, line)) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 349 |         self.source = filename | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 350 |         self.lineno = lineno | 
 | 351 |         self.line = line | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame] | 352 |         self.args = (filename, lineno, line) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 353 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 354 |  | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 355 | # Used in parsers to denote selecting a backwards-compatible inline comment | 
 | 356 | # character behavior (; and # are comments at the start of a line, but ; only | 
 | 357 | # inline) | 
 | 358 | _COMPATIBLE = object() | 
 | 359 |  | 
 | 360 | # Used in parser getters to indicate the default behaviour when a specific | 
 | 361 | # option is not found it to raise an exception. Created to enable `None' as | 
 | 362 | # a valid fallback value. | 
 | 363 | _UNSET = object() | 
 | 364 |  | 
 | 365 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 366 | class RawConfigParser(MutableMapping): | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 367 |     """ConfigParser that does not do interpolation.""" | 
 | 368 |  | 
 | 369 |     # Regular expressions for parsing section headers and options | 
 | 370 |     _SECT_TMPL = r""" | 
 | 371 |         \[                                 # [ | 
 | 372 |         (?P<header>[^]]+)                  # very permissive! | 
 | 373 |         \]                                 # ] | 
 | 374 |         """ | 
 | 375 |     _OPT_TMPL = r""" | 
 | 376 |         (?P<option>.*?)                    # very permissive! | 
 | 377 |         \s*(?P<vi>{delim})\s*              # any number of space/tab, | 
 | 378 |                                            # followed by any of the | 
 | 379 |                                            # allowed delimiters, | 
 | 380 |                                            # followed by any space/tab | 
 | 381 |         (?P<value>.*)$                     # everything up to eol | 
 | 382 |         """ | 
 | 383 |     _OPT_NV_TMPL = r""" | 
 | 384 |         (?P<option>.*?)                    # very permissive! | 
 | 385 |         \s*(?:                             # any number of space/tab, | 
 | 386 |         (?P<vi>{delim})\s*                 # optionally followed by | 
 | 387 |                                            # any of the allowed | 
 | 388 |                                            # delimiters, followed by any | 
 | 389 |                                            # space/tab | 
 | 390 |         (?P<value>.*))?$                   # everything up to eol | 
 | 391 |         """ | 
 | 392 |  | 
 | 393 |     # Compiled regular expression for matching sections | 
 | 394 |     SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE) | 
 | 395 |     # Compiled regular expression for matching options with typical separators | 
 | 396 |     OPTCRE = re.compile(_OPT_TMPL.format(delim="=|:"), re.VERBOSE) | 
 | 397 |     # Compiled regular expression for matching options with optional values | 
 | 398 |     # delimited using typical separators | 
 | 399 |     OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE) | 
 | 400 |     # Compiled regular expression for matching leading whitespace in a line | 
 | 401 |     NONSPACECRE = re.compile(r"\S") | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 402 |     # Possible boolean values in the configuration. | 
 | 403 |     BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True, | 
 | 404 |                       '0': False, 'no': False, 'false': False, 'off': False} | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 405 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 406 |     def __init__(self, defaults=None, dict_type=_default_dict, | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 407 |                  allow_no_value=False, *, delimiters=('=', ':'), | 
 | 408 |                  comment_prefixes=_COMPATIBLE, strict=False, | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 409 |                  empty_lines_in_values=True, | 
 | 410 |                  default_section=DEFAULTSECT): | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 411 |         self._dict = dict_type | 
 | 412 |         self._sections = self._dict() | 
 | 413 |         self._defaults = self._dict() | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 414 |         self._proxies = self._dict() | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 415 |         self._proxies[default_section] = SectionProxy(self, default_section) | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 416 |         if defaults: | 
 | 417 |             for key, value in defaults.items(): | 
 | 418 |                 self._defaults[self.optionxform(key)] = value | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 419 |         self._delimiters = tuple(delimiters) | 
 | 420 |         if delimiters == ('=', ':'): | 
 | 421 |             self._optcre = self.OPTCRE_NV if allow_no_value else self.OPTCRE | 
 | 422 |         else: | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 423 |             d = "|".join(re.escape(d) for d in delimiters) | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 424 |             if allow_no_value: | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 425 |                 self._optcre = re.compile(self._OPT_NV_TMPL.format(delim=d), | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 426 |                                           re.VERBOSE) | 
 | 427 |             else: | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 428 |                 self._optcre = re.compile(self._OPT_TMPL.format(delim=d), | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 429 |                                           re.VERBOSE) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 430 |         if comment_prefixes is _COMPATIBLE: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 431 |             self._startonly_comment_prefixes = ('#',) | 
 | 432 |             self._comment_prefixes = (';',) | 
 | 433 |         else: | 
 | 434 |             self._startonly_comment_prefixes = () | 
 | 435 |             self._comment_prefixes = tuple(comment_prefixes or ()) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 436 |         self._strict = strict | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 437 |         self._allow_no_value = allow_no_value | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 438 |         self._empty_lines_in_values = empty_lines_in_values | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 439 |         self._default_section=default_section | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 440 |  | 
 | 441 |     def defaults(self): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 442 |         return self._defaults | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 443 |  | 
 | 444 |     def sections(self): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 445 |         """Return a list of section names, excluding [DEFAULT]""" | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 446 |         # self._sections will never have [DEFAULT] in it | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 447 |         return list(self._sections.keys()) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 448 |  | 
 | 449 |     def add_section(self, section): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 450 |         """Create a new section in the configuration. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 451 |  | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 452 |         Raise DuplicateSectionError if a section by the specified name | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 453 |         already exists. Raise ValueError if name is DEFAULT. | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 454 |         """ | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 455 |         if section == self._default_section: | 
| Christian Heimes | 90c3d9b | 2008-02-23 13:18:03 +0000 | [diff] [blame] | 456 |             raise ValueError('Invalid section name: %s' % section) | 
 | 457 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 458 |         if section in self._sections: | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 459 |             raise DuplicateSectionError(section) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 460 |         self._sections[section] = self._dict() | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 461 |         self._proxies[section] = SectionProxy(self, section) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 462 |  | 
 | 463 |     def has_section(self, section): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 464 |         """Indicate whether the named section is present in the configuration. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 465 |  | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 466 |         The DEFAULT section is not acknowledged. | 
 | 467 |         """ | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 468 |         return section in self._sections | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 469 |  | 
 | 470 |     def options(self, section): | 
| Guido van Rossum | a5a24b7 | 1999-10-04 19:58:22 +0000 | [diff] [blame] | 471 |         """Return a list of option names for the given section name.""" | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 472 |         try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 473 |             opts = self._sections[section].copy() | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 474 |         except KeyError: | 
 | 475 |             raise NoSectionError(section) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 476 |         opts.update(self._defaults) | 
| Raymond Hettinger | 54f0222 | 2002-06-01 14:18:47 +0000 | [diff] [blame] | 477 |         if '__name__' in opts: | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 478 |             del opts['__name__'] | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 479 |         return list(opts.keys()) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 480 |  | 
| Georg Brandl | 8dcaa73 | 2010-07-29 12:17:40 +0000 | [diff] [blame] | 481 |     def read(self, filenames, encoding=None): | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 482 |         """Read and parse a filename or a list of filenames. | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 483 |  | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 484 |         Files that cannot be opened are silently ignored; this is | 
| Barry Warsaw | 2539451 | 1999-10-12 16:12:48 +0000 | [diff] [blame] | 485 |         designed so that you can specify a list of potential | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 486 |         configuration file locations (e.g. current directory, user's | 
 | 487 |         home directory, systemwide directory), and all existing | 
 | 488 |         configuration files in the list will be read.  A single | 
 | 489 |         filename may also be given. | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 490 |  | 
 | 491 |         Return list of successfully read files. | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 492 |         """ | 
| Guido van Rossum | 3172c5d | 2007-10-16 18:12:55 +0000 | [diff] [blame] | 493 |         if isinstance(filenames, str): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 494 |             filenames = [filenames] | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 495 |         read_ok = [] | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 496 |         for filename in filenames: | 
 | 497 |             try: | 
| Florent Xicluna | 42d5445 | 2010-09-22 22:35:38 +0000 | [diff] [blame] | 498 |                 with open(filename, encoding=encoding) as fp: | 
 | 499 |                     self._read(fp, filename) | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 500 |             except IOError: | 
 | 501 |                 continue | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 502 |             read_ok.append(filename) | 
 | 503 |         return read_ok | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 504 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 505 |     def read_file(self, f, source=None): | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 506 |         """Like read() but the argument must be a file-like object. | 
 | 507 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 508 |         The `f' argument must have a `readline' method.  Optional second | 
 | 509 |         argument is the `source' specifying the name of the file being read. If | 
 | 510 |         not given, it is taken from f.name. If `f' has no `name' attribute, | 
 | 511 |         `<???>' is used. | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 512 |         """ | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 513 |         if source is None: | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 514 |             try: | 
| Florent Xicluna | 42d5445 | 2010-09-22 22:35:38 +0000 | [diff] [blame] | 515 |                 source = f.name | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 516 |             except AttributeError: | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 517 |                 source = '<???>' | 
 | 518 |         self._read(f, source) | 
 | 519 |  | 
 | 520 |     def read_string(self, string, source='<string>'): | 
 | 521 |         """Read configuration from a given string.""" | 
 | 522 |         sfile = io.StringIO(string) | 
 | 523 |         self.read_file(sfile, source) | 
 | 524 |  | 
 | 525 |     def read_dict(self, dictionary, source='<dict>'): | 
 | 526 |         """Read configuration from a dictionary. | 
 | 527 |  | 
 | 528 |         Keys are section names, values are dictionaries with keys and values | 
 | 529 |         that should be present in the section. If the used dictionary type | 
 | 530 |         preserves order, sections and their keys will be added in order. | 
 | 531 |  | 
 | 532 |         Optional second argument is the `source' specifying the name of the | 
 | 533 |         dictionary being read. | 
 | 534 |         """ | 
 | 535 |         elements_added = set() | 
 | 536 |         for section, keys in dictionary.items(): | 
 | 537 |             try: | 
 | 538 |                 self.add_section(section) | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 539 |             except (DuplicateSectionError, ValueError): | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 540 |                 if self._strict and section in elements_added: | 
 | 541 |                     raise | 
 | 542 |                 elements_added.add(section) | 
 | 543 |             for key, value in keys.items(): | 
 | 544 |                 key = self.optionxform(key) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 545 |                 if value is not None: | 
 | 546 |                     value = str(value) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 547 |                 if self._strict and (section, key) in elements_added: | 
 | 548 |                     raise DuplicateOptionError(section, key, source) | 
 | 549 |                 elements_added.add((section, key)) | 
 | 550 |                 self.set(section, key, value) | 
 | 551 |  | 
 | 552 |     def readfp(self, fp, filename=None): | 
 | 553 |         """Deprecated, use read_file instead.""" | 
 | 554 |         warnings.warn( | 
 | 555 |             "This method will be removed in future versions.  " | 
 | 556 |             "Use 'parser.read_file()' instead.", | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 557 |             DeprecationWarning, stacklevel=2 | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 558 |         ) | 
 | 559 |         self.read_file(fp, source=filename) | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 560 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 561 |     def get(self, section, option, *, vars=None, fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 562 |         """Get an option value for a given section. | 
 | 563 |  | 
 | 564 |         If `vars' is provided, it must be a dictionary. The option is looked up | 
 | 565 |         in `vars' (if provided), `section', and in `DEFAULTSECT' in that order. | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 566 |         If the key is not found and `fallback' is provided, it is used as | 
 | 567 |         a fallback value. `None' can be provided as a `fallback' value. | 
 | 568 |  | 
 | 569 |         Arguments `vars' and `fallback' are keyword only. | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 570 |         """ | 
 | 571 |         try: | 
 | 572 |             d = self._unify_values(section, vars) | 
 | 573 |         except NoSectionError: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 574 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 575 |                 raise | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 576 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 577 |                 return fallback | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 578 |         option = self.optionxform(option) | 
 | 579 |         try: | 
 | 580 |             return d[option] | 
 | 581 |         except KeyError: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 582 |             if fallback is _UNSET: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 583 |                 raise NoOptionError(option, section) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 584 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 585 |                 return fallback | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 586 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 587 |     def items(self, section): | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 588 |         try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 589 |             d2 = self._sections[section] | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 590 |         except KeyError: | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 591 |             if section != self._default_section: | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 592 |                 raise NoSectionError(section) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 593 |             d2 = self._dict() | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 594 |         d = self._defaults.copy() | 
 | 595 |         d.update(d2) | 
| Fred Drake | df393bd | 2002-10-25 20:41:30 +0000 | [diff] [blame] | 596 |         if "__name__" in d: | 
 | 597 |             del d["__name__"] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 598 |         return d.items() | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 599 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 600 |     def _get(self, section, conv, option, **kwargs): | 
 | 601 |         return conv(self.get(section, option, **kwargs)) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 602 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 603 |     def getint(self, section, option, *, vars=None, fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 604 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 605 |             return self._get(section, int, option, vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 606 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 607 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 608 |                 raise | 
 | 609 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 610 |                 return fallback | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 611 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 612 |     def getfloat(self, section, option, *, vars=None, fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 613 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 614 |             return self._get(section, float, option, vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 615 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 616 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 617 |                 raise | 
 | 618 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 619 |                 return fallback | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 620 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 621 |     def getboolean(self, section, option, *, vars=None, fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 622 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 623 |             return self._get(section, self._convert_to_boolean, option, | 
 | 624 |                              vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 625 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 626 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 627 |                 raise | 
 | 628 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 629 |                 return fallback | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 630 |  | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 631 |     def optionxform(self, optionstr): | 
| Eric S. Raymond | 9eb54d9 | 2001-02-09 05:19:09 +0000 | [diff] [blame] | 632 |         return optionstr.lower() | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 633 |  | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 634 |     def has_option(self, section, option): | 
 | 635 |         """Check for the existence of a given option in a given section.""" | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 636 |         if not section or section == self._default_section: | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 637 |             option = self.optionxform(option) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 638 |             return option in self._defaults | 
 | 639 |         elif section not in self._sections: | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 640 |             return False | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 641 |         else: | 
| Fred Drake | 3c823aa | 2001-02-26 21:55:34 +0000 | [diff] [blame] | 642 |             option = self.optionxform(option) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 643 |             return (option in self._sections[section] | 
 | 644 |                     or option in self._defaults) | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 645 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 646 |     def set(self, section, option, value=None): | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 647 |         """Set an option.""" | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 648 |         if not section or section == self._default_section: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 649 |             sectdict = self._defaults | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 650 |         else: | 
 | 651 |             try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 652 |                 sectdict = self._sections[section] | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 653 |             except KeyError: | 
 | 654 |                 raise NoSectionError(section) | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 655 |         sectdict[self.optionxform(option)] = value | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 656 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 657 |     def write(self, fp, space_around_delimiters=True): | 
 | 658 |         """Write an .ini-format representation of the configuration state. | 
 | 659 |  | 
 | 660 |         If `space_around_delimiters' is True (the default), delimiters | 
 | 661 |         between keys and values are surrounded by spaces. | 
 | 662 |         """ | 
 | 663 |         if space_around_delimiters: | 
 | 664 |             d = " {} ".format(self._delimiters[0]) | 
 | 665 |         else: | 
 | 666 |             d = self._delimiters[0] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 667 |         if self._defaults: | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 668 |             self._write_section(fp, self._default_section, | 
 | 669 |                                     self._defaults.items(), d) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 670 |         for section in self._sections: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 671 |             self._write_section(fp, section, | 
 | 672 |                                 self._sections[section].items(), d) | 
 | 673 |  | 
 | 674 |     def _write_section(self, fp, section_name, section_items, delimiter): | 
 | 675 |         """Write a single section to the specified `fp'.""" | 
 | 676 |         fp.write("[{}]\n".format(section_name)) | 
 | 677 |         for key, value in section_items: | 
 | 678 |             if key == "__name__": | 
 | 679 |                 continue | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 680 |             if value is not None or not self._allow_no_value: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 681 |                 value = delimiter + str(value).replace('\n', '\n\t') | 
 | 682 |             else: | 
 | 683 |                 value = "" | 
 | 684 |             fp.write("{}{}\n".format(key, value)) | 
 | 685 |         fp.write("\n") | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 686 |  | 
| Thomas Wouters | ff4df6d | 2000-07-21 05:19:59 +0000 | [diff] [blame] | 687 |     def remove_option(self, section, option): | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 688 |         """Remove an option.""" | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 689 |         if not section or section == self._default_section: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 690 |             sectdict = self._defaults | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 691 |         else: | 
 | 692 |             try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 693 |                 sectdict = self._sections[section] | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 694 |             except KeyError: | 
 | 695 |                 raise NoSectionError(section) | 
| Fred Drake | 3c823aa | 2001-02-26 21:55:34 +0000 | [diff] [blame] | 696 |         option = self.optionxform(option) | 
| Raymond Hettinger | 54f0222 | 2002-06-01 14:18:47 +0000 | [diff] [blame] | 697 |         existed = option in sectdict | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 698 |         if existed: | 
| Fred Drake | ff4a23b | 2000-12-04 16:29:13 +0000 | [diff] [blame] | 699 |             del sectdict[option] | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 700 |         return existed | 
 | 701 |  | 
| Thomas Wouters | ff4df6d | 2000-07-21 05:19:59 +0000 | [diff] [blame] | 702 |     def remove_section(self, section): | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 703 |         """Remove a file section.""" | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 704 |         existed = section in self._sections | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 705 |         if existed: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 706 |             del self._sections[section] | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 707 |             del self._proxies[section] | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 708 |         return existed | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 709 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 710 |     def __getitem__(self, key): | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 711 |         if key != self._default_section and not self.has_section(key): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 712 |             raise KeyError(key) | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 713 |         return self._proxies[key] | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 714 |  | 
 | 715 |     def __setitem__(self, key, value): | 
 | 716 |         # To conform with the mapping protocol, overwrites existing values in | 
 | 717 |         # the section. | 
 | 718 |  | 
 | 719 |         # XXX this is not atomic if read_dict fails at any point. Then again, | 
 | 720 |         # no update method in configparser is atomic in this implementation. | 
 | 721 |         self.remove_section(key) | 
 | 722 |         self.read_dict({key: value}) | 
 | 723 |  | 
 | 724 |     def __delitem__(self, key): | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 725 |         if key == self._default_section: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 726 |             raise ValueError("Cannot remove the default section.") | 
 | 727 |         if not self.has_section(key): | 
 | 728 |             raise KeyError(key) | 
 | 729 |         self.remove_section(key) | 
 | 730 |  | 
 | 731 |     def __contains__(self, key): | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 732 |         return key == self._default_section or self.has_section(key) | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 733 |  | 
 | 734 |     def __len__(self): | 
 | 735 |         return len(self._sections) + 1 # the default section | 
 | 736 |  | 
 | 737 |     def __iter__(self): | 
 | 738 |         # XXX does it break when underlying container state changed? | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 739 |         return itertools.chain((self._default_section,), self._sections.keys()) | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 740 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 741 |     def _read(self, fp, fpname): | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 742 |         """Parse a sectioned configuration file. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 743 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 744 |         Each section in a configuration file contains a header, indicated by | 
 | 745 |         a name in square brackets (`[]'), plus key/value options, indicated by | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 746 |         `name' and `value' delimited with a specific substring (`=' or `:' by | 
 | 747 |         default). | 
 | 748 |  | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 749 |         Values can span multiple lines, as long as they are indented deeper | 
 | 750 |         than the first line of the value. Depending on the parser's mode, blank | 
 | 751 |         lines may be treated as parts of multiline values or ignored. | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 752 |  | 
 | 753 |         Configuration files may include comments, prefixed by specific | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 754 |         characters (`#' and `;' by default). Comments may appear on their own | 
 | 755 |         in an otherwise empty line or may be entered in lines holding values or | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 756 |         section names. | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 757 |         """ | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 758 |         elements_added = set() | 
| Brian Curtin | 9a27b0c | 2010-07-26 00:27:10 +0000 | [diff] [blame] | 759 |         cursect = None                        # None, or a dictionary | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 760 |         sectname = None | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 761 |         optname = None | 
 | 762 |         lineno = 0 | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 763 |         indent_level = 0 | 
| Brian Curtin | 9a27b0c | 2010-07-26 00:27:10 +0000 | [diff] [blame] | 764 |         e = None                              # None, or an exception | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 765 |         for lineno, line in enumerate(fp, start=1): | 
| Georg Brandl | f206d0e | 2010-07-29 11:56:20 +0000 | [diff] [blame] | 766 |             # strip full line comments | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 767 |             comment_start = None | 
 | 768 |             for prefix in self._startonly_comment_prefixes: | 
 | 769 |                 if line.strip().startswith(prefix): | 
 | 770 |                     comment_start = 0 | 
 | 771 |                     break | 
 | 772 |             # strip inline comments | 
 | 773 |             for prefix in self._comment_prefixes: | 
 | 774 |                 index = line.find(prefix) | 
 | 775 |                 if index == 0 or (index > 0 and line[index-1].isspace()): | 
 | 776 |                     comment_start = index | 
 | 777 |                     break | 
 | 778 |             value = line[:comment_start].strip() | 
 | 779 |             if not value: | 
| Georg Brandl | f206d0e | 2010-07-29 11:56:20 +0000 | [diff] [blame] | 780 |                 if self._empty_lines_in_values: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 781 |                     # add empty line to the value, but only if there was no | 
 | 782 |                     # comment on the line | 
| Georg Brandl | f206d0e | 2010-07-29 11:56:20 +0000 | [diff] [blame] | 783 |                     if (comment_start is None and | 
 | 784 |                         cursect is not None and | 
 | 785 |                         optname and | 
 | 786 |                         cursect[optname] is not None): | 
 | 787 |                         cursect[optname].append('') # newlines added at join | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 788 |                 else: | 
 | 789 |                     # empty line marks end of value | 
 | 790 |                     indent_level = sys.maxsize | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 791 |                 continue | 
 | 792 |             # continuation line? | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 793 |             first_nonspace = self.NONSPACECRE.search(line) | 
 | 794 |             cur_indent_level = first_nonspace.start() if first_nonspace else 0 | 
 | 795 |             if (cursect is not None and optname and | 
 | 796 |                 cur_indent_level > indent_level): | 
 | 797 |                 cursect[optname].append(value) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 798 |             # a section header or option header? | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 799 |             else: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 800 |                 indent_level = cur_indent_level | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 801 |                 # is it a section header? | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 802 |                 mo = self.SECTCRE.match(value) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 803 |                 if mo: | 
 | 804 |                     sectname = mo.group('header') | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 805 |                     if sectname in self._sections: | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 806 |                         if self._strict and sectname in elements_added: | 
 | 807 |                             raise DuplicateSectionError(sectname, fpname, | 
 | 808 |                                                         lineno) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 809 |                         cursect = self._sections[sectname] | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 810 |                         elements_added.add(sectname) | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 811 |                     elif sectname == self._default_section: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 812 |                         cursect = self._defaults | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 813 |                     else: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 814 |                         cursect = self._dict() | 
 | 815 |                         cursect['__name__'] = sectname | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 816 |                         self._sections[sectname] = cursect | 
| Łukasz Langa | 49afa38 | 2010-11-11 19:53:23 +0000 | [diff] [blame] | 817 |                         self._proxies[sectname] = SectionProxy(self, sectname) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 818 |                         elements_added.add(sectname) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 819 |                     # So sections can't start with a continuation line | 
 | 820 |                     optname = None | 
 | 821 |                 # no section header in the file? | 
 | 822 |                 elif cursect is None: | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 823 |                     raise MissingSectionHeaderError(fpname, lineno, line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 824 |                 # an option line? | 
 | 825 |                 else: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 826 |                     mo = self._optcre.match(value) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 827 |                     if mo: | 
| Fred Drake | c517b9b | 2000-02-28 20:59:03 +0000 | [diff] [blame] | 828 |                         optname, vi, optval = mo.group('option', 'vi', 'value') | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 829 |                         if not optname: | 
 | 830 |                             e = self._handle_error(e, fpname, lineno, line) | 
| Brian Curtin | 9a27b0c | 2010-07-26 00:27:10 +0000 | [diff] [blame] | 831 |                         optname = self.optionxform(optname.rstrip()) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 832 |                         if (self._strict and | 
 | 833 |                             (sectname, optname) in elements_added): | 
 | 834 |                             raise DuplicateOptionError(sectname, optname, | 
 | 835 |                                                        fpname, lineno) | 
 | 836 |                         elements_added.add((sectname, optname)) | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 837 |                         # This check is fine because the OPTCRE cannot | 
 | 838 |                         # match if it would set optval to None | 
 | 839 |                         if optval is not None: | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 840 |                             optval = optval.strip() | 
| Brian Curtin | 9a27b0c | 2010-07-26 00:27:10 +0000 | [diff] [blame] | 841 |                             # allow empty values | 
 | 842 |                             if optval == '""': | 
 | 843 |                                 optval = '' | 
 | 844 |                             cursect[optname] = [optval] | 
 | 845 |                         else: | 
 | 846 |                             # valueless option handling | 
 | 847 |                             cursect[optname] = optval | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 848 |                     else: | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 849 |                         # a non-fatal parsing error occurred. set up the | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 850 |                         # exception but keep going. the exception will be | 
 | 851 |                         # raised at the end of the file and will contain a | 
 | 852 |                         # list of all bogus lines | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 853 |                         e = self._handle_error(e, fpname, lineno, line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 854 |         # if any parsing errors occurred, raise an exception | 
 | 855 |         if e: | 
 | 856 |             raise e | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 857 |         self._join_multiline_values() | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 858 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 859 |     def _join_multiline_values(self): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 860 |         all_sections = itertools.chain((self._defaults,), | 
 | 861 |                                        self._sections.values()) | 
| Brian Curtin | 9a27b0c | 2010-07-26 00:27:10 +0000 | [diff] [blame] | 862 |         for options in all_sections: | 
 | 863 |             for name, val in options.items(): | 
 | 864 |                 if isinstance(val, list): | 
| Georg Brandl | f206d0e | 2010-07-29 11:56:20 +0000 | [diff] [blame] | 865 |                     options[name] = '\n'.join(val).rstrip() | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 866 |  | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 867 |     def _handle_error(self, exc, fpname, lineno, line): | 
 | 868 |         if not exc: | 
 | 869 |             exc = ParsingError(fpname) | 
 | 870 |         exc.append(lineno, repr(line)) | 
 | 871 |         return exc | 
 | 872 |  | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 873 |     def _unify_values(self, section, vars): | 
 | 874 |         """Create a copy of the DEFAULTSECT with values from a specific | 
 | 875 |         `section' and the `vars' dictionary. If provided, values in `vars' | 
 | 876 |         take precendence. | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 877 |         """ | 
 | 878 |         d = self._defaults.copy() | 
 | 879 |         try: | 
 | 880 |             d.update(self._sections[section]) | 
 | 881 |         except KeyError: | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 882 |             if section != self._default_section: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 883 |                 raise NoSectionError(section) | 
 | 884 |         # Update with the entry specific variables | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 885 |         if vars: | 
 | 886 |             for key, value in vars.items(): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 887 |                 if value is not None: | 
 | 888 |                     value = str(value) | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 889 |                 d[self.optionxform(key)] = value | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 890 |         return d | 
 | 891 |  | 
 | 892 |     def _convert_to_boolean(self, value): | 
 | 893 |         """Return a boolean value translating from other types if necessary. | 
 | 894 |         """ | 
 | 895 |         if value.lower() not in self.BOOLEAN_STATES: | 
 | 896 |             raise ValueError('Not a boolean: %s' % value) | 
 | 897 |         return self.BOOLEAN_STATES[value.lower()] | 
 | 898 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 899 |     def _validate_value_type(self, value): | 
 | 900 |         """Raises a TypeError for non-string values. | 
 | 901 |  | 
 | 902 |         The only legal non-string value if we allow valueless | 
 | 903 |         options is None, so we need to check if the value is a | 
 | 904 |         string if: | 
 | 905 |         - we do not allow valueless options, or | 
 | 906 |         - we allow valueless options but the value is not None | 
 | 907 |  | 
 | 908 |         For compatibility reasons this method is not used in classic set() | 
 | 909 |         for RawConfigParsers and ConfigParsers. It is invoked in every | 
 | 910 |         case for mapping protocol access and in SafeConfigParser.set(). | 
 | 911 |         """ | 
 | 912 |         if not self._allow_no_value or value: | 
 | 913 |             if not isinstance(value, str): | 
 | 914 |                 raise TypeError("option values must be strings") | 
 | 915 |  | 
 | 916 |  | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 917 |  | 
 | 918 | class ConfigParser(RawConfigParser): | 
 | 919 |     """ConfigParser implementing interpolation.""" | 
 | 920 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 921 |     def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 922 |         """Get an option value for a given section. | 
 | 923 |  | 
 | 924 |         If `vars' is provided, it must be a dictionary. The option is looked up | 
 | 925 |         in `vars' (if provided), `section', and in `DEFAULTSECT' in that order. | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 926 |         If the key is not found and `fallback' is provided, it is used as | 
 | 927 |         a fallback value. `None' can be provided as a `fallback' value. | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 928 |  | 
 | 929 |         All % interpolations are expanded in the return values, unless the | 
 | 930 |         optional argument `raw' is true.  Values for interpolation keys are | 
 | 931 |         looked up in the same manner as the option. | 
 | 932 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 933 |         Arguments `raw', `vars', and `fallback' are keyword only. | 
 | 934 |  | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 935 |         The section DEFAULT is special. | 
 | 936 |         """ | 
 | 937 |         try: | 
 | 938 |             d = self._unify_values(section, vars) | 
 | 939 |         except NoSectionError: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 940 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 941 |                 raise | 
 | 942 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 943 |                 return fallback | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 944 |         option = self.optionxform(option) | 
 | 945 |         try: | 
 | 946 |             value = d[option] | 
 | 947 |         except KeyError: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 948 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 949 |                 raise NoOptionError(option, section) | 
 | 950 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 951 |                 return fallback | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 952 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 953 |         if raw or value is None: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 954 |             return value | 
 | 955 |         else: | 
 | 956 |             return self._interpolate(section, option, value, d) | 
 | 957 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 958 |     def getint(self, section, option, *, raw=False, vars=None, | 
 | 959 |                fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 960 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 961 |             return self._get(section, int, option, raw=raw, vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 962 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 963 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 964 |                 raise | 
 | 965 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 966 |                 return fallback | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 967 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 968 |     def getfloat(self, section, option, *, raw=False, vars=None, | 
 | 969 |                  fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 970 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 971 |             return self._get(section, float, option, raw=raw, vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 972 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 973 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 974 |                 raise | 
 | 975 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 976 |                 return fallback | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 977 |  | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 978 |     def getboolean(self, section, option, *, raw=False, vars=None, | 
 | 979 |                    fallback=_UNSET): | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 980 |         try: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 981 |             return self._get(section, self._convert_to_boolean, option, | 
 | 982 |                              raw=raw, vars=vars) | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 983 |         except (NoSectionError, NoOptionError): | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 984 |             if fallback is _UNSET: | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 985 |                 raise | 
 | 986 |             else: | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 987 |                 return fallback | 
| Fred Drake | cc645b9 | 2010-09-04 04:35:34 +0000 | [diff] [blame] | 988 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 989 |     def items(self, section, raw=False, vars=None): | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 990 |         """Return a list of (name, value) tuples for each option in a section. | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 991 |  | 
 | 992 |         All % interpolations are expanded in the return values, based on the | 
 | 993 |         defaults passed into the constructor, unless the optional argument | 
 | 994 |         `raw' is true.  Additional substitutions may be provided using the | 
 | 995 |         `vars' argument, which must be a dictionary whose contents overrides | 
 | 996 |         any pre-existing defaults. | 
 | 997 |  | 
 | 998 |         The section DEFAULT is special. | 
 | 999 |         """ | 
 | 1000 |         d = self._defaults.copy() | 
 | 1001 |         try: | 
 | 1002 |             d.update(self._sections[section]) | 
 | 1003 |         except KeyError: | 
| Łukasz Langa | c264c09 | 2010-11-20 16:15:37 +0000 | [diff] [blame^] | 1004 |             if section != self._default_section: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1005 |                 raise NoSectionError(section) | 
 | 1006 |         # Update with the entry specific variables | 
 | 1007 |         if vars: | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 1008 |             for key, value in vars.items(): | 
 | 1009 |                 d[self.optionxform(key)] = value | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 1010 |         options = list(d.keys()) | 
| Fred Drake | df393bd | 2002-10-25 20:41:30 +0000 | [diff] [blame] | 1011 |         if "__name__" in options: | 
 | 1012 |             options.remove("__name__") | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1013 |         if raw: | 
| Fred Drake | 8c4da53 | 2003-10-21 16:45:00 +0000 | [diff] [blame] | 1014 |             return [(option, d[option]) | 
 | 1015 |                     for option in options] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1016 |         else: | 
| Fred Drake | 8c4da53 | 2003-10-21 16:45:00 +0000 | [diff] [blame] | 1017 |             return [(option, self._interpolate(section, option, d[option], d)) | 
 | 1018 |                     for option in options] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1019 |  | 
 | 1020 |     def _interpolate(self, section, option, rawval, vars): | 
 | 1021 |         # do the string interpolation | 
 | 1022 |         value = rawval | 
| Tim Peters | 230a60c | 2002-11-09 05:08:07 +0000 | [diff] [blame] | 1023 |         depth = MAX_INTERPOLATION_DEPTH | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1024 |         while depth:                    # Loop through this until it's done | 
 | 1025 |             depth -= 1 | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 1026 |             if value and "%(" in value: | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 1027 |                 value = self._KEYCRE.sub(self._interpolation_replace, value) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1028 |                 try: | 
 | 1029 |                     value = value % vars | 
| Guido van Rossum | b940e11 | 2007-01-10 16:19:56 +0000 | [diff] [blame] | 1030 |                 except KeyError as e: | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 1031 |                     raise InterpolationMissingOptionError( | 
| Brett Cannon | ca477b2 | 2007-03-21 22:26:20 +0000 | [diff] [blame] | 1032 |                         option, section, rawval, e.args[0]) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1033 |             else: | 
 | 1034 |                 break | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 1035 |         if value and "%(" in value: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 1036 |             raise InterpolationDepthError(option, section, rawval) | 
 | 1037 |         return value | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1038 |  | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 1039 |     _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") | 
 | 1040 |  | 
 | 1041 |     def _interpolation_replace(self, match): | 
 | 1042 |         s = match.group(1) | 
 | 1043 |         if s is None: | 
 | 1044 |             return match.group() | 
 | 1045 |         else: | 
 | 1046 |             return "%%(%s)s" % self.optionxform(s) | 
 | 1047 |  | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1048 |  | 
 | 1049 | class SafeConfigParser(ConfigParser): | 
| Georg Brandl | 96a60ae | 2010-07-28 13:13:46 +0000 | [diff] [blame] | 1050 |     """ConfigParser implementing sane interpolation.""" | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1051 |  | 
 | 1052 |     def _interpolate(self, section, option, rawval, vars): | 
 | 1053 |         # do the string interpolation | 
 | 1054 |         L = [] | 
 | 1055 |         self._interpolate_some(option, L, rawval, section, vars, 1) | 
 | 1056 |         return ''.join(L) | 
 | 1057 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1058 |     _interpvar_re = re.compile(r"%\(([^)]+)\)s") | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1059 |  | 
 | 1060 |     def _interpolate_some(self, option, accum, rest, section, map, depth): | 
 | 1061 |         if depth > MAX_INTERPOLATION_DEPTH: | 
 | 1062 |             raise InterpolationDepthError(option, section, rest) | 
 | 1063 |         while rest: | 
 | 1064 |             p = rest.find("%") | 
 | 1065 |             if p < 0: | 
 | 1066 |                 accum.append(rest) | 
 | 1067 |                 return | 
 | 1068 |             if p > 0: | 
 | 1069 |                 accum.append(rest[:p]) | 
 | 1070 |                 rest = rest[p:] | 
 | 1071 |             # p is no longer used | 
 | 1072 |             c = rest[1:2] | 
 | 1073 |             if c == "%": | 
 | 1074 |                 accum.append("%") | 
 | 1075 |                 rest = rest[2:] | 
 | 1076 |             elif c == "(": | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1077 |                 m = self._interpvar_re.match(rest) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1078 |                 if m is None: | 
| Neal Norwitz | 10f3018 | 2003-06-29 04:23:35 +0000 | [diff] [blame] | 1079 |                     raise InterpolationSyntaxError(option, section, | 
 | 1080 |                         "bad interpolation variable reference %r" % rest) | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 1081 |                 var = self.optionxform(m.group(1)) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1082 |                 rest = rest[m.end():] | 
 | 1083 |                 try: | 
 | 1084 |                     v = map[var] | 
 | 1085 |                 except KeyError: | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 1086 |                     raise InterpolationMissingOptionError( | 
 | 1087 |                         option, section, rest, var) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 1088 |                 if "%" in v: | 
 | 1089 |                     self._interpolate_some(option, accum, v, | 
 | 1090 |                                            section, map, depth + 1) | 
 | 1091 |                 else: | 
 | 1092 |                     accum.append(v) | 
 | 1093 |             else: | 
 | 1094 |                 raise InterpolationSyntaxError( | 
| Neal Norwitz | 10f3018 | 2003-06-29 04:23:35 +0000 | [diff] [blame] | 1095 |                     option, section, | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 1096 |                     "'%%' must be followed by '%%' or '(', " | 
 | 1097 |                     "found: %r" % (rest,)) | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 1098 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 1099 |     def set(self, section, option, value=None): | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 1100 |         """Set an option.  Extend ConfigParser.set: check for string values.""" | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 1101 |         self._validate_value_type(value) | 
| Fred Drake | a492362 | 2010-08-09 12:52:45 +0000 | [diff] [blame] | 1102 |         # check for bad percent signs | 
 | 1103 |         if value: | 
 | 1104 |             tmp_value = value.replace('%%', '') # escaped percent signs | 
 | 1105 |             tmp_value = self._interpvar_re.sub('', tmp_value) # valid syntax | 
 | 1106 |             if '%' in tmp_value: | 
 | 1107 |                 raise ValueError("invalid interpolation syntax in %r at " | 
 | 1108 |                                 "position %d" % (value, tmp_value.find('%'))) | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 1109 |         ConfigParser.set(self, section, option, value) | 
| Łukasz Langa | 26d513c | 2010-11-10 18:57:39 +0000 | [diff] [blame] | 1110 |  | 
 | 1111 |  | 
 | 1112 | class SectionProxy(MutableMapping): | 
 | 1113 |     """A proxy for a single section from a parser.""" | 
 | 1114 |  | 
 | 1115 |     _noname = ("__name__ special key access and modification " | 
 | 1116 |                "not supported through the mapping interface.") | 
 | 1117 |  | 
 | 1118 |     def __init__(self, parser, section_name): | 
 | 1119 |         """Creates a view on a section named `section_name` in `parser`.""" | 
 | 1120 |         self._parser = parser | 
 | 1121 |         self._section = section_name | 
 | 1122 |         self.getint = functools.partial(self._parser.getint, | 
 | 1123 |                                         self._section) | 
 | 1124 |         self.getfloat = functools.partial(self._parser.getfloat, | 
 | 1125 |                                           self._section) | 
 | 1126 |         self.getboolean = functools.partial(self._parser.getboolean, | 
 | 1127 |                                             self._section) | 
 | 1128 |  | 
 | 1129 |     def __repr__(self): | 
 | 1130 |         return '<Section: {}>'.format(self._section) | 
 | 1131 |  | 
 | 1132 |     def __getitem__(self, key): | 
 | 1133 |         if key == '__name__': | 
 | 1134 |             raise ValueError(self._noname) | 
 | 1135 |         if not self._parser.has_option(self._section, key): | 
 | 1136 |             raise KeyError(key) | 
 | 1137 |         return self._parser.get(self._section, key) | 
 | 1138 |  | 
 | 1139 |     def __setitem__(self, key, value): | 
 | 1140 |         if key == '__name__': | 
 | 1141 |             raise ValueError(self._noname) | 
 | 1142 |         self._parser._validate_value_type(value) | 
 | 1143 |         return self._parser.set(self._section, key, value) | 
 | 1144 |  | 
 | 1145 |     def __delitem__(self, key): | 
 | 1146 |         if key == '__name__': | 
 | 1147 |             raise ValueError(self._noname) | 
 | 1148 |         if not self._parser.has_option(self._section, key): | 
 | 1149 |             raise KeyError(key) | 
 | 1150 |         return self._parser.remove_option(self._section, key) | 
 | 1151 |  | 
 | 1152 |     def __contains__(self, key): | 
 | 1153 |         if key == '__name__': | 
 | 1154 |             return False | 
 | 1155 |         return self._parser.has_option(self._section, key) | 
 | 1156 |  | 
 | 1157 |     def __len__(self): | 
 | 1158 |         # __name__ is properly hidden by .options() | 
 | 1159 |         # XXX weak performance | 
 | 1160 |         return len(self._parser.options(self._section)) | 
 | 1161 |  | 
 | 1162 |     def __iter__(self): | 
 | 1163 |         # __name__ is properly hidden by .options() | 
 | 1164 |         # XXX weak performance | 
 | 1165 |         # XXX does not break when underlying container state changed | 
 | 1166 |         return self._parser.options(self._section).__iter__() |