Added function to create alternate title boxing like Dave.
[docutils.git] / docutils / frontend.py
blob01731c47891d437b0a8fa944d401a2e46dfe6c17
1 # Author: David Goodger
2 # Contact: goodger@users.sourceforge.net
3 # Revision: $Revision$
4 # Date: $Date$
5 # Copyright: This module has been placed in the public domain.
7 """
8 Command-line and common processing for Docutils front-end tools.
10 Exports the following classes:
12 * `OptionParser`: Standard Docutils command-line processing.
13 * `Option`: Customized version of `optparse.Option`; validation support.
14 * `Values`: Runtime settings; objects are simple structs
15 (``object.attribute``). Supports cumulative list settings (attributes).
16 * `ConfigParser`: Standard Docutils config file processing.
18 Also exports the following functions:
20 * Option callbacks: `store_multiple`, `read_config_file`.
21 * Setting validators: `validate_encoding`,
22 `validate_encoding_error_handler`,
23 `validate_encoding_and_error_handler`, `validate_boolean`,
24 `validate_threshold`, `validate_colon_separated_string_list`,
25 `validate_dependency_file`.
26 * `make_paths_absolute`.
27 """
29 __docformat__ = 'reStructuredText'
31 import os
32 import os.path
33 import sys
34 import types
35 import copy
36 import warnings
37 import ConfigParser as CP
38 import codecs
39 import docutils
40 import optparse
41 from optparse import SUPPRESS_HELP
44 def store_multiple(option, opt, value, parser, *args, **kwargs):
45 """
46 Store multiple values in `parser.values`. (Option callback.)
48 Store `None` for each attribute named in `args`, and store the value for
49 each key (attribute name) in `kwargs`.
50 """
51 for attribute in args:
52 setattr(parser.values, attribute, None)
53 for key, value in kwargs.items():
54 setattr(parser.values, key, value)
56 def read_config_file(option, opt, value, parser):
57 """
58 Read a configuration file during option processing. (Option callback.)
59 """
60 try:
61 new_settings = parser.get_config_file_settings(value)
62 except ValueError, error:
63 parser.error(error)
64 parser.values.update(new_settings, parser)
66 def validate_encoding(setting, value, option_parser,
67 config_parser=None, config_section=None):
68 try:
69 codecs.lookup(value)
70 except LookupError:
71 raise (LookupError('setting "%s": unknown encoding: "%s"'
72 % (setting, value)),
73 None, sys.exc_info()[2])
74 return value
76 def validate_encoding_error_handler(setting, value, option_parser,
77 config_parser=None, config_section=None):
78 try:
79 codecs.lookup_error(value)
80 except AttributeError: # prior to Python 2.3
81 if value not in ('strict', 'ignore', 'replace', 'xmlcharrefreplace'):
82 raise (LookupError(
83 'unknown encoding error handler: "%s" (choices: '
84 '"strict", "ignore", "replace", or "xmlcharrefreplace")' % value),
85 None, sys.exc_info()[2])
86 except LookupError:
87 raise (LookupError(
88 'unknown encoding error handler: "%s" (choices: '
89 '"strict", "ignore", "replace", "backslashreplace", '
90 '"xmlcharrefreplace", and possibly others; see documentation for '
91 'the Python ``codecs`` module)' % value),
92 None, sys.exc_info()[2])
93 return value
95 def validate_encoding_and_error_handler(
96 setting, value, option_parser, config_parser=None, config_section=None):
97 """
98 Side-effect: if an error handler is included in the value, it is inserted
99 into the appropriate place as if it was a separate setting/option.
101 if ':' in value:
102 encoding, handler = value.split(':')
103 validate_encoding_error_handler(
104 setting + '_error_handler', handler, option_parser,
105 config_parser, config_section)
106 if config_parser:
107 config_parser.set(config_section, setting + '_error_handler',
108 handler)
109 else:
110 setattr(option_parser.values, setting + '_error_handler', handler)
111 else:
112 encoding = value
113 validate_encoding(setting, encoding, option_parser,
114 config_parser, config_section)
115 return encoding
117 def validate_boolean(setting, value, option_parser,
118 config_parser=None, config_section=None):
119 if isinstance(value, types.StringType):
120 try:
121 return option_parser.booleans[value.strip().lower()]
122 except KeyError:
123 raise (LookupError('unknown boolean value: "%s"' % value),
124 None, sys.exc_info()[2])
125 return value
127 def validate_threshold(setting, value, option_parser,
128 config_parser=None, config_section=None):
129 try:
130 return int(value)
131 except ValueError:
132 try:
133 return option_parser.thresholds[value.lower()]
134 except (KeyError, AttributeError):
135 raise (LookupError('unknown threshold: %r.' % value),
136 None, sys.exc_info[2])
138 def validate_colon_separated_string_list(
139 setting, value, option_parser, config_parser=None, config_section=None):
140 if isinstance(value, types.StringType):
141 value = value.split(':')
142 else:
143 last = value.pop()
144 value.extend(last.split(':'))
145 return value
147 def validate_url_trailing_slash(
148 setting, value, option_parser, config_parser=None, config_section=None):
149 if not value:
150 return './'
151 elif value.endswith('/'):
152 return value
153 else:
154 return value + '/'
156 def validate_dependency_file(
157 setting, value, option_parser, config_parser=None, config_section=None):
158 try:
159 return docutils.utils.DependencyList(value)
160 except IOError:
161 return docutils.utils.DependencyList(None)
163 def make_paths_absolute(pathdict, keys, base_path=None):
165 Interpret filesystem path settings relative to the `base_path` given.
167 Paths are values in `pathdict` whose keys are in `keys`. Get `keys` from
168 `OptionParser.relative_path_settings`.
170 if base_path is None:
171 base_path = os.getcwd()
172 for key in keys:
173 if pathdict.has_key(key):
174 value = pathdict[key]
175 if isinstance(value, types.ListType):
176 value = [make_one_path_absolute(base_path, path)
177 for path in value]
178 elif value:
179 value = make_one_path_absolute(base_path, value)
180 pathdict[key] = value
182 def make_one_path_absolute(base_path, path):
183 return os.path.abspath(os.path.join(base_path, path))
186 class Values(optparse.Values):
189 Updates list attributes by extension rather than by replacement.
190 Works in conjunction with the `OptionParser.lists` instance attribute.
193 def __init__(self, *args, **kwargs):
194 optparse.Values.__init__(self, *args, **kwargs)
195 if (not hasattr(self, 'record_dependencies')
196 or self.record_dependencies is None):
197 # Set up dependency list, in case it is needed.
198 self.record_dependencies = docutils.utils.DependencyList()
200 def update(self, other_dict, option_parser):
201 if isinstance(other_dict, Values):
202 other_dict = other_dict.__dict__
203 other_dict = other_dict.copy()
204 for setting in option_parser.lists.keys():
205 if (hasattr(self, setting) and other_dict.has_key(setting)):
206 value = getattr(self, setting)
207 if value:
208 value += other_dict[setting]
209 del other_dict[setting]
210 self._update_loose(other_dict)
213 class Option(optparse.Option):
215 ATTRS = optparse.Option.ATTRS + ['validator', 'overrides']
217 def process(self, opt, value, values, parser):
219 Call the validator function on applicable settings and
220 evaluate the 'overrides' option.
221 Extends `optparse.Option.process`.
223 result = optparse.Option.process(self, opt, value, values, parser)
224 setting = self.dest
225 if setting:
226 if self.validator:
227 value = getattr(values, setting)
228 try:
229 new_value = self.validator(setting, value, parser)
230 except Exception, error:
231 raise (optparse.OptionValueError(
232 'Error in option "%s":\n %s: %s'
233 % (opt, error.__class__.__name__, error)),
234 None, sys.exc_info()[2])
235 setattr(values, setting, new_value)
236 if self.overrides:
237 setattr(values, self.overrides, None)
238 return result
241 class OptionParser(optparse.OptionParser, docutils.SettingsSpec):
244 Parser for command-line and library use. The `settings_spec`
245 specification here and in other Docutils components are merged to build
246 the set of command-line options and runtime settings for this process.
248 Common settings (defined below) and component-specific settings must not
249 conflict. Short options are reserved for common settings, and components
250 are restrict to using long options.
253 standard_config_files = [
254 '/etc/docutils.conf', # system-wide
255 './docutils.conf', # project-specific
256 '~/.docutils'] # user-specific
257 """Docutils configuration files, using ConfigParser syntax. Filenames
258 will be tilde-expanded later. Later files override earlier ones."""
260 threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split()
261 """Possible inputs for for --report and --halt threshold values."""
263 thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5}
264 """Lookup table for --report and --halt threshold values."""
266 booleans={'1': 1, 'on': 1, 'yes': 1, 'true': 1,
267 '0': 0, 'off': 0, 'no': 0, 'false': 0, '': 0}
268 """Lookup table for boolean configuration file settings."""
270 if hasattr(codecs, 'backslashreplace_errors'):
271 default_error_encoding_error_handler = 'backslashreplace'
272 else:
273 default_error_encoding_error_handler = 'replace'
275 settings_spec = (
276 'General Docutils Options',
277 None,
278 (('Include a "Generated by Docutils" credit and link at the end '
279 'of the document.',
280 ['--generator', '-g'], {'action': 'store_true',
281 'validator': validate_boolean}),
282 ('Do not include a generator credit.',
283 ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}),
284 ('Include the date at the end of the document (UTC).',
285 ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d',
286 'dest': 'datestamp'}),
287 ('Include the time & date at the end of the document (UTC).',
288 ['--time', '-t'], {'action': 'store_const',
289 'const': '%Y-%m-%d %H:%M UTC',
290 'dest': 'datestamp'}),
291 ('Do not include a datestamp of any kind.',
292 ['--no-datestamp'], {'action': 'store_const', 'const': None,
293 'dest': 'datestamp'}),
294 ('Include a "View document source" link (relative to destination).',
295 ['--source-link', '-s'], {'action': 'store_true',
296 'validator': validate_boolean}),
297 ('Use the supplied <URL> verbatim for a "View document source" '
298 'link; implies --source-link.',
299 ['--source-url'], {'metavar': '<URL>'}),
300 ('Do not include a "View document source" link.',
301 ['--no-source-link'],
302 {'action': 'callback', 'callback': store_multiple,
303 'callback_args': ('source_link', 'source_url')}),
304 ('Enable backlinks from section headers to table of contents '
305 'entries. This is the default.',
306 ['--toc-entry-backlinks'],
307 {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'entry',
308 'default': 'entry'}),
309 ('Enable backlinks from section headers to the top of the table of '
310 'contents.',
311 ['--toc-top-backlinks'],
312 {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'top'}),
313 ('Disable backlinks to the table of contents.',
314 ['--no-toc-backlinks'],
315 {'dest': 'toc_backlinks', 'action': 'store_false'}),
316 ('Enable backlinks from footnotes and citations to their '
317 'references. This is the default.',
318 ['--footnote-backlinks'],
319 {'action': 'store_true', 'default': 1,
320 'validator': validate_boolean}),
321 ('Disable backlinks from footnotes and citations.',
322 ['--no-footnote-backlinks'],
323 {'dest': 'footnote_backlinks', 'action': 'store_false'}),
324 ('Disable Docutils section numbering',
325 ['--no-section-numbering'],
326 {'action': 'store_false', 'dest': 'sectnum_xform',
327 'default': 1, 'validator': validate_boolean}),
328 ('Set verbosity threshold; report system messages at or higher than '
329 '<level> (by name or number: "info" or "1", warning/2, error/3, '
330 'severe/4; also, "none" or "5"). Default is 2 (warning).',
331 ['--report', '-r'], {'choices': threshold_choices, 'default': 2,
332 'dest': 'report_level', 'metavar': '<level>',
333 'validator': validate_threshold}),
334 ('Report all system messages, info-level and higher. (Same as '
335 '"--report=info".)',
336 ['--verbose', '-v'], {'action': 'store_const', 'const': 1,
337 'dest': 'report_level'}),
338 ('Do not report any system messages. (Same as "--report=none".)',
339 ['--quiet', '-q'], {'action': 'store_const', 'const': 5,
340 'dest': 'report_level'}),
341 ('Set the threshold (<level>) at or above which system messages are '
342 'converted to exceptions, halting execution immediately by '
343 'exiting (or propagating the exception if --traceback set). '
344 'Levels as in --report. Default is 4 (severe).',
345 ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level',
346 'default': 4, 'metavar': '<level>',
347 'validator': validate_threshold}),
348 ('Same as "--halt=info": halt processing at the slightest problem.',
349 ['--strict'], {'action': 'store_const', 'const': 'info',
350 'dest': 'halt_level'}),
351 ('Enable a non-zero exit status for normal exit if non-halting '
352 'system messages (at or above <level>) were generated. Levels as '
353 'in --report. Default is 5 (disabled). Exit status is the maximum '
354 'system message level plus 10 (11 for INFO, etc.).',
355 ['--exit-status'], {'choices': threshold_choices,
356 'dest': 'exit_status_level',
357 'default': 5, 'metavar': '<level>',
358 'validator': validate_threshold}),
359 ('Report debug-level system messages and generate diagnostic output.',
360 ['--debug'], {'action': 'store_true', 'validator': validate_boolean}),
361 ('Do not report debug-level system messages or generate diagnostic '
362 'output.',
363 ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}),
364 ('Send the output of system messages (warnings) to <file>.',
365 ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}),
366 ('Enable Python tracebacks when halt-level system messages and '
367 'other exceptions occur. Useful for debugging, and essential for '
368 'issue reports.',
369 ['--traceback'], {'action': 'store_true', 'default': None,
370 'validator': validate_boolean}),
371 ('Disable Python tracebacks when errors occur; report just the error '
372 'instead. This is the default.',
373 ['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}),
374 ('Specify the encoding of input text. Default is locale-dependent. '
375 'Optionally also specify the error handler for undecodable '
376 'characters, after a colon (":"); default is "strict". (See '
377 '"--intput-encoding-error-handler".)',
378 ['--input-encoding', '-i'],
379 {'metavar': '<name[:handler]>',
380 'validator': validate_encoding_and_error_handler}),
381 ('Specify the error handler for undecodable characters in '
382 'the input. Acceptable values include "strict", "ignore", and '
383 '"replace". Default is "strict". '
384 'Usually specified as part of --input-encoding.',
385 ['--input-encoding-error-handler'],
386 {'default': 'strict', 'validator': validate_encoding_error_handler}),
387 ('Specify the text encoding for output. Default is UTF-8. '
388 'Optionally also specify the error handler for unencodable '
389 'characters, after a colon (":"); default is "strict". (See '
390 '"--output-encoding-error-handler".)',
391 ['--output-encoding', '-o'],
392 {'metavar': '<name[:handler]>', 'default': 'utf-8',
393 'validator': validate_encoding_and_error_handler}),
394 ('Specify the error handler for unencodable characters in '
395 'the output. Acceptable values include "strict", "ignore", '
396 '"replace", "xmlcharrefreplace", and '
397 '"backslashreplace" (in Python 2.3+). Default is "strict". '
398 'Usually specified as part of --output-encoding.',
399 ['--output-encoding-error-handler'],
400 {'default': 'strict', 'validator': validate_encoding_error_handler}),
401 ('Specify the text encoding for error output. Default is ASCII. '
402 'Optionally also specify the error handler for unencodable '
403 'characters, after a colon (":"); default is "%s". (See '
404 '"--output-encoding-error-handler".)'
405 % default_error_encoding_error_handler,
406 ['--error-encoding', '-e'],
407 {'metavar': '<name[:handler]>', 'default': 'ascii',
408 'validator': validate_encoding_and_error_handler}),
409 ('Specify the error handler for unencodable characters in '
410 'error output. See --output-encoding-error-handler for acceptable '
411 'values. Default is "%s". Usually specified as part of '
412 '--error-encoding.' % default_error_encoding_error_handler,
413 ['--error-encoding-error-handler'],
414 {'default': default_error_encoding_error_handler,
415 'validator': validate_encoding_error_handler}),
416 ('Specify the language of input text (ISO 639 2-letter identifier).'
417 ' Default is "en" (English).',
418 ['--language', '-l'], {'dest': 'language_code', 'default': 'en',
419 'metavar': '<name>'}),
420 ('Write dependencies (caused e.g. by file inclusions) to '
421 '<file>. Useful in conjunction with programs like "make".',
422 ['--record-dependencies'],
423 {'metavar': '<file>', 'validator': validate_dependency_file,
424 'default': None}), # default set in Values class
425 ('Read configuration settings from <file>, if it exists.',
426 ['--config'], {'metavar': '<file>', 'type': 'string',
427 'action': 'callback', 'callback': read_config_file}),
428 ("Show this program's version number and exit.",
429 ['--version', '-V'], {'action': 'version'}),
430 ('Show this help message and exit.',
431 ['--help', '-h'], {'action': 'help'}),
432 # Hidden options, for development use only:
433 (SUPPRESS_HELP, ['--dump-settings'], {'action': 'store_true'}),
434 (SUPPRESS_HELP, ['--dump-internals'], {'action': 'store_true'}),
435 (SUPPRESS_HELP, ['--dump-transforms'], {'action': 'store_true'}),
436 (SUPPRESS_HELP, ['--dump-pseudo-xml'], {'action': 'store_true'}),
437 (SUPPRESS_HELP, ['--expose-internal-attribute'],
438 {'action': 'append', 'dest': 'expose_internals',
439 'validator': validate_colon_separated_string_list}),
440 (SUPPRESS_HELP, ['--strict-visitor'], {'action': 'store_true'}),
442 """Runtime settings and command-line options common to all Docutils front
443 ends. Setting specs specific to individual Docutils components are also
444 used (see `populate_from_components()`)."""
446 settings_defaults = {'_disable_config': None,
447 '_source': None,
448 '_destination': None}
449 """Defaults for settings that don't have command-line option equivalents."""
451 relative_path_settings = ('warning_stream',)
453 config_section = 'general'
455 version_template = '%%prog (Docutils %s)' % docutils.__version__
456 """Default version message."""
458 def __init__(self, components=(), defaults=None, read_config_files=None,
459 *args, **kwargs):
461 `components` is a list of Docutils components each containing a
462 ``.settings_spec`` attribute. `defaults` is a mapping of setting
463 default overrides.
466 self.lists = {}
467 """Set of list-type settings."""
469 optparse.OptionParser.__init__(
470 self, option_class=Option, add_help_option=None,
471 formatter=optparse.TitledHelpFormatter(width=78),
472 *args, **kwargs)
473 if not self.version:
474 self.version = self.version_template
475 # Make an instance copy (it will be modified):
476 self.relative_path_settings = list(self.relative_path_settings)
477 self.components = (self,) + tuple(components)
478 self.populate_from_components(self.components)
479 self.set_defaults(**(defaults or {}))
480 if read_config_files and not self.defaults['_disable_config']:
481 try:
482 config_settings = self.get_standard_config_settings()
483 except ValueError, error:
484 self.error(error)
485 self.set_defaults(**config_settings.__dict__)
487 def populate_from_components(self, components):
489 For each component, first populate from the `SettingsSpec.settings_spec`
490 structure, then from the `SettingsSpec.settings_defaults` dictionary.
491 After all components have been processed, check for and populate from
492 each component's `SettingsSpec.settings_default_overrides` dictionary.
494 for component in components:
495 if component is None:
496 continue
497 settings_spec = component.settings_spec
498 self.relative_path_settings.extend(
499 component.relative_path_settings)
500 for i in range(0, len(settings_spec), 3):
501 title, description, option_spec = settings_spec[i:i+3]
502 if title:
503 group = optparse.OptionGroup(self, title, description)
504 self.add_option_group(group)
505 else:
506 group = self # single options
507 for (help_text, option_strings, kwargs) in option_spec:
508 option = group.add_option(help=help_text, *option_strings,
509 **kwargs)
510 if kwargs.get('action') == 'append':
511 self.lists[option.dest] = 1
512 if component.settings_defaults:
513 self.defaults.update(component.settings_defaults)
514 for component in components:
515 if component and component.settings_default_overrides:
516 self.defaults.update(component.settings_default_overrides)
518 def get_standard_config_files(self):
519 """Return list of config files, from environment or standard."""
520 try:
521 config_files = os.environ['DOCUTILSCONFIG'].split(os.pathsep)
522 except KeyError:
523 config_files = self.standard_config_files
524 return [os.path.expanduser(f) for f in config_files if f.strip()]
526 def get_standard_config_settings(self):
527 settings = Values()
528 for filename in self.get_standard_config_files():
529 settings.update(self.get_config_file_settings(filename), self)
530 return settings
532 def get_config_file_settings(self, config_file):
533 """Returns a dictionary containing appropriate config file settings."""
534 parser = ConfigParser()
535 parser.read(config_file, self)
536 base_path = os.path.dirname(config_file)
537 applied = {}
538 settings = Values()
539 for component in self.components:
540 if not component:
541 continue
542 for section in (tuple(component.config_section_dependencies or ())
543 + (component.config_section,)):
544 if applied.has_key(section):
545 continue
546 applied[section] = 1
547 settings.update(parser.get_section(section), self)
548 make_paths_absolute(
549 settings.__dict__, self.relative_path_settings, base_path)
550 return settings.__dict__
552 def check_values(self, values, args):
553 """Store positional arguments as runtime settings."""
554 values._source, values._destination = self.check_args(args)
555 make_paths_absolute(values.__dict__, self.relative_path_settings,
556 os.getcwd())
557 return values
559 def check_args(self, args):
560 source = destination = None
561 if args:
562 source = args.pop(0)
563 if source == '-': # means stdin
564 source = None
565 if args:
566 destination = args.pop(0)
567 if destination == '-': # means stdout
568 destination = None
569 if args:
570 self.error('Maximum 2 arguments allowed.')
571 if source and source == destination:
572 self.error('Do not specify the same file for both source and '
573 'destination. It will clobber the source file.')
574 return source, destination
576 def get_default_values(self):
577 """Needed to get custom `Values` instances."""
578 return Values(self.defaults)
580 def get_option_by_dest(self, dest):
582 Get an option by its dest.
584 If you're supplying a dest which is shared by several options,
585 it is undefined which option of those is returned.
587 A KeyError is raised if there is no option with the supplied
588 dest.
590 for group in self.option_groups + [self]:
591 for option in group.option_list:
592 if option.dest == dest:
593 return option
594 raise KeyError('No option with dest == %r.' % dest)
597 class ConfigParser(CP.ConfigParser):
599 old_settings = {
600 'pep_stylesheet': ('pep_html writer', 'stylesheet'),
601 'pep_stylesheet_path': ('pep_html writer', 'stylesheet_path'),
602 'pep_template': ('pep_html writer', 'template')}
603 """{old setting: (new section, new setting)} mapping, used by
604 `handle_old_config`, to convert settings from the old [options] section."""
606 old_warning = """
607 The "[option]" section is deprecated. Support for old-format configuration
608 files may be removed in a future Docutils release. Please revise your
609 configuration files. See <http://docutils.sf.net/docs/user/config.html>,
610 section "Old-Format Configuration Files".
613 def read(self, filenames, option_parser):
614 if type(filenames) in (types.StringType, types.UnicodeType):
615 filenames = [filenames]
616 for filename in filenames:
617 CP.ConfigParser.read(self, filename)
618 if self.has_section('options'):
619 self.handle_old_config(filename)
620 self.validate_settings(filename, option_parser)
622 def handle_old_config(self, filename):
623 warnings.warn_explicit(self.old_warning, ConfigDeprecationWarning,
624 filename, 0)
625 options = self.get_section('options')
626 if not self.has_section('general'):
627 self.add_section('general')
628 for key, value in options.items():
629 if self.old_settings.has_key(key):
630 section, setting = self.old_settings[key]
631 if not self.has_section(section):
632 self.add_section(section)
633 else:
634 section = 'general'
635 setting = key
636 if not self.has_option(section, setting):
637 self.set(section, setting, value)
638 self.remove_section('options')
640 def validate_settings(self, filename, option_parser):
642 Call the validator function and implement overrides on all applicable
643 settings.
645 for section in self.sections():
646 for setting in self.options(section):
647 try:
648 option = option_parser.get_option_by_dest(setting)
649 except KeyError:
650 continue
651 if option.validator:
652 value = self.get(section, setting, raw=1)
653 try:
654 new_value = option.validator(
655 setting, value, option_parser,
656 config_parser=self, config_section=section)
657 except Exception, error:
658 raise (ValueError(
659 'Error in config file "%s", section "[%s]":\n'
660 ' %s: %s\n %s = %s'
661 % (filename, section, error.__class__.__name__,
662 error, setting, value)), None, sys.exc_info()[2])
663 self.set(section, setting, new_value)
664 if option.overrides:
665 self.set(section, option.overrides, None)
667 def optionxform(self, optionstr):
669 Transform '-' to '_' so the cmdline form of option names can be used.
671 return optionstr.lower().replace('-', '_')
673 def get_section(self, section):
675 Return a given section as a dictionary (empty if the section
676 doesn't exist).
678 section_dict = {}
679 if self.has_section(section):
680 for option in self.options(section):
681 section_dict[option] = self.get(section, option, raw=1)
682 return section_dict
685 class ConfigDeprecationWarning(DeprecationWarning):
686 """Warning for deprecated configuration file features."""