From 1d1eaa45c94a9b1dacfb9aa711c0d6ecf87cbd67 Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Wed, 14 May 2008 22:59:42 +0000 Subject: Renamed ConfigParser to configparser. Merged revisions 63247-63248 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r63247 | georg.brandl | 2008-05-14 18:30:31 -0400 (Wed, 14 May 2008) | 2 lines Update configparser docs for lowercasing rename. ........ r63248 | alexandre.vassalotti | 2008-05-14 18:44:22 -0400 (Wed, 14 May 2008) | 8 lines Updated import statements to use the new `configparser` module name. Updated the documentation to use the new name. Revert addition of the stub entry for the old name. Georg, I am reverting your changes since this commit should propagate to py3k. ........ --- Doc/library/configparser.rst | 29 +- Doc/library/logging.rst | 38 +-- Doc/library/shlex.rst | 2 +- Lib/ConfigParser.py | 669 ---------------------------------------- Lib/configparser.py | 669 ++++++++++++++++++++++++++++++++++++++++ Lib/distutils/command/upload.py | 2 +- Lib/distutils/dist.py | 2 +- Lib/idlelib/configHandler.py | 2 +- Lib/logging/config.py | 4 +- Lib/test/test___all__.py | 2 +- Lib/test/test_cfgparser.py | 36 +-- Misc/NEWS | 2 + 12 files changed, 730 insertions(+), 727 deletions(-) delete mode 100644 Lib/ConfigParser.py create mode 100644 Lib/configparser.py diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index a7ad2e7..75bfd92 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -1,15 +1,14 @@ - -:mod:`ConfigParser` --- Configuration file parser +:mod:`configparser` --- Configuration file parser ================================================= -.. module:: ConfigParser +.. module:: configparser :synopsis: Configuration file parser. + .. moduleauthor:: Ken Manheimer .. moduleauthor:: Barry Warsaw .. moduleauthor:: Eric S. Raymond .. sectionauthor:: Christopher G. Petrilli - .. index:: pair: .ini; file pair: configuration; file @@ -213,9 +212,9 @@ RawConfigParser Objects load the required file or files using :meth:`readfp` before calling :meth:`read` for any optional files:: - import ConfigParser, os + import configparser, os - config = ConfigParser.ConfigParser() + config = configparser.ConfigParser() config.readfp(open('defaults.cfg')) config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')]) @@ -342,9 +341,9 @@ Examples An example of writing to a configuration file:: - import ConfigParser + import configparser - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() # When adding sections or items, add them in the reverse order of # how you want them to be displayed in the actual file. @@ -367,9 +366,9 @@ An example of writing to a configuration file:: An example of reading the configuration file again:: - import ConfigParser + import configparser - config = ConfigParser.RawConfigParser() + config = configparser.RawConfigParser() config.read('example.cfg') # getfloat() raises an exception if the value is not a float @@ -386,9 +385,9 @@ An example of reading the configuration file again:: To get interpolation, you will need to use a :class:`ConfigParser` or :class:`SafeConfigParser`:: - import ConfigParser + import configparser - config = ConfigParser.ConfigParser() + config = configparser.ConfigParser() config.read('example.cfg') # Set the third, optional argument of get to 1 if you wish to use raw mode. @@ -403,10 +402,10 @@ To get interpolation, you will need to use a :class:`ConfigParser` or Defaults are available in all three types of ConfigParsers. They are used in interpolation if an option used is not defined elsewhere. :: - import ConfigParser + import configparser # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each - config = ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'}) + config = configparser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'}) config.read('example.cfg') print(config.get('Section1', 'foo')) # -> "Python is fun!" @@ -419,7 +418,7 @@ The function ``opt_move`` below can be used to move options between sections:: def opt_move(config, section1, section2, option): try: config.set(section2, option, config.get(section1, option, 1)) - except ConfigParser.NoSectionError: + except configparser.NoSectionError: # Create non-existent section config.add_section(section2) opt_move(config, section1, section2, option) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 365776a..cac29e9 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -2202,12 +2202,12 @@ in :mod:`logging` itself) and defining handlers which are declared either in .. function:: fileConfig(fname[, defaults]) - Reads the logging configuration from a ConfigParser-format file named *fname*. - This function can be called several times from an application, allowing an end - user the ability to select from various pre-canned configurations (if the - developer provides a mechanism to present the choices and load the chosen - configuration). Defaults to be passed to ConfigParser can be specified in the - *defaults* argument. + Reads the logging configuration from a :mod:`configparser`\-format file named + *fname*. This function can be called several times from an application, + allowing an end user the ability to select from various pre-canned + configurations (if the developer provides a mechanism to present the choices + and load the chosen configuration). Defaults to be passed to the ConfigParser + can be specified in the *defaults* argument. .. function:: listen([port]) @@ -2237,18 +2237,20 @@ in :mod:`logging` itself) and defining handlers which are declared either in Configuration file format ^^^^^^^^^^^^^^^^^^^^^^^^^ -The configuration file format understood by :func:`fileConfig` is based on -ConfigParser functionality. The file must contain sections called ``[loggers]``, -``[handlers]`` and ``[formatters]`` which identify by name the entities of each -type which are defined in the file. For each such entity, there is a separate -section which identified how that entity is configured. Thus, for a logger named -``log01`` in the ``[loggers]`` section, the relevant configuration details are -held in a section ``[logger_log01]``. Similarly, a handler called ``hand01`` in -the ``[handlers]`` section will have its configuration held in a section called -``[handler_hand01]``, while a formatter called ``form01`` in the -``[formatters]`` section will have its configuration specified in a section -called ``[formatter_form01]``. The root logger configuration must be specified -in a section called ``[logger_root]``. +The configuration file format understood by :func:`fileConfig` is +based on :mod:`configparser` functionality. The file must contain +sections called ``[loggers]``, ``[handlers]`` and ``[formatters]`` +which identify by name the entities of each type which are defined in +the file. For each such entity, there is a separate section which +identified how that entity is configured. Thus, for a logger named +``log01`` in the ``[loggers]`` section, the relevant configuration +details are held in a section ``[logger_log01]``. Similarly, a handler +called ``hand01`` in the ``[handlers]`` section will have its +configuration held in a section called ``[handler_hand01]``, while a +formatter called ``form01`` in the ``[formatters]`` section will have +its configuration specified in a section called +``[formatter_form01]``. The root logger configuration must be +specified in a section called ``[logger_root]``. Examples of these sections in the file are given below. :: diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index 7d88610..1b1e6fe 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -55,7 +55,7 @@ The :mod:`shlex` module defines the following class: .. seealso:: - Module :mod:`ConfigParser` + Module :mod:`configparser` Parser for configuration files similar to the Windows :file:`.ini` files. diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py deleted file mode 100644 index 5e36cc9..0000000 --- a/Lib/ConfigParser.py +++ /dev/null @@ -1,669 +0,0 @@ -"""Configuration file parser. - -A setup file consists of sections, lead by a "[section]" header, -and followed by "name: value" entries, with continuations and such in -the style of RFC 822. - -The option values can contain format strings which refer to other values in -the same section, or values in a special [DEFAULT] section. - -For example: - - something: %(dir)s/whatever - -would resolve the "%(dir)s" to the value of dir. All reference -expansions are done late, on demand. - -Intrinsic defaults can be specified by passing them into the -ConfigParser constructor as a dictionary. - -class: - -ConfigParser -- responsible for parsing a list of - configuration files, and managing the parsed database. - - methods: - - __init__(defaults=None) - create the parser and specify a dictionary of intrinsic defaults. The - keys must be strings, the values must be appropriate for %()s string - interpolation. Note that `__name__' is always an intrinsic default; - its value is the section's name. - - sections() - return all the configuration section names, sans DEFAULT - - has_section(section) - return whether the given section exists - - has_option(section, option) - return whether the given option exists in the given section - - options(section) - return list of configuration options for the named section - - read(filenames) - read and parse the list of named configuration files, given by - name. A single filename is also allowed. Non-existing files - are ignored. Return list of successfully read files. - - readfp(fp, filename=None) - read and parse one configuration file, given as a file object. - The filename defaults to fp.name; it is only used in error - messages (if fp has no `name' attribute, the string `' is used). - - get(section, option, raw=False, vars=None) - return a string value for the named option. All % interpolations are - expanded in the return values, based on the defaults passed into the - constructor and the DEFAULT section. Additional substitutions may be - provided using the `vars' argument, which must be a dictionary whose - contents override any pre-existing defaults. - - getint(section, options) - like get(), but convert value to an integer - - getfloat(section, options) - like get(), but convert value to a float - - getboolean(section, options) - like get(), but convert value to a boolean (currently case - insensitively defined as 0, false, no, off for False, and 1, true, - yes, on for True). Returns False or True. - - items(section, raw=False, vars=None) - return a list of tuples with (name, value) for each option - in the section. - - remove_section(section) - remove the given file section and all its options - - remove_option(section, option) - remove the given option from the given section - - set(section, option, value) - set the given option - - write(fp) - write the configuration state in .ini format -""" - -import re - -__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", - "InterpolationError", "InterpolationDepthError", - "InterpolationSyntaxError", "ParsingError", - "MissingSectionHeaderError", - "ConfigParser", "SafeConfigParser", "RawConfigParser", - "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] - -DEFAULTSECT = "DEFAULT" - -MAX_INTERPOLATION_DEPTH = 10 - - - -# exception classes -class Error(Exception): - """Base class for ConfigParser exceptions.""" - - def _get_message(self): - """Getter for 'message'; needed only to override deprecation in - BaseException.""" - return self.__message - - def _set_message(self, value): - """Setter for 'message'; needed only to override deprecation in - BaseException.""" - self.__message = value - - # BaseException.message has been deprecated since Python 2.6. To prevent - # DeprecationWarning from popping up over this pre-existing attribute, use - # a new property that takes lookup precedence. - message = property(_get_message, _set_message) - - def __init__(self, msg=''): - self.message = msg - Exception.__init__(self, msg) - - def __repr__(self): - return self.message - - __str__ = __repr__ - -class NoSectionError(Error): - """Raised when no section matches a requested option.""" - - def __init__(self, section): - Error.__init__(self, 'No section: %r' % (section,)) - self.section = section - -class DuplicateSectionError(Error): - """Raised when a section is multiply-created.""" - - def __init__(self, section): - Error.__init__(self, "Section %r already exists" % section) - self.section = section - -class NoOptionError(Error): - """A requested option was not found.""" - - def __init__(self, option, section): - Error.__init__(self, "No option %r in section: %r" % - (option, section)) - self.option = option - self.section = section - -class InterpolationError(Error): - """Base class for interpolation-related exceptions.""" - - def __init__(self, option, section, msg): - Error.__init__(self, msg) - self.option = option - self.section = section - -class InterpolationMissingOptionError(InterpolationError): - """A string substitution required a setting which was not available.""" - - def __init__(self, option, section, rawval, reference): - msg = ("Bad value substitution:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\tkey : %s\n" - "\trawval : %s\n" - % (section, option, reference, rawval)) - InterpolationError.__init__(self, option, section, msg) - self.reference = reference - -class InterpolationSyntaxError(InterpolationError): - """Raised when the source text into which substitutions are made - does not conform to the required syntax.""" - -class InterpolationDepthError(InterpolationError): - """Raised when substitutions are nested too deeply.""" - - def __init__(self, option, section, rawval): - msg = ("Value interpolation too deeply recursive:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\trawval : %s\n" - % (section, option, rawval)) - InterpolationError.__init__(self, option, section, msg) - -class ParsingError(Error): - """Raised when a configuration file does not follow legal syntax.""" - - def __init__(self, filename): - Error.__init__(self, 'File contains parsing errors: %s' % filename) - self.filename = filename - self.errors = [] - - def append(self, lineno, line): - self.errors.append((lineno, line)) - self.message += '\n\t[line %2d]: %s' % (lineno, line) - -class MissingSectionHeaderError(ParsingError): - """Raised when a key-value pair is found before any section header.""" - - def __init__(self, filename, lineno, line): - Error.__init__( - self, - 'File contains no section headers.\nfile: %s, line: %d\n%r' % - (filename, lineno, line)) - self.filename = filename - self.lineno = lineno - self.line = line - - -class RawConfigParser: - def __init__(self, defaults=None, dict_type=dict): - self._dict = dict_type - self._sections = self._dict() - self._defaults = self._dict() - if defaults: - for key, value in defaults.items(): - self._defaults[self.optionxform(key)] = value - - def defaults(self): - return self._defaults - - def sections(self): - """Return a list of section names, excluding [DEFAULT]""" - # self._sections will never have [DEFAULT] in it - return list(self._sections.keys()) - - def add_section(self, section): - """Create a new section in the configuration. - - Raise DuplicateSectionError if a section by the specified name - already exists. Raise ValueError if name is DEFAULT or any of it's - case-insensitive variants. - """ - if section.lower() == "default": - raise ValueError('Invalid section name: %s' % section) - - if section in self._sections: - raise DuplicateSectionError(section) - self._sections[section] = self._dict() - - def has_section(self, section): - """Indicate whether the named section is present in the configuration. - - The DEFAULT section is not acknowledged. - """ - return section in self._sections - - def options(self, section): - """Return a list of option names for the given section name.""" - try: - opts = self._sections[section].copy() - except KeyError: - raise NoSectionError(section) - opts.update(self._defaults) - if '__name__' in opts: - del opts['__name__'] - return list(opts.keys()) - - def read(self, filenames): - """Read and parse a filename or a list of filenames. - - Files that cannot be opened are silently ignored; this is - designed so that you can specify a list of potential - configuration file locations (e.g. current directory, user's - home directory, systemwide directory), and all existing - configuration files in the list will be read. A single - filename may also be given. - - Return list of successfully read files. - """ - if isinstance(filenames, str): - filenames = [filenames] - read_ok = [] - for filename in filenames: - try: - fp = open(filename) - except IOError: - continue - self._read(fp, filename) - fp.close() - read_ok.append(filename) - return read_ok - - def readfp(self, fp, filename=None): - """Like read() but the argument must be a file-like object. - - The `fp' argument must have a `readline' method. Optional - second argument is the `filename', which if not given, is - taken from fp.name. If fp has no `name' attribute, `' is - used. - - """ - if filename is None: - try: - filename = fp.name - except AttributeError: - filename = '' - self._read(fp, filename) - - def get(self, section, option): - opt = self.optionxform(option) - if section not in self._sections: - if section != DEFAULTSECT: - raise NoSectionError(section) - if opt in self._defaults: - return self._defaults[opt] - else: - raise NoOptionError(option, section) - elif opt in self._sections[section]: - return self._sections[section][opt] - elif opt in self._defaults: - return self._defaults[opt] - else: - raise NoOptionError(option, section) - - def items(self, section): - try: - d2 = self._sections[section] - except KeyError: - if section != DEFAULTSECT: - raise NoSectionError(section) - d2 = self._dict() - d = self._defaults.copy() - d.update(d2) - if "__name__" in d: - del d["__name__"] - return d.items() - - def _get(self, section, conv, option): - return conv(self.get(section, option)) - - def getint(self, section, option): - return self._get(section, int, option) - - def getfloat(self, section, option): - return self._get(section, float, option) - - _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, - '0': False, 'no': False, 'false': False, 'off': False} - - def getboolean(self, section, option): - v = self.get(section, option) - if v.lower() not in self._boolean_states: - raise ValueError('Not a boolean: %s' % v) - return self._boolean_states[v.lower()] - - def optionxform(self, optionstr): - return optionstr.lower() - - def has_option(self, section, option): - """Check for the existence of a given option in a given section.""" - if not section or section == DEFAULTSECT: - option = self.optionxform(option) - return option in self._defaults - elif section not in self._sections: - return False - else: - option = self.optionxform(option) - return (option in self._sections[section] - or option in self._defaults) - - def set(self, section, option, value): - """Set an option.""" - if not section or section == DEFAULTSECT: - sectdict = self._defaults - else: - try: - sectdict = self._sections[section] - except KeyError: - raise NoSectionError(section) - sectdict[self.optionxform(option)] = value - - def write(self, fp): - """Write an .ini-format representation of the configuration state.""" - if self._defaults: - fp.write("[%s]\n" % DEFAULTSECT) - for (key, value) in self._defaults.items(): - fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) - fp.write("\n") - for section in self._sections: - fp.write("[%s]\n" % section) - for (key, value) in self._sections[section].items(): - if key != "__name__": - fp.write("%s = %s\n" % - (key, str(value).replace('\n', '\n\t'))) - fp.write("\n") - - def remove_option(self, section, option): - """Remove an option.""" - if not section or section == DEFAULTSECT: - sectdict = self._defaults - else: - try: - sectdict = self._sections[section] - except KeyError: - raise NoSectionError(section) - option = self.optionxform(option) - existed = option in sectdict - if existed: - del sectdict[option] - return existed - - def remove_section(self, section): - """Remove a file section.""" - existed = section in self._sections - if existed: - del self._sections[section] - return existed - - # - # Regular expressions for parsing section headers and options. - # - SECTCRE = re.compile( - r'\[' # [ - r'(?P
[^]]+)' # very permissive! - r'\]' # ] - ) - OPTCRE = re.compile( - r'(?P