| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 1 | """Configuration file parser. | 
 | 2 |  | 
 | 3 | A setup file consists of sections, lead by a "[section]" header, | 
 | 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 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 27 |     __init__(defaults=None) | 
 | 28 |         create the parser and specify a dictionary of intrinsic defaults.  The | 
 | 29 |         keys must be strings, the values must be appropriate for %()s string | 
 | 30 |         interpolation.  Note that `__name__' is always an intrinsic default; | 
| Georg Brandl | 7eb4b7d | 2005-07-22 21:49:32 +0000 | [diff] [blame] | 31 |         its value is the section's name. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 32 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 33 |     sections() | 
 | 34 |         return all the configuration section names, sans DEFAULT | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 35 |  | 
| Guido van Rossum | a5a24b7 | 1999-10-04 19:58:22 +0000 | [diff] [blame] | 36 |     has_section(section) | 
 | 37 |         return whether the given section exists | 
 | 38 |  | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 39 |     has_option(section, option) | 
 | 40 |         return whether the given option exists in the given section | 
 | 41 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 42 |     options(section) | 
 | 43 |         return list of configuration options for the named section | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 44 |  | 
| Guido van Rossum | c0780ac | 1999-01-30 04:35:47 +0000 | [diff] [blame] | 45 |     read(filenames) | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 46 |         read and parse the list of named configuration files, given by | 
 | 47 |         name.  A single filename is also allowed.  Non-existing files | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 48 |         are ignored.  Return list of successfully read files. | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 49 |  | 
 | 50 |     readfp(fp, filename=None) | 
 | 51 |         read and parse one configuration file, given as a file object. | 
 | 52 |         The filename defaults to fp.name; it is only used in error | 
| Barry Warsaw | 2539451 | 1999-10-12 16:12:48 +0000 | [diff] [blame] | 53 |         messages (if fp has no `name' attribute, the string `<???>' is used). | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 54 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 55 |     get(section, option, raw=False, vars=None) | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 56 |         return a string value for the named option.  All % interpolations are | 
 | 57 |         expanded in the return values, based on the defaults passed into the | 
 | 58 |         constructor and the DEFAULT section.  Additional substitutions may be | 
 | 59 |         provided using the `vars' argument, which must be a dictionary whose | 
 | 60 |         contents override any pre-existing defaults. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 61 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 62 |     getint(section, options) | 
 | 63 |         like get(), but convert value to an integer | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 64 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 65 |     getfloat(section, options) | 
 | 66 |         like get(), but convert value to a float | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 67 |  | 
| Barry Warsaw | f09f6a5 | 1999-01-26 22:01:37 +0000 | [diff] [blame] | 68 |     getboolean(section, options) | 
| Guido van Rossum | fb06f75 | 2001-10-04 19:58:46 +0000 | [diff] [blame] | 69 |         like get(), but convert value to a boolean (currently case | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 70 |         insensitively defined as 0, false, no, off for False, and 1, true, | 
 | 71 |         yes, on for True).  Returns False or True. | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 72 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 73 |     items(section, raw=False, vars=None) | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 74 |         return a list of tuples with (name, value) for each option | 
 | 75 |         in the section. | 
 | 76 |  | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 77 |     remove_section(section) | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 78 |         remove the given file section and all its options | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 79 |  | 
 | 80 |     remove_option(section, option) | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 81 |         remove the given option from the given section | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 82 |  | 
 | 83 |     set(section, option, value) | 
 | 84 |         set the given option | 
 | 85 |  | 
 | 86 |     write(fp) | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 87 |         write the configuration state in .ini format | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 88 | """ | 
 | 89 |  | 
| Raymond Hettinger | ff23e8c | 2009-03-03 01:32:48 +0000 | [diff] [blame] | 90 | try: | 
 | 91 |     from collections import OrderedDict as _default_dict | 
 | 92 | except ImportError: | 
 | 93 |     # fallback for setup.py which hasn't yet built _collections | 
 | 94 |     _default_dict = dict | 
 | 95 |  | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 96 | import re | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 97 |  | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 98 | __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", | 
 | 99 |            "InterpolationError", "InterpolationDepthError", | 
 | 100 |            "InterpolationSyntaxError", "ParsingError", | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 101 |            "MissingSectionHeaderError", | 
 | 102 |            "ConfigParser", "SafeConfigParser", "RawConfigParser", | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 103 |            "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] | 
