svn-gvsig-desktop / tags / v1_0_2_Build_907 / extensions / extScripting / scripts / jython / Lib / ConfigParser.py @ 11015
History | View | Annotate | Download (16.8 KB)
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
|
5 |
the style of RFC 822.
|
6 |
|
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 |
|
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 |
|
22 |
ConfigParser -- responsible for for parsing a list of
|
23 |
configuration files, and managing the parsed database.
|
24 |
|
25 |
methods:
|
26 |
|
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;
|
31 |
it's value is the section's name.
|
32 |
|
33 |
sections()
|
34 |
return all the configuration section names, sans DEFAULT
|
35 |
|
36 |
has_section(section)
|
37 |
return whether the given section exists
|
38 |
|
39 |
has_option(section, option)
|
40 |
return whether the given option exists in the given section
|
41 |
|
42 |
options(section)
|
43 |
return list of configuration options for the named section
|
44 |
|
45 |
has_option(section, option)
|
46 |
return whether the given section has the given option
|
47 |
|
48 |
read(filenames)
|
49 |
read and parse the list of named configuration files, given by
|
50 |
name. A single filename is also allowed. Non-existing files
|
51 |
are ignored.
|
52 |
|
53 |
readfp(fp, filename=None)
|
54 |
read and parse one configuration file, given as a file object.
|
55 |
The filename defaults to fp.name; it is only used in error
|
56 |
messages (if fp has no `name' attribute, the string `<???>' is used).
|
57 |
|
58 |
get(section, option, raw=0, vars=None)
|
59 |
return a string value for the named option. All % interpolations are
|
60 |
expanded in the return values, based on the defaults passed into the
|
61 |
constructor and the DEFAULT section. Additional substitutions may be
|
62 |
provided using the `vars' argument, which must be a dictionary whose
|
63 |
contents override any pre-existing defaults.
|
64 |
|
65 |
getint(section, options)
|
66 |
like get(), but convert value to an integer
|
67 |
|
68 |
getfloat(section, options)
|
69 |
like get(), but convert value to a float
|
70 |
|
71 |
getboolean(section, options)
|
72 |
like get(), but convert value to a boolean (currently defined as 0 or
|
73 |
1, only)
|
74 |
|
75 |
remove_section(section)
|
76 |
remove the given file section and all its options
|
77 |
|
78 |
remove_option(section, option)
|
79 |
remove the given option from the given section
|
80 |
|
81 |
set(section, option, value)
|
82 |
set the given option
|
83 |
|
84 |
write(fp)
|
85 |
write the configuration state in .ini format
|
86 |
"""
|
87 |
|
88 |
import sys |
89 |
import string |
90 |
import re |
91 |
|
92 |
__all__ = ["NoSectionError","DuplicateSectionError","NoOptionError", |
93 |
"InterpolationError","InterpolationDepthError","ParsingError", |
94 |
"MissingSectionHeaderError","ConfigParser", |
95 |
"MAX_INTERPOLATION_DEPTH"]
|
96 |
|
97 |
DEFAULTSECT = "DEFAULT"
|
98 |
|
99 |
MAX_INTERPOLATION_DEPTH = 10
|
100 |
|
101 |
|
102 |
|
103 |
# exception classes
|
104 |
class Error(Exception): |
105 |
def __init__(self, msg=''): |
106 |
self._msg = msg
|
107 |
Exception.__init__(self, msg) |
108 |
def __repr__(self): |
109 |
return self._msg |
110 |
__str__ = __repr__ |
111 |
|
112 |
class NoSectionError(Error): |
113 |
def __init__(self, section): |
114 |
Error.__init__(self, 'No section: %s' % section) |
115 |
self.section = section
|
116 |
|
117 |
class DuplicateSectionError(Error): |
118 |
def __init__(self, section): |
119 |
Error.__init__(self, "Section %s already exists" % section) |
120 |
self.section = section
|
121 |
|
122 |
class NoOptionError(Error): |
123 |
def __init__(self, option, section): |
124 |
Error.__init__(self, "No option `%s' in section: %s" % |
125 |
(option, section)) |
126 |
self.option = option
|
127 |
self.section = section
|
128 |
|
129 |
class InterpolationError(Error): |
130 |
def __init__(self, reference, option, section, rawval): |
131 |
Error.__init__(self,
|
132 |
"Bad value substitution:\n"
|
133 |
"\tsection: [%s]\n"
|
134 |
"\toption : %s\n"
|
135 |
"\tkey : %s\n"
|
136 |
"\trawval : %s\n"
|
137 |
% (section, option, reference, rawval)) |
138 |
self.reference = reference
|
139 |
self.option = option
|
140 |
self.section = section
|
141 |
|
142 |
class InterpolationDepthError(Error): |
143 |
def __init__(self, option, section, rawval): |
144 |
Error.__init__(self,
|
145 |
"Value interpolation too deeply recursive:\n"
|
146 |
"\tsection: [%s]\n"
|
147 |
"\toption : %s\n"
|
148 |
"\trawval : %s\n"
|
149 |
% (section, option, rawval)) |
150 |
self.option = option
|
151 |
self.section = section
|
152 |
|
153 |
class ParsingError(Error): |
154 |
def __init__(self, filename): |
155 |
Error.__init__(self, 'File contains parsing errors: %s' % filename) |
156 |
self.filename = filename
|
157 |
self.errors = []
|
158 |
|
159 |
def append(self, lineno, line): |
160 |
self.errors.append((lineno, line))
|
161 |
self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line) |
162 |
|
163 |
class MissingSectionHeaderError(ParsingError): |
164 |
def __init__(self, filename, lineno, line): |
165 |
Error.__init__( |
166 |
self,
|
167 |
'File contains no section headers.\nfile: %s, line: %d\n%s' %
|
168 |
(filename, lineno, line)) |
169 |
self.filename = filename
|
170 |
self.lineno = lineno
|
171 |
self.line = line
|
172 |
|
173 |
|
174 |
|
175 |
class ConfigParser: |
176 |
def __init__(self, defaults=None): |
177 |
self.__sections = {}
|
178 |
if defaults is None: |
179 |
self.__defaults = {}
|
180 |
else:
|
181 |
self.__defaults = defaults
|
182 |
|
183 |
def defaults(self): |
184 |
return self.__defaults |
185 |
|
186 |
def sections(self): |
187 |
"""Return a list of section names, excluding [DEFAULT]"""
|
188 |
# self.__sections will never have [DEFAULT] in it
|
189 |
return self.__sections.keys() |
190 |
|
191 |
def add_section(self, section): |
192 |
"""Create a new section in the configuration.
|
193 |
|
194 |
Raise DuplicateSectionError if a section by the specified name
|
195 |
already exists.
|
196 |
"""
|
197 |
if self.__sections.has_key(section): |
198 |
raise DuplicateSectionError(section)
|
199 |
self.__sections[section] = {}
|
200 |
|
201 |
def has_section(self, section): |
202 |
"""Indicate whether the named section is present in the configuration.
|
203 |
|
204 |
The DEFAULT section is not acknowledged.
|
205 |
"""
|
206 |
return section in self.sections() |
207 |
|
208 |
def options(self, section): |
209 |
"""Return a list of option names for the given section name."""
|
210 |
try:
|
211 |
opts = self.__sections[section].copy()
|
212 |
except KeyError: |
213 |
raise NoSectionError(section)
|
214 |
opts.update(self.__defaults)
|
215 |
if opts.has_key('__name__'): |
216 |
del opts['__name__'] |
217 |
return opts.keys()
|
218 |
|
219 |
def has_option(self, section, option): |
220 |
"""Return whether the given section has the given option."""
|
221 |
return option in self.options(section) |
222 |
|
223 |
def read(self, filenames): |
224 |
"""Read and parse a filename or a list of filenames.
|
225 |
|
226 |
Files that cannot be opened are silently ignored; this is
|
227 |
designed so that you can specify a list of potential
|
228 |
configuration file locations (e.g. current directory, user's
|
229 |
home directory, systemwide directory), and all existing
|
230 |
configuration files in the list will be read. A single
|
231 |
filename may also be given.
|
232 |
"""
|
233 |
if type(filenames) in [type(''), type(u'')]: |
234 |
filenames = [filenames] |
235 |
for filename in filenames: |
236 |
try:
|
237 |
fp = open(filename)
|
238 |
except IOError: |
239 |
continue
|
240 |
self.__read(fp, filename)
|
241 |
fp.close() |
242 |
|
243 |
def readfp(self, fp, filename=None): |
244 |
"""Like read() but the argument must be a file-like object.
|
245 |
|
246 |
The `fp' argument must have a `readline' method. Optional
|
247 |
second argument is the `filename', which if not given, is
|
248 |
taken from fp.name. If fp has no `name' attribute, `<???>' is
|
249 |
used.
|
250 |
|
251 |
"""
|
252 |
if filename is None: |
253 |
try:
|
254 |
filename = fp.name |
255 |
except AttributeError: |
256 |
filename = '<???>'
|
257 |
self.__read(fp, filename)
|
258 |
|
259 |
def get(self, section, option, raw=0, vars=None): |
260 |
"""Get an option value for a given section.
|
261 |
|
262 |
All % interpolations are expanded in the return values, based on the
|
263 |
defaults passed into the constructor, unless the optional argument
|
264 |
`raw' is true. Additional substitutions may be provided using the
|
265 |
`vars' argument, which must be a dictionary whose contents overrides
|
266 |
any pre-existing defaults.
|
267 |
|
268 |
The section DEFAULT is special.
|
269 |
"""
|
270 |
try:
|
271 |
sectdict = self.__sections[section].copy()
|
272 |
except KeyError: |
273 |
if section == DEFAULTSECT:
|
274 |
sectdict = {} |
275 |
else:
|
276 |
raise NoSectionError(section)
|
277 |
d = self.__defaults.copy()
|
278 |
d.update(sectdict) |
279 |
# Update with the entry specific variables
|
280 |
if vars: |
281 |
d.update(vars)
|
282 |
option = self.optionxform(option)
|
283 |
try:
|
284 |
rawval = d[option] |
285 |
except KeyError: |
286 |
raise NoOptionError(option, section)
|
287 |
|
288 |
if raw:
|
289 |
return rawval
|
290 |
|
291 |
# do the string interpolation
|
292 |
value = rawval # Make it a pretty variable name
|
293 |
depth = 0
|
294 |
while depth < 10: # Loop through this until it's done |
295 |
depth = depth + 1
|
296 |
if value.find("%(") >= 0: |
297 |
try:
|
298 |
value = value % d |
299 |
except KeyError, key: |
300 |
raise InterpolationError(key, option, section, rawval)
|
301 |
else:
|
302 |
break
|
303 |
if value.find("%(") >= 0: |
304 |
raise InterpolationDepthError(option, section, rawval)
|
305 |
return value
|
306 |
|
307 |
def __get(self, section, conv, option): |
308 |
return conv(self.get(section, option)) |
309 |
|
310 |
def getint(self, section, option): |
311 |
return self.__get(section, string.atoi, option) |
312 |
|
313 |
def getfloat(self, section, option): |
314 |
return self.__get(section, string.atof, option) |
315 |
|
316 |
def getboolean(self, section, option): |
317 |
v = self.get(section, option)
|
318 |
val = int(v)
|
319 |
if val not in (0, 1): |
320 |
raise ValueError, 'Not a boolean: %s' % v |
321 |
return val
|
322 |
|
323 |
def optionxform(self, optionstr): |
324 |
return optionstr.lower()
|
325 |
|
326 |
def has_option(self, section, option): |
327 |
"""Check for the existence of a given option in a given section."""
|
328 |
if not section or section == "DEFAULT": |
329 |
return self.__defaults.has_key(option) |
330 |
elif not self.has_section(section): |
331 |
return 0 |
332 |
else:
|
333 |
option = self.optionxform(option)
|
334 |
return self.__sections[section].has_key(option) |
335 |
|
336 |
def set(self, section, option, value): |
337 |
"""Set an option."""
|
338 |
if not section or section == "DEFAULT": |
339 |
sectdict = self.__defaults
|
340 |
else:
|
341 |
try:
|
342 |
sectdict = self.__sections[section]
|
343 |
except KeyError: |
344 |
raise NoSectionError(section)
|
345 |
option = self.optionxform(option)
|
346 |
sectdict[option] = value |
347 |
|
348 |
def write(self, fp): |
349 |
"""Write an .ini-format representation of the configuration state."""
|
350 |
if self.__defaults: |
351 |
fp.write("[DEFAULT]\n")
|
352 |
for (key, value) in self.__defaults.items(): |
353 |
fp.write("%s = %s\n" % (key, value))
|
354 |
fp.write("\n")
|
355 |
for section in self.sections(): |
356 |
fp.write("[" + section + "]\n") |
357 |
sectdict = self.__sections[section]
|
358 |
for (key, value) in sectdict.items(): |
359 |
if key == "__name__": |
360 |
continue
|
361 |
fp.write("%s = %s\n" % (key, value))
|
362 |
fp.write("\n")
|
363 |
|
364 |
def remove_option(self, section, option): |
365 |
"""Remove an option."""
|
366 |
if not section or section == "DEFAULT": |
367 |
sectdict = self.__defaults
|
368 |
else:
|
369 |
try:
|
370 |
sectdict = self.__sections[section]
|
371 |
except KeyError: |
372 |
raise NoSectionError(section)
|
373 |
option = self.optionxform(option)
|
374 |
existed = sectdict.has_key(option) |
375 |
if existed:
|
376 |
del sectdict[option]
|
377 |
return existed
|
378 |
|
379 |
def remove_section(self, section): |
380 |
"""Remove a file section."""
|
381 |
if self.__sections.has_key(section): |
382 |
del self.__sections[section] |
383 |
return 1 |
384 |
else:
|
385 |
return 0 |
386 |
|
387 |
#
|
388 |
# Regular expressions for parsing section headers and options. Note a
|
389 |
# slight semantic change from the previous version, because of the use
|
390 |
# of \w, _ is allowed in section header names.
|
391 |
SECTCRE = re.compile( |
392 |
r'\[' # [ |
393 |
r'(?P<header>[^]]+)' # very permissive! |
394 |
r'\]' # ] |
395 |
) |
396 |
OPTCRE = re.compile( |
397 |
r'(?P<option>[]\-[\w_.*,(){}]+)' # a lot of stuff found by IvL |
398 |
r'[ \t]*(?P<vi>[:=])[ \t]*' # any number of space/tab, |
399 |
# followed by separator
|
400 |
# (either : or =), followed
|
401 |
# by any # space/tab
|
402 |
r'(?P<value>.*)$' # everything up to eol |
403 |
) |
404 |
|
405 |
def __read(self, fp, fpname): |
406 |
"""Parse a sectioned setup file.
|
407 |
|
408 |
The sections in setup file contains a title line at the top,
|
409 |
indicated by a name in square brackets (`[]'), plus key/value
|
410 |
options lines, indicated by `name: value' format lines.
|
411 |
Continuation are represented by an embedded newline then
|
412 |
leading whitespace. Blank lines, lines beginning with a '#',
|
413 |
and just about everything else is ignored.
|
414 |
"""
|
415 |
cursect = None # None, or a dictionary |
416 |
optname = None
|
417 |
lineno = 0
|
418 |
e = None # None, or an exception |
419 |
while 1: |
420 |
line = fp.readline() |
421 |
if not line: |
422 |
break
|
423 |
lineno = lineno + 1
|
424 |
# comment or blank line?
|
425 |
if line.strip() == '' or line[0] in '#;': |
426 |
continue
|
427 |
if line.split()[0].lower() == 'rem' \ |
428 |
and line[0] in "rR": # no leading whitespace |
429 |
continue
|
430 |
# continuation line?
|
431 |
if line[0] in ' \t' and cursect is not None and optname: |
432 |
value = line.strip() |
433 |
if value:
|
434 |
k = self.optionxform(optname)
|
435 |
cursect[k] = "%s\n%s" % (cursect[k], value)
|
436 |
# a section header or option header?
|
437 |
else:
|
438 |
# is it a section header?
|
439 |
mo = self.SECTCRE.match(line)
|
440 |
if mo:
|
441 |
sectname = mo.group('header')
|
442 |
if self.__sections.has_key(sectname): |
443 |
cursect = self.__sections[sectname]
|
444 |
elif sectname == DEFAULTSECT:
|
445 |
cursect = self.__defaults
|
446 |
else:
|
447 |
cursect = {'__name__': sectname}
|
448 |
self.__sections[sectname] = cursect
|
449 |
# So sections can't start with a continuation line
|
450 |
optname = None
|
451 |
# no section header in the file?
|
452 |
elif cursect is None: |
453 |
raise MissingSectionHeaderError(fpname, lineno, `line`)
|
454 |
# an option line?
|
455 |
else:
|
456 |
mo = self.OPTCRE.match(line)
|
457 |
if mo:
|
458 |
optname, vi, optval = mo.group('option', 'vi', 'value') |
459 |
if vi in ('=', ':') and ';' in optval: |
460 |
# ';' is a comment delimiter only if it follows
|
461 |
# a spacing character
|
462 |
pos = optval.find(';')
|
463 |
if pos and optval[pos-1] in string.whitespace: |
464 |
optval = optval[:pos] |
465 |
optval = optval.strip() |
466 |
# allow empty values
|
467 |
if optval == '""': |
468 |
optval = ''
|
469 |
cursect[self.optionxform(optname)] = optval
|
470 |
else:
|
471 |
# a non-fatal parsing error occurred. set up the
|
472 |
# exception but keep going. the exception will be
|
473 |
# raised at the end of the file and will contain a
|
474 |
# list of all bogus lines
|
475 |
if not e: |
476 |
e = ParsingError(fpname) |
477 |
e.append(lineno, `line`) |
478 |
# if any parsing errors occurred, raise an exception
|
479 |
if e:
|
480 |
raise e
|