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