| Skip Montanaro | e99d5ea | 2001-01-20 19:54:20 +0000 | [diff] [blame] | 104 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 105 | DEFAULTSECT = "DEFAULT" | 
 | 106 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 107 | MAX_INTERPOLATION_DEPTH = 10 | 
 | 108 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 109 |  | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 110 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 111 | # exception classes | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 112 | class Error(Exception): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 113 |     """Base class for ConfigParser exceptions.""" | 
 | 114 |  | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 115 |     def _get_message(self): | 
 | 116 |         """Getter for 'message'; needed only to override deprecation in | 
 | 117 |         BaseException.""" | 
 | 118 |         return self.__message | 
 | 119 |  | 
 | 120 |     def _set_message(self, value): | 
 | 121 |         """Setter for 'message'; needed only to override deprecation in | 
 | 122 |         BaseException.""" | 
 | 123 |         self.__message = value | 
 | 124 |  | 
 | 125 |     # BaseException.message has been deprecated since Python 2.6.  To prevent | 
 | 126 |     # DeprecationWarning from popping up over this pre-existing attribute, use | 
 | 127 |     # a new property that takes lookup precedence. | 
 | 128 |     message = property(_get_message, _set_message) | 
 | 129 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 130 |     def __init__(self, msg=''): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 131 |         self.message = msg | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 132 |         Exception.__init__(self, msg) | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 133 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 134 |     def __repr__(self): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 135 |         return self.message | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 136 |  | 
| Fred Drake | 7c1e5ad | 2000-12-11 18:13:19 +0000 | [diff] [blame] | 137 |     __str__ = __repr__ | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 138 |  | 
 | 139 | class NoSectionError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 140 |     """Raised when no section matches a requested option.""" | 
 | 141 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 142 |     def __init__(self, section): | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 143 |         Error.__init__(self, 'No section: %r' % (section,)) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 144 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 145 |         self.args = (section, ) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 146 |  | 
 | 147 | class DuplicateSectionError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 148 |     """Raised when a section is multiply-created.""" | 
 | 149 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 150 |     def __init__(self, section): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 151 |         Error.__init__(self, "Section %r already exists" % section) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 152 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 153 |         self.args = (section, ) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 154 |  | 
 | 155 | class NoOptionError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 156 |     """A requested option was not found.""" | 
 | 157 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 158 |     def __init__(self, option, section): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 159 |         Error.__init__(self, "No option %r in section: %r" % | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 160 |                        (option, section)) | 
 | 161 |         self.option = option | 
 | 162 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 163 |         self.args = (option, section) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 164 |  | 
 | 165 | class InterpolationError(Error): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 166 |     """Base class for interpolation-related exceptions.""" | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 167 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 168 |     def __init__(self, option, section, msg): | 
 | 169 |         Error.__init__(self, msg) | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 170 |         self.option = option | 
 | 171 |         self.section = section | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 172 |         self.args = (option, section, msg) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 173 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 174 | class InterpolationMissingOptionError(InterpolationError): | 
 | 175 |     """A string substitution required a setting which was not available.""" | 
 | 176 |  | 
 | 177 |     def __init__(self, option, section, rawval, reference): | 
 | 178 |         msg = ("Bad value substitution:\n" | 
 | 179 |                "\tsection: [%s]\n" | 
 | 180 |                "\toption : %s\n" | 
 | 181 |                "\tkey    : %s\n" | 
 | 182 |                "\trawval : %s\n" | 
 | 183 |                % (section, option, reference, rawval)) | 
 | 184 |         InterpolationError.__init__(self, option, section, msg) | 
 | 185 |         self.reference = reference | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 186 |         self.args = (option, section, rawval, reference) | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 187 |  | 
 | 188 | class InterpolationSyntaxError(InterpolationError): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 189 |     """Raised when the source text into which substitutions are made | 
 | 190 |     does not conform to the required syntax.""" | 
