[Python-3000-checkins] r63251 - in python/branches/py3k: Doc/library/configparser.rst Doc/library/logging.rst Doc/library/shlex.rst Lib/ConfigParser.py Lib/configparser.py Lib/distutils/command/upload.py Lib/distutils/dist.py Lib/idlelib/configHandler.py Lib/logging/config.py Lib/test/test___all__.py Lib/test/test_cfgparser.py Misc/NEWS
alexandre.vassalotti
python-3000-checkins at python.org
Thu May 15 00:59:42 CEST 2008
Author: alexandre.vassalotti
Date: Thu May 15 00:59:42 2008
New Revision: 63251
Log:
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.
........
Added:
python/branches/py3k/Lib/configparser.py
- copied unchanged from r63249, /python/branches/py3k/Lib/ConfigParser.py
Removed:
python/branches/py3k/Lib/ConfigParser.py
Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Doc/library/configparser.rst
python/branches/py3k/Doc/library/logging.rst
python/branches/py3k/Doc/library/shlex.rst
python/branches/py3k/Lib/distutils/command/upload.py
python/branches/py3k/Lib/distutils/dist.py
python/branches/py3k/Lib/idlelib/configHandler.py
python/branches/py3k/Lib/logging/config.py
python/branches/py3k/Lib/test/test___all__.py
python/branches/py3k/Lib/test/test_cfgparser.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/configparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/configparser.rst (original)
+++ python/branches/py3k/Doc/library/configparser.rst Thu May 15 00:59:42 2008
@@ -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 <klm at zope.com>
.. moduleauthor:: Barry Warsaw <bwarsaw at python.org>
.. moduleauthor:: Eric S. Raymond <esr at thyrsus.com>
.. sectionauthor:: Christopher G. Petrilli <petrilli at amber.org>
-
.. index::
pair: .ini; file
pair: configuration; file
@@ -213,9 +212,9 @@
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 @@
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 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 @@
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 @@
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 @@
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)
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Thu May 15 00:59:42 2008
@@ -2202,12 +2202,12 @@
.. 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 @@
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. ::
Modified: python/branches/py3k/Doc/library/shlex.rst
==============================================================================
--- python/branches/py3k/Doc/library/shlex.rst (original)
+++ python/branches/py3k/Doc/library/shlex.rst Thu May 15 00:59:42 2008
@@ -55,7 +55,7 @@
.. seealso::
- Module :mod:`ConfigParser`
+ Module :mod:`configparser`
Parser for configuration files similar to the Windows :file:`.ini` files.
Deleted: python/branches/py3k/Lib/ConfigParser.py
==============================================================================
--- python/branches/py3k/Lib/ConfigParser.py Thu May 15 00:59:42 2008
+++ (empty file)
@@ -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<header>[^]]+)' # very permissive!
- r'\]' # ]
- )
- OPTCRE = re.compile(
- r'(?P<option>[^:=\s][^:=]*)' # very permissive!
- r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
- # followed by separator
- # (either : or =), followed
- # by any # space/tab
- r'(?P<value>.*)$' # everything up to eol
- )
-
- def _read(self, fp, fpname):
- """Parse a sectioned setup file.
-
- The sections in setup file contains a title line at the top,
- indicated by a name in square brackets (`[]'), plus key/value
- options lines, indicated by `name: value' format lines.
- Continuations are represented by an embedded newline then
- leading whitespace. Blank lines, lines beginning with a '#',
- and just about everything else are ignored.
- """
- cursect = None # None, or a dictionary
- optname = None
- lineno = 0
- e = None # None, or an exception
- while True:
- line = fp.readline()
- if not line:
- break
- lineno = lineno + 1
- # comment or blank line?
- if line.strip() == '' or line[0] in '#;':
- continue
- if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
- # no leading whitespace
- continue
- # continuation line?
- if line[0].isspace() and cursect is not None and optname:
- value = line.strip()
- if value:
- cursect[optname] = "%s\n%s" % (cursect[optname], value)
- # a section header or option header?
- else:
- # is it a section header?
- mo = self.SECTCRE.match(line)
- if mo:
- sectname = mo.group('header')
- if sectname in self._sections:
- cursect = self._sections[sectname]
- elif sectname == DEFAULTSECT:
- cursect = self._defaults
- else:
- cursect = self._dict()
- cursect['__name__'] = sectname
- self._sections[sectname] = cursect
- # So sections can't start with a continuation line
- optname = None
- # no section header in the file?
- elif cursect is None:
- raise MissingSectionHeaderError(fpname, lineno, line)
- # an option line?
- else:
- mo = self.OPTCRE.match(line)
- if mo:
- optname, vi, optval = mo.group('option', 'vi', 'value')
- if vi in ('=', ':') and ';' in optval:
- # ';' is a comment delimiter only if it follows
- # a spacing character
- pos = optval.find(';')
- if pos != -1 and optval[pos-1].isspace():
- optval = optval[:pos]
- optval = optval.strip()
- # allow empty values
- if optval == '""':
- optval = ''
- optname = self.optionxform(optname.rstrip())
- cursect[optname] = optval
- else:
- # a non-fatal parsing error occurred. set up the
- # exception but keep going. the exception will be
- # raised at the end of the file and will contain a
- # list of all bogus lines
- if not e:
- e = ParsingError(fpname)
- e.append(lineno, repr(line))
- # if any parsing errors occurred, raise an exception
- if e:
- raise e
-
-
-class ConfigParser(RawConfigParser):
-
- def get(self, section, option, raw=False, vars=None):
- """Get an option value for a given section.
-
- All % interpolations are expanded in the return values, based on the
- defaults passed into the constructor, unless the optional argument
- `raw' is true. Additional substitutions may be provided using the
- `vars' argument, which must be a dictionary whose contents overrides
- any pre-existing defaults.
-
- The section DEFAULT is special.
- """
- d = self._defaults.copy()
- try:
- d.update(self._sections[section])
- except KeyError:
- if section != DEFAULTSECT:
- raise NoSectionError(section)
- # Update with the entry specific variables
- if vars:
- for key, value in vars.items():
- d[self.optionxform(key)] = value
- option = self.optionxform(option)
- try:
- value = d[option]
- except KeyError:
- raise NoOptionError(option, section)
-
- if raw:
- return value
- else:
- return self._interpolate(section, option, value, d)
-
- def items(self, section, raw=False, vars=None):
- """Return a list of tuples with (name, value) for each option
- in the section.
-
- All % interpolations are expanded in the return values, based on the
- defaults passed into the constructor, unless the optional argument
- `raw' is true. Additional substitutions may be provided using the
- `vars' argument, which must be a dictionary whose contents overrides
- any pre-existing defaults.
-
- The section DEFAULT is special.
- """
- d = self._defaults.copy()
- try:
- d.update(self._sections[section])
- except KeyError:
- if section != DEFAULTSECT:
- raise NoSectionError(section)
- # Update with the entry specific variables
- if vars:
- for key, value in vars.items():
- d[self.optionxform(key)] = value
- options = list(d.keys())
- if "__name__" in options:
- options.remove("__name__")
- if raw:
- return [(option, d[option])
- for option in options]
- else:
- return [(option, self._interpolate(section, option, d[option], d))
- for option in options]
-
- def _interpolate(self, section, option, rawval, vars):
- # do the string interpolation
- value = rawval
- depth = MAX_INTERPOLATION_DEPTH
- while depth: # Loop through this until it's done
- depth -= 1
- if "%(" in value:
- value = self._KEYCRE.sub(self._interpolation_replace, value)
- try:
- value = value % vars
- except KeyError as e:
- raise InterpolationMissingOptionError(
- option, section, rawval, e.args[0])
- else:
- break
- if "%(" in value:
- raise InterpolationDepthError(option, section, rawval)
- return value
-
- _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
-
- def _interpolation_replace(self, match):
- s = match.group(1)
- if s is None:
- return match.group()
- else:
- return "%%(%s)s" % self.optionxform(s)
-
-
-class SafeConfigParser(ConfigParser):
-
- def _interpolate(self, section, option, rawval, vars):
- # do the string interpolation
- L = []
- self._interpolate_some(option, L, rawval, section, vars, 1)
- return ''.join(L)
-
- _interpvar_re = re.compile(r"%\(([^)]+)\)s")
- _badpercent_re = re.compile(r"%[^%]|%$")
-
- def _interpolate_some(self, option, accum, rest, section, map, depth):
- if depth > MAX_INTERPOLATION_DEPTH:
- raise InterpolationDepthError(option, section, rest)
- while rest:
- p = rest.find("%")
- if p < 0:
- accum.append(rest)
- return
- if p > 0:
- accum.append(rest[:p])
- rest = rest[p:]
- # p is no longer used
- c = rest[1:2]
- if c == "%":
- accum.append("%")
- rest = rest[2:]
- elif c == "(":
- m = self._interpvar_re.match(rest)
- if m is None:
- raise InterpolationSyntaxError(option, section,
- "bad interpolation variable reference %r" % rest)
- var = self.optionxform(m.group(1))
- rest = rest[m.end():]
- try:
- v = map[var]
- except KeyError:
- raise InterpolationMissingOptionError(
- option, section, rest, var)
- if "%" in v:
- self._interpolate_some(option, accum, v,
- section, map, depth + 1)
- else:
- accum.append(v)
- else:
- raise InterpolationSyntaxError(
- option, section,
- "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
-
- def set(self, section, option, value):
- """Set an option. Extend ConfigParser.set: check for string values."""
- if not isinstance(value, str):
- raise TypeError("option values must be strings")
- # check for bad percent signs:
- # first, replace all "good" interpolations
- tmp_value = self._interpvar_re.sub('', value)
- # then, check if there's a lone percent sign left
- m = self._badpercent_re.search(tmp_value)
- if m:
- raise ValueError("invalid interpolation syntax in %r at "
- "position %d" % (value, m.start()))
- ConfigParser.set(self, section, option, value)
Modified: python/branches/py3k/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/upload.py (original)
+++ python/branches/py3k/Lib/distutils/command/upload.py Thu May 15 00:59:42 2008
@@ -10,7 +10,7 @@
import os
import socket
import platform
-import ConfigParser
+import configparser
import httplib
import base64
import urlparse
Modified: python/branches/py3k/Lib/distutils/dist.py
==============================================================================
--- python/branches/py3k/Lib/distutils/dist.py (original)
+++ python/branches/py3k/Lib/distutils/dist.py Thu May 15 00:59:42 2008
@@ -349,7 +349,7 @@
def parse_config_files (self, filenames=None):
- from ConfigParser import ConfigParser
+ from configparser import ConfigParser
if filenames is None:
filenames = self.find_config_files()
Modified: python/branches/py3k/Lib/idlelib/configHandler.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/configHandler.py (original)
+++ python/branches/py3k/Lib/idlelib/configHandler.py Thu May 15 00:59:42 2008
@@ -21,7 +21,7 @@
import sys
from idlelib import macosxSupport
-from ConfigParser import ConfigParser, NoOptionError, NoSectionError
+from configparser import ConfigParser, NoOptionError, NoSectionError
class InvalidConfigType(Exception): pass
class InvalidConfigSet(Exception): pass
Modified: python/branches/py3k/Lib/logging/config.py
==============================================================================
--- python/branches/py3k/Lib/logging/config.py (original)
+++ python/branches/py3k/Lib/logging/config.py Thu May 15 00:59:42 2008
@@ -62,9 +62,9 @@
rather than a filename, in which case the file-like object will be read
using readfp.
"""
- import ConfigParser
+ import configparser
- cp = ConfigParser.ConfigParser(defaults)
+ cp = configparser.ConfigParser(defaults)
if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
cp.readfp(fname)
else:
Modified: python/branches/py3k/Lib/test/test___all__.py
==============================================================================
--- python/branches/py3k/Lib/test/test___all__.py (original)
+++ python/branches/py3k/Lib/test/test___all__.py Thu May 15 00:59:42 2008
@@ -34,7 +34,7 @@
self.check_all("BaseHTTPServer")
self.check_all("CGIHTTPServer")
- self.check_all("ConfigParser")
+ self.check_all("configparser")
self.check_all("Cookie")
self.check_all("Queue")
self.check_all("SimpleHTTPServer")
Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py (original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py Thu May 15 00:59:42 2008
@@ -1,4 +1,4 @@
-import ConfigParser
+import configparser
import io
import unittest
import collections
@@ -89,7 +89,7 @@
"remove_option() failed to report non-existance of option"
" that was removed")
- self.assertRaises(ConfigParser.NoSectionError,
+ self.assertRaises(configparser.NoSectionError,
cf.remove_option, 'No Such Section', 'foo')
eq(cf.get('Long Line', 'foo'),
@@ -142,17 +142,17 @@
def test_parse_errors(self):
self.newconfig()
- self.parse_error(ConfigParser.ParsingError,
+ self.parse_error(configparser.ParsingError,
"[Foo]\n extra-spaces: splat\n")
- self.parse_error(ConfigParser.ParsingError,
+ self.parse_error(configparser.ParsingError,
"[Foo]\n extra-spaces= splat\n")
- self.parse_error(ConfigParser.ParsingError,
+ self.parse_error(configparser.ParsingError,
"[Foo]\noption-without-value\n")
- self.parse_error(ConfigParser.ParsingError,
+ self.parse_error(configparser.ParsingError,
"[Foo]\n:value-without-option-name\n")
- self.parse_error(ConfigParser.ParsingError,
+ self.parse_error(configparser.ParsingError,
"[Foo]\n=value-without-option-name\n")
- self.parse_error(ConfigParser.MissingSectionHeaderError,
+ self.parse_error(configparser.MissingSectionHeaderError,
"No Section!\n")
def parse_error(self, exc, src):
@@ -165,13 +165,13 @@
"new ConfigParser should have no defined sections")
self.failIf(cf.has_section("Foo"),
"new ConfigParser should have no acknowledged sections")
- self.assertRaises(ConfigParser.NoSectionError,
+ self.assertRaises(configparser.NoSectionError,
cf.options, "Foo")
- self.assertRaises(ConfigParser.NoSectionError,
+ self.assertRaises(configparser.NoSectionError,
cf.set, "foo", "bar", "value")
- self.get_error(ConfigParser.NoSectionError, "foo", "bar")
+ self.get_error(configparser.NoSectionError, "foo", "bar")
cf.add_section("foo")
- self.get_error(ConfigParser.NoOptionError, "foo", "bar")
+ self.get_error(configparser.NoOptionError, "foo", "bar")
def get_error(self, exc, section, option):
try:
@@ -210,7 +210,7 @@
def test_weird_errors(self):
cf = self.newconfig()
cf.add_section("Foo")
- self.assertRaises(ConfigParser.DuplicateSectionError,
+ self.assertRaises(configparser.DuplicateSectionError,
cf.add_section, "Foo")
def test_write(self):
@@ -314,7 +314,7 @@
class ConfigParserTestCase(TestCaseBase):
- config_class = ConfigParser.ConfigParser
+ config_class = configparser.ConfigParser
def test_interpolation(self):
cf = self.get_interpolation_config()
@@ -325,11 +325,11 @@
"something with lots of interpolation (9 steps)")
eq(cf.get("Foo", "bar10"),
"something with lots of interpolation (10 steps)")
- self.get_error(ConfigParser.InterpolationDepthError, "Foo", "bar11")
+ self.get_error(configparser.InterpolationDepthError, "Foo", "bar11")
def test_interpolation_missing_value(self):
cf = self.get_interpolation_config()
- e = self.get_error(ConfigParser.InterpolationError,
+ e = self.get_error(configparser.InterpolationError,
"Interpolation Error", "name")
self.assertEqual(e.reference, "reference")
self.assertEqual(e.section, "Interpolation Error")
@@ -365,7 +365,7 @@
class RawConfigParserTestCase(TestCaseBase):
- config_class = ConfigParser.RawConfigParser
+ config_class = configparser.RawConfigParser
def test_interpolation(self):
cf = self.get_interpolation_config()
@@ -400,7 +400,7 @@
class SafeConfigParserTestCase(ConfigParserTestCase):
- config_class = ConfigParser.SafeConfigParser
+ config_class = configparser.SafeConfigParser
def test_safe_interpolation(self):
# See http://www.python.org/sf/511737
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu May 15 00:59:42 2008
@@ -28,6 +28,8 @@
Library
-------
+- The ConfigParser module has been renamed to configparser.
+
- Issue 2865: webbrowser.open() works again in a KDE environment.
- The multifile module has been removed.
More information about the Python-3000-checkins
mailing list