| Neal Norwitz | ce1d944 | 2002-12-30 23:38:47 +0000 | [diff] [blame] | 191 |  | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 192 | class InterpolationDepthError(InterpolationError): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 193 |     """Raised when substitutions are nested too deeply.""" | 
 | 194 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 195 |     def __init__(self, option, section, rawval): | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 196 |         msg = ("Value interpolation too deeply recursive:\n" | 
 | 197 |                "\tsection: [%s]\n" | 
 | 198 |                "\toption : %s\n" | 
 | 199 |                "\trawval : %s\n" | 
 | 200 |                % (section, option, rawval)) | 
 | 201 |         InterpolationError.__init__(self, option, section, msg) | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 202 |         self.args = (option, section, rawval) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 203 |  | 
 | 204 | class ParsingError(Error): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 205 |     """Raised when a configuration file does not follow legal syntax.""" | 
 | 206 |  | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 207 |     def __init__(self, filename): | 
 | 208 |         Error.__init__(self, 'File contains parsing errors: %s' % filename) | 
 | 209 |         self.filename = filename | 
 | 210 |         self.errors = [] | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 211 |         self.args = (filename, ) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 212 |  | 
 | 213 |     def append(self, lineno, line): | 
 | 214 |         self.errors.append((lineno, line)) | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 215 |         self.message += '\n\t[line %2d]: %s' % (lineno, line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 216 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 217 | class MissingSectionHeaderError(ParsingError): | 
| Fred Drake | 8d5dd98 | 2002-12-30 23:51:45 +0000 | [diff] [blame] | 218 |     """Raised when a key-value pair is found before any section header.""" | 
 | 219 |  | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 220 |     def __init__(self, filename, lineno, line): | 
 | 221 |         Error.__init__( | 
 | 222 |             self, | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 223 |             'File contains no section headers.\nfile: %s, line: %d\n%r' % | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 224 |             (filename, lineno, line)) | 
 | 225 |         self.filename = filename | 
 | 226 |         self.lineno = lineno | 
 | 227 |         self.line = line | 
| Michael Foord | bd6c079 | 2010-07-25 23:09:25 +0000 | [diff] [blame^] | 228 |         self.args = (filename, lineno, line) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 229 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 230 | class RawConfigParser: | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 231 |     def __init__(self, defaults=None, dict_type=_default_dict, | 
 | 232 |                  allow_no_value=False): | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 233 |         self._dict = dict_type | 
 | 234 |         self._sections = self._dict() | 
 | 235 |         self._defaults = self._dict() | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 236 |         if allow_no_value: | 
 | 237 |             self._optcre = self.OPTCRE_NV | 
 | 238 |         else: | 
 | 239 |             self._optcre = self.OPTCRE | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 240 |         if defaults: | 
 | 241 |             for key, value in defaults.items(): | 
 | 242 |                 self._defaults[self.optionxform(key)] = value | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 243 |  | 
 | 244 |     def defaults(self): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 245 |         return self._defaults | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 246 |  | 
 | 247 |     def sections(self): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 248 |         """Return a list of section names, excluding [DEFAULT]""" | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 249 |         # self._sections will never have [DEFAULT] in it | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 250 |         return list(self._sections.keys()) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 251 |  | 
 | 252 |     def add_section(self, section): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 253 |         """Create a new section in the configuration. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 254 |  | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 255 |         Raise DuplicateSectionError if a section by the specified name | 
| Christian Heimes | 90c3d9b | 2008-02-23 13:18:03 +0000 | [diff] [blame] | 256 |         already exists. Raise ValueError if name is DEFAULT or any of it's | 
 | 257 |         case-insensitive variants. | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 258 |         """ | 
| Christian Heimes | 90c3d9b | 2008-02-23 13:18:03 +0000 | [diff] [blame] | 259 |         if section.lower() == "default": | 
 | 260 |             raise ValueError('Invalid section name: %s' % section) | 
 | 261 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 262 |         if section in self._sections: | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 263 |             raise DuplicateSectionError(section) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 264 |         self._sections[section] = self._dict() | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 265 |  | 
 | 266 |     def has_section(self, section): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 267 |         """Indicate whether the named section is present in the configuration. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 268 |  | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 269 |         The DEFAULT section is not acknowledged. | 
 | 270 |         """ | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 271 |         return section in self._sections | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 272 |  | 
 | 273 |     def options(self, section): | 
| Guido van Rossum | a5a24b7 | 1999-10-04 19:58:22 +0000 | [diff] [blame] | 274 |         """Return a list of option names for the given section name.""" | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 275 |         try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 276 |             opts = self._sections[section].copy() | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 277 |         except KeyError: | 
 | 278 |             raise NoSectionError(section) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 279 |         opts.update(self._defaults) | 
| Raymond Hettinger | 54f0222 | 2002-06-01 14:18:47 +0000 | [diff] [blame] | 280 |         if '__name__' in opts: | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 281 |             del opts['__name__'] | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 282 |         return list(opts.keys()) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 283 |  | 
 | 284 |     def read(self, filenames): | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 285 |         """Read and parse a filename or a list of filenames. | 
| Tim Peters | 88869f9 | 2001-01-14 23:36:06 +0000 | [diff] [blame] | 286 |  | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 287 |         Files that cannot be opened are silently ignored; this is | 
| Barry Warsaw | 2539451 | 1999-10-12 16:12:48 +0000 | [diff] [blame] | 288 |         designed so that you can specify a list of potential | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 289 |         configuration file locations (e.g. current directory, user's | 
 | 290 |         home directory, systemwide directory), and all existing | 
 | 291 |         configuration files in the list will be read.  A single | 
 | 292 |         filename may also be given. | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 293 |  | 
 | 294 |         Return list of successfully read files. | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 295 |         """ | 
| Guido van Rossum | 3172c5d | 2007-10-16 18:12:55 +0000 | [diff] [blame] | 296 |         if isinstance(filenames, str): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 297 |             filenames = [filenames] | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 298 |         read_ok = [] | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 299 |         for filename in filenames: | 
 | 300 |             try: | 
 | 301 |                 fp = open(filename) | 
 | 302 |             except IOError: | 
 | 303 |                 continue | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 304 |             self._read(fp, filename) | 
| Fred Drake | 2438a48 | 1999-10-04 18:11:56 +0000 | [diff] [blame] | 305 |             fp.close() | 
| Fred Drake | 8290314 | 2004-05-18 04:24:02 +0000 | [diff] [blame] | 306 |             read_ok.append(filename) | 
 | 307 |         return read_ok | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 308 |  | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 309 |     def readfp(self, fp, filename=None): | 
 | 310 |         """Like read() but the argument must be a file-like object. | 
 | 311 |  | 
 | 312 |         The `fp' argument must have a `readline' method.  Optional | 
 | 313 |         second argument is the `filename', which if not given, is | 
 | 314 |         taken from fp.name.  If fp has no `name' attribute, `<???>' is | 
 | 315 |         used. | 
 | 316 |  | 
 | 317 |         """ | 
 | 318 |         if filename is None: | 
 | 319 |             try: | 
 | 320 |                 filename = fp.name | 
 | 321 |             except AttributeError: | 
 | 322 |                 filename = '<???>' | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 323 |         self._read(fp, filename) | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 324 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 325 |     def get(self, section, option): | 
 | 326 |         opt = self.optionxform(option) | 
 | 327 |         if section not in self._sections: | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 328 |             if section != DEFAULTSECT: | 
 | 329 |                 raise NoSectionError(section) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 330 |             if opt in self._defaults: | 
 | 331 |                 return self._defaults[opt] | 
 | 332 |             else: | 
 | 333 |                 raise NoOptionError(option, section) | 
 | 334 |         elif opt in self._sections[section]: | 
 | 335 |             return self._sections[section][opt] | 
 | 336 |         elif opt in self._defaults: | 
 | 337 |             return self._defaults[opt] | 
 | 338 |         else: | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 339 |             raise NoOptionError(option, section) | 
| Fred Drake | 2a37f9f | 2000-09-27 22:43:54 +0000 | [diff] [blame] | 340 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 341 |     def items(self, section): | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 342 |         try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 343 |             d2 = self._sections[section] | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 344 |         except KeyError: | 
 | 345 |             if section != DEFAULTSECT: | 
 | 346 |                 raise NoSectionError(section) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 347 |             d2 = self._dict() | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 348 |         d = self._defaults.copy() | 
 | 349 |         d.update(d2) | 
| Fred Drake | df393bd | 2002-10-25 20:41:30 +0000 | [diff] [blame] | 350 |         if "__name__" in d: | 
 | 351 |             del d["__name__"] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 352 |         return d.items() | 
| Fred Drake | 2ca041f | 2002-09-27 15:49:56 +0000 | [diff] [blame] | 353 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 354 |     def _get(self, section, conv, option): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 355 |         return conv(self.get(section, option)) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 356 |  | 
 | 357 |     def getint(self, section, option): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 358 |         return self._get(section, int, option) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 359 |  | 
 | 360 |     def getfloat(self, section, option): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 361 |         return self._get(section, float, option) | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 362 |  | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 363 |     _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, | 
 | 364 |                        '0': False, 'no': False, 'false': False, 'off': False} | 
 | 365 |  | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 366 |     def getboolean(self, section, option): | 
| Tim Peters | e0c446b | 2001-10-18 21:57:37 +0000 | [diff] [blame] | 367 |         v = self.get(section, option) | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 368 |         if v.lower() not in self._boolean_states: | 
| Collin Winter | ce36ad8 | 2007-08-30 01:19:48 +0000 | [diff] [blame] | 369 |             raise ValueError('Not a boolean: %s' % v) | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 370 |         return self._boolean_states[v.lower()] | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 371 |  | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 372 |     def optionxform(self, optionstr): | 
| Eric S. Raymond | 9eb54d9 | 2001-02-09 05:19:09 +0000 | [diff] [blame] | 373 |         return optionstr.lower() | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 374 |  | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 375 |     def has_option(self, section, option): | 
 | 376 |         """Check for the existence of a given option in a given section.""" | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 377 |         if not section or section == DEFAULTSECT: | 
 | 378 |             option = self.optionxform(option) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 379 |             return option in self._defaults | 
 | 380 |         elif section not in self._sections: | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 381 |             return False | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 382 |         else: | 
| Fred Drake | 3c823aa | 2001-02-26 21:55:34 +0000 | [diff] [blame] | 383 |             option = self.optionxform(option) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 384 |             return (option in self._sections[section] | 
 | 385 |                     or option in self._defaults) | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 386 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 387 |     def set(self, section, option, value=None): | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 388 |         """Set an option.""" | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 389 |         if not section or section == DEFAULTSECT: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 390 |             sectdict = self._defaults | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 391 |         else: | 
 | 392 |             try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 393 |                 sectdict = self._sections[section] | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 394 |             except KeyError: | 
 | 395 |                 raise NoSectionError(section) | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 396 |         sectdict[self.optionxform(option)] = value | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 397 |  | 
 | 398 |     def write(self, fp): | 
 | 399 |         """Write an .ini-format representation of the configuration state.""" | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 400 |         if self._defaults: | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 401 |             fp.write("[%s]\n" % DEFAULTSECT) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 402 |             for (key, value) in self._defaults.items(): | 
| Andrew M. Kuchling | 00824ed | 2002-03-08 18:08:47 +0000 | [diff] [blame] | 403 |                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 404 |             fp.write("\n") | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 405 |         for section in self._sections: | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 406 |             fp.write("[%s]\n" % section) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 407 |             for (key, value) in self._sections[section].items(): | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 408 |                 if key != "__name__": | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 409 |                     if value is None: | 
 | 410 |                         fp.write("%s\n" % (key)) | 
 | 411 |                     else: | 
 | 412 |                         fp.write("%s = %s\n" % | 
 | 413 |                                  (key, str(value).replace('\n', '\n\t'))) | 
| Eric S. Raymond | 417c489 | 2000-07-10 18:11:00 +0000 | [diff] [blame] | 414 |             fp.write("\n") | 
 | 415 |  | 
| Thomas Wouters | ff4df6d | 2000-07-21 05:19:59 +0000 | [diff] [blame] | 416 |     def remove_option(self, section, option): | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 417 |         """Remove an option.""" | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 418 |         if not section or section == DEFAULTSECT: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 419 |             sectdict = self._defaults | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 420 |         else: | 
 | 421 |             try: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 422 |                 sectdict = self._sections[section] | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 423 |             except KeyError: | 
 | 424 |                 raise NoSectionError(section) | 
| Fred Drake | 3c823aa | 2001-02-26 21:55:34 +0000 | [diff] [blame] | 425 |         option = self.optionxform(option) | 
| Raymond Hettinger | 54f0222 | 2002-06-01 14:18:47 +0000 | [diff] [blame] | 426 |         existed = option in sectdict | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 427 |         if existed: | 
| Fred Drake | ff4a23b | 2000-12-04 16:29:13 +0000 | [diff] [blame] | 428 |             del sectdict[option] | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 429 |         return existed | 
 | 430 |  | 
| Thomas Wouters | ff4df6d | 2000-07-21 05:19:59 +0000 | [diff] [blame] | 431 |     def remove_section(self, section): | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 432 |         """Remove a file section.""" | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 433 |         existed = section in self._sections | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 434 |         if existed: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 435 |             del self._sections[section] | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 436 |         return existed | 
| Eric S. Raymond | 649685a | 2000-07-14 14:28:22 +0000 | [diff] [blame] | 437 |  | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 438 |     # | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 439 |     # Regular expressions for parsing section headers and options. | 
 | 440 |     # | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 441 |     SECTCRE = re.compile( | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 442 |         r'\['                                 # [ | 
| Fred Drake | d4df94b | 2001-02-14 15:24:17 +0000 | [diff] [blame] | 443 |         r'(?P<header>[^]]+)'                  # very permissive! | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 444 |         r'\]'                                 # ] | 
 | 445 |         ) | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 446 |     OPTCRE = re.compile( | 
| Fred Drake | 176916a | 2002-09-27 16:21:18 +0000 | [diff] [blame] | 447 |         r'(?P<option>[^:=\s][^:=]*)'          # very permissive! | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 448 |         r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab, | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 449 |                                               # followed by separator | 
 | 450 |                                               # (either : or =), followed | 
 | 451 |                                               # by any # space/tab | 
 | 452 |         r'(?P<value>.*)$'                     # everything up to eol | 
 | 453 |         ) | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 454 |     OPTCRE_NV = re.compile( | 
 | 455 |         r'(?P<option>[^:=\s][^:=]*)'          # very permissive! | 
 | 456 |         r'\s*(?:'                             # any number of space/tab, | 
 | 457 |         r'(?P<vi>[:=])\s*'                    # optionally followed by | 
 | 458 |                                               # separator (either : or | 
 | 459 |                                               # =), followed by any # | 
 | 460 |                                               # space/tab | 
 | 461 |         r'(?P<value>.*))?$'                   # everything up to eol | 
 | 462 |         ) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 463 |  | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 464 |     def _read(self, fp, fpname): | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 465 |         """Parse a sectioned setup file. | 
| Guido van Rossum | 3d20986 | 1997-12-09 16:10:31 +0000 | [diff] [blame] | 466 |  | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 467 |         The sections in setup file contains a title line at the top, | 
 | 468 |         indicated by a name in square brackets (`[]'), plus key/value | 
 | 469 |         options lines, indicated by `name: value' format lines. | 
| Andrew M. Kuchling | 9050a51 | 2002-11-06 14:51:20 +0000 | [diff] [blame] | 470 |         Continuations are represented by an embedded newline then | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 471 |         leading whitespace.  Blank lines, lines beginning with a '#', | 
| Andrew M. Kuchling | 9050a51 | 2002-11-06 14:51:20 +0000 | [diff] [blame] | 472 |         and just about everything else are ignored. | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 473 |         """ | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 474 |         cursect = None                            # None, or a dictionary | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 475 |         optname = None | 
 | 476 |         lineno = 0 | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 477 |         e = None                                  # None, or an exception | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 478 |         while True: | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 479 |             line = fp.readline() | 
 | 480 |             if not line: | 
 | 481 |                 break | 
 | 482 |             lineno = lineno + 1 | 
 | 483 |             # comment or blank line? | 
| Eric S. Raymond | 9eb54d9 | 2001-02-09 05:19:09 +0000 | [diff] [blame] | 484 |             if line.strip() == '' or line[0] in '#;': | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 485 |                 continue | 
| Fred Drake | 176916a | 2002-09-27 16:21:18 +0000 | [diff] [blame] | 486 |             if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": | 
 | 487 |                 # no leading whitespace | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 488 |                 continue | 
 | 489 |             # continuation line? | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 490 |             if line[0].isspace() and cursect is not None and optname: | 
| Eric S. Raymond | 9eb54d9 | 2001-02-09 05:19:09 +0000 | [diff] [blame] | 491 |                 value = line.strip() | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 492 |                 if value: | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 493 |                     cursect[optname] = "%s\n%s" % (cursect[optname], value) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 494 |             # a section header or option header? | 
| Guido van Rossum | 45e2fbc | 1998-03-26 21:13:24 +0000 | [diff] [blame] | 495 |             else: | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 496 |                 # is it a section header? | 
| Guido van Rossum | 9e480ad | 1999-06-17 18:41:42 +0000 | [diff] [blame] | 497 |                 mo = self.SECTCRE.match(line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 498 |                 if mo: | 
 | 499 |                     sectname = mo.group('header') | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 500 |                     if sectname in self._sections: | 
 | 501 |                         cursect = self._sections[sectname] | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 502 |                     elif sectname == DEFAULTSECT: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 503 |                         cursect = self._defaults | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 504 |                     else: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 505 |                         cursect = self._dict() | 
 | 506 |                         cursect['__name__'] = sectname | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 507 |                         self._sections[sectname] = cursect | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 508 |                     # So sections can't start with a continuation line | 
 | 509 |                     optname = None | 
 | 510 |                 # no section header in the file? | 
 | 511 |                 elif cursect is None: | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 512 |                     raise MissingSectionHeaderError(fpname, lineno, line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 513 |                 # an option line? | 
 | 514 |                 else: | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 515 |                     mo = self._optcre.match(line) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 516 |                     if mo: | 
| Fred Drake | c517b9b | 2000-02-28 20:59:03 +0000 | [diff] [blame] | 517 |                         optname, vi, optval = mo.group('option', 'vi', 'value') | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 518 |                         # This check is fine because the OPTCRE cannot | 
 | 519 |                         # match if it would set optval to None | 
 | 520 |                         if optval is not None: | 
 | 521 |                             if vi in ('=', ':') and ';' in optval: | 
 | 522 |                                 # ';' is a comment delimiter only if it follows | 
 | 523 |                                 # a spacing character | 
 | 524 |                                 pos = optval.find(';') | 
 | 525 |                                 if pos != -1 and optval[pos-1].isspace(): | 
 | 526 |                                     optval = optval[:pos] | 
 | 527 |                             optval = optval.strip() | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 528 |                         # allow empty values | 
 | 529 |                         if optval == '""': | 
 | 530 |                             optval = '' | 
| Fred Drake | 176916a | 2002-09-27 16:21:18 +0000 | [diff] [blame] | 531 |                         optname = self.optionxform(optname.rstrip()) | 
| Fred Drake | c2ff905 | 2002-09-27 15:33:11 +0000 | [diff] [blame] | 532 |                         cursect[optname] = optval | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 533 |                     else: | 
 | 534 |                         # a non-fatal parsing error occurred.  set up the | 
 | 535 |                         # exception but keep going. the exception will be | 
 | 536 |                         # raised at the end of the file and will contain a | 
 | 537 |                         # list of all bogus lines | 
 | 538 |                         if not e: | 
| Guido van Rossum | 6a8d84b | 1999-10-04 18:57:27 +0000 | [diff] [blame] | 539 |                             e = ParsingError(fpname) | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 540 |                         e.append(lineno, repr(line)) | 
| Barry Warsaw | bfa3f6b | 1998-07-01 20:41:12 +0000 | [diff] [blame] | 541 |         # if any parsing errors occurred, raise an exception | 
 | 542 |         if e: | 
 | 543 |             raise e | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 544 |  | 
 | 545 |  | 
 | 546 | class ConfigParser(RawConfigParser): | 
 | 547 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 548 |     def get(self, section, option, raw=False, vars=None): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 549 |         """Get an option value for a given section. | 
 | 550 |  | 
 | 551 |         All % interpolations are expanded in the return values, based on the | 
 | 552 |         defaults passed into the constructor, unless the optional argument | 
 | 553 |         `raw' is true.  Additional substitutions may be provided using the | 
 | 554 |         `vars' argument, which must be a dictionary whose contents overrides | 
 | 555 |         any pre-existing defaults. | 
 | 556 |  | 
 | 557 |         The section DEFAULT is special. | 
 | 558 |         """ | 
 | 559 |         d = self._defaults.copy() | 
 | 560 |         try: | 
 | 561 |             d.update(self._sections[section]) | 
 | 562 |         except KeyError: | 
 | 563 |             if section != DEFAULTSECT: | 
 | 564 |                 raise NoSectionError(section) | 
 | 565 |         # Update with the entry specific variables | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 566 |         if vars: | 
 | 567 |             for key, value in vars.items(): | 
 | 568 |                 d[self.optionxform(key)] = value | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 569 |         option = self.optionxform(option) | 
 | 570 |         try: | 
 | 571 |             value = d[option] | 
 | 572 |         except KeyError: | 
 | 573 |             raise NoOptionError(option, section) | 
 | 574 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 575 |         if raw or value is None: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 576 |             return value | 
 | 577 |         else: | 
 | 578 |             return self._interpolate(section, option, value, d) | 
 | 579 |  | 
| Neal Norwitz | f680cc4 | 2002-12-17 01:56:47 +0000 | [diff] [blame] | 580 |     def items(self, section, raw=False, vars=None): | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 581 |         """Return a list of tuples with (name, value) for each option | 
 | 582 |         in the section. | 
 | 583 |  | 
 | 584 |         All % interpolations are expanded in the return values, based on the | 
 | 585 |         defaults passed into the constructor, unless the optional argument | 
 | 586 |         `raw' is true.  Additional substitutions may be provided using the | 
 | 587 |         `vars' argument, which must be a dictionary whose contents overrides | 
 | 588 |         any pre-existing defaults. | 
 | 589 |  | 
 | 590 |         The section DEFAULT is special. | 
 | 591 |         """ | 
 | 592 |         d = self._defaults.copy() | 
 | 593 |         try: | 
 | 594 |             d.update(self._sections[section]) | 
 | 595 |         except KeyError: | 
 | 596 |             if section != DEFAULTSECT: | 
 | 597 |                 raise NoSectionError(section) | 
 | 598 |         # Update with the entry specific variables | 
 | 599 |         if vars: | 
| David Goodger | 68a1abd | 2004-10-03 15:40:25 +0000 | [diff] [blame] | 600 |             for key, value in vars.items(): | 
 | 601 |                 d[self.optionxform(key)] = value | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 602 |         options = list(d.keys()) | 
| Fred Drake | df393bd | 2002-10-25 20:41:30 +0000 | [diff] [blame] | 603 |         if "__name__" in options: | 
 | 604 |             options.remove("__name__") | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 605 |         if raw: | 
| Fred Drake | 8c4da53 | 2003-10-21 16:45:00 +0000 | [diff] [blame] | 606 |             return [(option, d[option]) | 
 | 607 |                     for option in options] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 608 |         else: | 
| Fred Drake | 8c4da53 | 2003-10-21 16:45:00 +0000 | [diff] [blame] | 609 |             return [(option, self._interpolate(section, option, d[option], d)) | 
 | 610 |                     for option in options] | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 611 |  | 
 | 612 |     def _interpolate(self, section, option, rawval, vars): | 
 | 613 |         # do the string interpolation | 
 | 614 |         value = rawval | 
| Tim Peters | 230a60c | 2002-11-09 05:08:07 +0000 | [diff] [blame] | 615 |         depth = MAX_INTERPOLATION_DEPTH | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 616 |         while depth:                    # Loop through this until it's done | 
 | 617 |             depth -= 1 | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 618 |             if value and "%(" in value: | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 619 |                 value = self._KEYCRE.sub(self._interpolation_replace, value) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 620 |                 try: | 
 | 621 |                     value = value % vars | 
| Guido van Rossum | b940e11 | 2007-01-10 16:19:56 +0000 | [diff] [blame] | 622 |                 except KeyError as e: | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 623 |                     raise InterpolationMissingOptionError( | 
| Brett Cannon | ca477b2 | 2007-03-21 22:26:20 +0000 | [diff] [blame] | 624 |                         option, section, rawval, e.args[0]) | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 625 |             else: | 
 | 626 |                 break | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 627 |         if value and "%(" in value: | 
| Fred Drake | fce6557 | 2002-10-25 18:08:18 +0000 | [diff] [blame] | 628 |             raise InterpolationDepthError(option, section, rawval) | 
 | 629 |         return value | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 630 |  | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 631 |     _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") | 
 | 632 |  | 
 | 633 |     def _interpolation_replace(self, match): | 
 | 634 |         s = match.group(1) | 
 | 635 |         if s is None: | 
 | 636 |             return match.group() | 
 | 637 |         else: | 
 | 638 |             return "%%(%s)s" % self.optionxform(s) | 
 | 639 |  | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 640 |  | 
 | 641 | class SafeConfigParser(ConfigParser): | 
 | 642 |  | 
 | 643 |     def _interpolate(self, section, option, rawval, vars): | 
 | 644 |         # do the string interpolation | 
 | 645 |         L = [] | 
 | 646 |         self._interpolate_some(option, L, rawval, section, vars, 1) | 
 | 647 |         return ''.join(L) | 
 | 648 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 649 |     _interpvar_re = re.compile(r"%\(([^)]+)\)s") | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 650 |  | 
 | 651 |     def _interpolate_some(self, option, accum, rest, section, map, depth): | 
 | 652 |         if depth > MAX_INTERPOLATION_DEPTH: | 
 | 653 |             raise InterpolationDepthError(option, section, rest) | 
 | 654 |         while rest: | 
 | 655 |             p = rest.find("%") | 
 | 656 |             if p < 0: | 
 | 657 |                 accum.append(rest) | 
 | 658 |                 return | 
 | 659 |             if p > 0: | 
 | 660 |                 accum.append(rest[:p]) | 
 | 661 |                 rest = rest[p:] | 
 | 662 |             # p is no longer used | 
 | 663 |             c = rest[1:2] | 
 | 664 |             if c == "%": | 
 | 665 |                 accum.append("%") | 
 | 666 |                 rest = rest[2:] | 
 | 667 |             elif c == "(": | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 668 |                 m = self._interpvar_re.match(rest) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 669 |                 if m is None: | 
| Neal Norwitz | 10f3018 | 2003-06-29 04:23:35 +0000 | [diff] [blame] | 670 |                     raise InterpolationSyntaxError(option, section, | 
 | 671 |                         "bad interpolation variable reference %r" % rest) | 
| Fred Drake | bc12b01 | 2004-05-18 02:25:51 +0000 | [diff] [blame] | 672 |                 var = self.optionxform(m.group(1)) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 673 |                 rest = rest[m.end():] | 
 | 674 |                 try: | 
 | 675 |                     v = map[var] | 
 | 676 |                 except KeyError: | 
| Fred Drake | e2c6491 | 2002-12-31 17:23:27 +0000 | [diff] [blame] | 677 |                     raise InterpolationMissingOptionError( | 
 | 678 |                         option, section, rest, var) | 
| Fred Drake | 0eebd5c | 2002-10-25 21:52:00 +0000 | [diff] [blame] | 679 |                 if "%" in v: | 
 | 680 |                     self._interpolate_some(option, accum, v, | 
 | 681 |                                            section, map, depth + 1) | 
 | 682 |                 else: | 
 | 683 |                     accum.append(v) | 
 | 684 |             else: | 
 | 685 |                 raise InterpolationSyntaxError( | 
| Neal Norwitz | 10f3018 | 2003-06-29 04:23:35 +0000 | [diff] [blame] | 686 |                     option, section, | 
| Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 687 |                     "'%%' must be followed by '%%' or '(', found: %r" % (rest,)) | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 688 |  | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 689 |     def set(self, section, option, value=None): | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 690 |         """Set an option.  Extend ConfigParser.set: check for string values.""" | 
| Fred Drake | 03c44a3 | 2010-02-19 06:08:41 +0000 | [diff] [blame] | 691 |         # The only legal non-string value if we allow valueless | 
 | 692 |         # options is None, so we need to check if the value is a | 
 | 693 |         # string if: | 
 | 694 |         # - we do not allow valueless options, or | 
 | 695 |         # - we allow valueless options but the value is not None | 
 | 696 |         if self._optcre is self.OPTCRE or value: | 
 | 697 |             if not isinstance(value, str): | 
 | 698 |                 raise TypeError("option values must be strings") | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 699 |         # check for bad percent signs: | 
 | 700 |         # first, replace all "good" interpolations | 
| Georg Brandl | 68998bf | 2009-04-27 16:43:36 +0000 | [diff] [blame] | 701 |         tmp_value = value.replace('%%', '') | 
 | 702 |         tmp_value = self._interpvar_re.sub('', tmp_value) | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 703 |         # then, check if there's a lone percent sign left | 
| Georg Brandl | 1f9fa31 | 2009-04-27 16:42:58 +0000 | [diff] [blame] | 704 |         percent_index = tmp_value.find('%') | 
 | 705 |         if percent_index != -1: | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 706 |             raise ValueError("invalid interpolation syntax in %r at " | 
| Georg Brandl | 1f9fa31 | 2009-04-27 16:42:58 +0000 | [diff] [blame] | 707 |                              "position %d" % (value, percent_index)) | 
| David Goodger | 1cbf206 | 2004-10-03 15:55:09 +0000 | [diff] [blame] | 708 |         ConfigParser.set(self, section, option, value) |