Commit 314034af authored by Agustin Henze's avatar Agustin Henze

New upstream version 3.5.0

parent 5890b607
This diff is collapsed.
......@@ -4,13 +4,15 @@ configparser
The ancient ``ConfigParser`` module available in the standard library 2.x has
seen a major update in Python 3.2. This is a backport of those changes so that
they can be used directly in Python 2.6 - 2.7.
they can be used directly in Python 2.6 - 3.5.
To use ``configparser`` instead of ``ConfigParser``, simply replace::
import ConfigParser
To use the ``configparser`` backport instead of the built-in version on both
Python 2 and Python 3, simply import it explicitly as a backport::
with::
from backports import configparser
If you'd like to use the backport on Python 2 and the built-in version on
Python 3, use that invocation instead::
import configparser
......@@ -51,7 +53,7 @@ sports a bunch of interesting new features:
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'
* there's now one default ``ConfigParser`` class, which basically is the old
``SafeConfigParser`` with a bunch of tweaks which make it more predictable for
users. Don't need interpolation? Simply use
......@@ -70,14 +72,14 @@ sports a bunch of interesting new features:
* the classic ``%(string-like)s`` syntax (called ``BasicInterpolation``)
* a new ``${buildout:like}`` syntax (called ``ExtendedInterpolation``)
* fallback values may be specified in getters (`more info
<http://docs.python.org/3/library/configparser.html#fallback-values>`__)::
>>> config.get('closet', 'monster',
... fallback='No such things as monsters')
'No such things as monsters'
* ``ConfigParser`` objects can now read data directly `from strings
<http://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read_string>`__
and `from dictionaries
......@@ -85,7 +87,7 @@ sports a bunch of interesting new features:
That means importing configuration from JSON or specifying default values for
the whole configuration (multiple sections) is now a single line of code. Same
goes for copying data from another ``ConfigParser`` instance, thanks to its
mapping protocol support.
mapping protocol support.
* many smaller tweaks, updates and fixes
......@@ -104,7 +106,7 @@ gives you the certainty that what's stored in a configuration object is text.
Once your configuration is read, the rest of your application doesn't have to
deal with encoding issues. All you have is text [2]_. The only two phases when
you should explicitly state encoding is when you either read from an external
source (e.g. a file) or write back.
source (e.g. a file) or write back.
Versioning
----------
......@@ -113,17 +115,19 @@ This backport is intended to keep 100% compatibility with the vanilla release in
Python 3.2+. To help maintaining a version you want and expect, a versioning
scheme is used where:
* the first three numbers indicate the version of Python 3.x from which the
* the first two numbers indicate the version of Python 3 from which the
backport is done
* a backport release number is provided after the ``r`` letter
* a backport release number is provided as the final number (zero-indexed)
For example, ``3.3.0r1`` is the **first** release of ``configparser`` compatible
with the library found in Python **3.3.0**.
For example, ``3.5.2`` is the **third** backport release of the
``configparser`` library as seen in Python 3.5. Note that ``3.5.2`` does
**NOT** necessarily mean this backport version is based on the standard library
of Python 3.5.2.
A single exception from the 100% compatibility principle is that bugs fixed
before releasing another minor Python 3.x.y version **will be included** in the
backport releases done in the mean time. This rule applies to bugs only.
One exception from the 100% compatibility principle is that bugs fixed before
releasing another minor Python 3 bugfix version **will be included** in the
backport releases done in the mean time.
Maintenance
-----------
......@@ -133,11 +137,47 @@ This backport is maintained on BitBucket by Łukasz Langa, the current vanilla
* `configparser Mercurial repository <https://bitbucket.org/ambv/configparser>`_
* `configparser issue tracker <https://bitbucket.org/ambv/configparser/issues>`_
* `configparser issue tracker <https://bitbucket.org/ambv/configparser/issues>`_
Change Log
----------
3.5.0
~~~~~
* a complete rewrite of the backport; now single codebase working on Python
2.6 - 3.5. To use on Python 3 import ``from backports import configparser``
instead of the built-in version.
* compatible with 3.5.1
* fixes `BitBucket issue #1
<https://bitbucket.org/ambv/configparser/issue/1>`_: versioning non-compliant
with PEP 386
* fixes `BitBucket issue #3
<https://bitbucket.org/ambv/configparser/issue/3>`_: ``reload(sys);
sys.setdefaultencoding('utf8')`` in setup.py
* fixes `BitBucket issue #5
<https://bitbucket.org/ambv/configparser/issue/5>`_: Installing the backport
on Python 3 breaks virtualenv
* fixes `BitBucket issue #6
<https://bitbucket.org/ambv/configparser/issue/6>`_: PyPy compatibility
3.5.0b2
~~~~~~~
* second beta of 3.5.0, not using any third-party futurization libraries
3.5.0b1
~~~~~~~
* first beta of 3.5.0, using python-future
* for the full feature list, see `3.5.0`_
3.3.0r2
~~~~~~~
......@@ -200,53 +240,40 @@ This section is technical and should bother you only if you are wondering how
this backport is produced. If the implementation details of this backport are
not important for you, feel free to ignore the following content.
``configparser`` is converted using `3to2 <http://pypi.python.org/pypi/3to2>`_.
Because a fully automatic conversion was not doable, I took the following
branching approach:
``configparser`` is converted using `python-future
<http://python-future.org>`_ and free time. Because a fully automatic
conversion was not doable, I took the following branching approach:
* the ``3.x`` branch holds unchanged files synchronized from the upstream
CPython repository. The synchronization is currently done by manually copying
the required files and stating from which CPython changeset they come from.
* the ``3.x-clean`` branch holds a version of the ``3.x`` code with some tweaks
* the ``default`` branch holds a version of the ``3.x`` code with some tweaks
that make it independent from libraries and constructions unavailable on 2.x.
Code on this branch still *must* work on the corresponding Python 3.x. You
can check this running the supplied unit tests.
* the ``default`` branch holds necessary changes which break unit tests on
Python 3.2. Additional files which are used by the backport are also stored
here.
Code on this branch still *must* work on the corresponding Python 3.x but
will also work on Python 2.6 and 2.7 (including PyPy). You can check this
running the supplied unit tests with ``tox``.
The process works like this:
1. I update the ``3.x`` branch with new versions of files. Commit.
2. I merge the new commit to ``3.x-clean``. Check unit tests. Commit.
3. If there are necessary changes that can be made in a 3.x compatible manner,
I do them now (still on ``3.x-clean``), check unit tests and commit. If I'm
not yet aware of any, no problem.
4. I merge the changes from ``3.x-clean`` to ``default``. Commit.
1. I update the ``3.x`` branch with new versions of files. Note that the
actual ``configparser.py`` file is now just a proxy for sources held in
``backports/configparser/__init__.py``.
5. If there are necessary changes that *cannot* be made in a 3.x compatible
manner, I do them now (on ``default``). Note that the changes should still
be written using 3.x syntax. If I'm not yet aware of any required changes,
no problem.
2. I check for new names in ``__all__`` and update imports in
``configparser.py`` accordingly. I run the tests on Python 3. Commit.
6. I run ``./convert.py`` which is a custom ``3to2`` runner for this project.
3. I merge the new commit to ``default``. I run ``tox``. Commit.
7. I run the unit tests with ``unittest2`` on Python 2.x. If the tests are OK,
I can prepare a new release. Otherwise, I revert the ``default`` branch to
its previous state (``hg revert .``) and go back to Step 3.
4. If there are necessary changes, I do them now (on ``default``). Note that
the changes should be written in the syntax subset supported by Python
2.6.
**NOTE:** the ``default`` branch holds unconverted code. This is because keeping
the conversion step as the last (after any custom changes) helps managing the
history better. Plus, the merges are nicer and updates of the converter software
don't create nasty conflicts in the repository.
5. I run ``tox``. If it works, I update the docs and release the new version.
Otherwise, I go back to point 3. I might use ``pasteurize`` to suggest me
required changes but usually I do them manually to keep resulting code in
a nicer form.
This process works well but if you have any tips on how to make it simpler and
faster, do enlighten me :)
Footnotes
---------
......
MANIFEST.in
README.rst
configparser.py
configparser.rst
configparser_helpers.py
setup.py
configparser.egg-info/PKG-INFO
configparser.egg-info/SOURCES.txt
configparser.egg-info/dependency_links.txt
configparser.egg-info/requires.txt
configparser.egg-info/top_level.txt
configparser.egg-info/zip-safe
\ No newline at end of file
ordereddict
\ No newline at end of file
configparser_helpers
configparser
......@@ -11,6 +11,8 @@
.. sectionauthor:: Christopher G. Petrilli <petrilli@amber.org>
.. sectionauthor:: Łukasz Langa <lukasz@langa.pl>
**Source code:** :source:`Lib/configparser.py`
.. index::
pair: .ini; file
pair: configuration; file
......@@ -371,7 +373,8 @@ are changed on a section proxy, they are actually mutated in the original
parser.
:mod:`configparser` objects behave as close to actual dictionaries as possible.
The mapping interface is complete and adheres to the ``MutableMapping`` ABC.
The mapping interface is complete and adheres to the
:class:`~collections.abc.MutableMapping` ABC.
However, there are a few differences that should be taken into account:
* By default, all keys in sections are accessible in a case-insensitive manner
......@@ -385,11 +388,17 @@ However, there are a few differences that should be taken into account:
* All sections include ``DEFAULTSECT`` values as well which means that
``.clear()`` on a section may not leave the section visibly empty. This is
because default values cannot be deleted from the section (because technically
they are not there). If they are overriden in the section, deleting causes
they are not there). If they are overridden in the section, deleting causes
the default value to be visible again. Trying to delete a default value
causes a ``KeyError``.
* Trying to delete the ``DEFAULTSECT`` raises ``ValueError``.
* ``DEFAULTSECT`` cannot be removed from the parser:
* trying to delete it raises ``ValueError``,
* ``parser.clear()`` leaves it intact,
* ``parser.popitem()`` never returns it.
* ``parser.get(section, option, **kwargs)`` - the second argument is **not**
a fallback value. Note however that the section-level ``get()`` methods are
......@@ -533,7 +542,7 @@ the :meth:`__init__` options:
* *delimiters*, default value: ``('=', ':')``
Delimiters are substrings that delimit keys from values within a section. The
first occurence of a delimiting substring on a line is considered a delimiter.
first occurrence of a delimiting substring on a line is considered a delimiter.
This means values (but not keys) can contain the delimiters.
See also the *space_around_delimiters* argument to
......@@ -660,7 +669,7 @@ the :meth:`__init__` options:
More advanced customization may be achieved by overriding default values of
these parser attributes. The defaults are defined on the classes, so they
may be overriden by subclasses or by attribute assignment.
may be overridden by subclasses or by attribute assignment.
.. attribute:: BOOLEAN_STATES
......@@ -770,9 +779,9 @@ An example of writing to a configuration file::
# values using the mapping protocol or ConfigParser's set() does not allow
# such assignments to take place.
config.add_section('Section1')
config.set('Section1', 'int', '15')
config.set('Section1', 'bool', 'true')
config.set('Section1', 'float', '3.1415')
config.set('Section1', 'an_int', '15')
config.set('Section1', 'a_bool', 'true')
config.set('Section1', 'a_float', '3.1415')
config.set('Section1', 'baz', 'fun')
config.set('Section1', 'bar', 'Python')
config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
......@@ -790,13 +799,13 @@ An example of reading the configuration file again::
# getfloat() raises an exception if the value is not a float
# getint() and getboolean() also do this for their respective types
float = config.getfloat('Section1', 'float')
int = config.getint('Section1', 'int')
print(float + int)
a_float = config.getfloat('Section1', 'a_float')
an_int = config.getint('Section1', 'an_int')
print(a_float + an_int)
# Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
# This is because we are using a RawConfigParser().
if config.getboolean('Section1', 'bool'):
if config.getboolean('Section1', 'a_bool'):
print(config.get('Section1', 'foo'))
To get interpolation, use :class:`ConfigParser`::
......@@ -806,17 +815,17 @@ To get interpolation, use :class:`ConfigParser`::
cfg = configparser.ConfigParser()
cfg.read('example.cfg')
# Set the optional `raw` argument of get() to True if you wish to disable
# Set the optional *raw* argument of get() to True if you wish to disable
# interpolation in a single get operation.
print(cfg.get('Section1', 'foo', raw=False)) # -> "Python is fun!"
print(cfg.get('Section1', 'foo', raw=True)) # -> "%(bar)s is %(baz)s!"
# The optional `vars` argument is a dict with members that will take
# The optional *vars* argument is a dict with members that will take
# precedence in interpolation.
print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
'baz': 'evil'}))
# The optional `fallback` argument can be used to provide a fallback value
# The optional *fallback* argument can be used to provide a fallback value
print(cfg.get('Section1', 'foo'))
# -> "Python is fun!"
......@@ -865,10 +874,6 @@ ConfigParser Objects
Comments can be indented. When *inline_comment_prefixes* is given, it will be
used as the set of substrings that prefix comments in non-empty lines.
line and inline comments. For backwards compatibility, the default value for
*comment_prefixes* is a special value that indicates that ``;`` and ``#`` can
start whole line comments while only ``;`` can start inline comments.
When *strict* is ``True`` (the default), the parser won't allow for
any section or option duplicates while reading from a single source (file,
string or dictionary), raising :exc:`DuplicateSectionError` or
......@@ -1011,7 +1016,7 @@ ConfigParser Objects
.. versionadded:: 3.2
.. method:: get(section, option, raw=False, [vars, fallback])
.. method:: get(section, option, *, raw=False, vars=None[, fallback])
Get an *option* value for the named *section*. If *vars* is provided, it
must be a dictionary. The *option* is looked up in *vars* (if provided),
......@@ -1029,21 +1034,21 @@ ConfigParser Objects
(especially when using the mapping protocol).
.. method:: getint(section, option, raw=False, [vars, fallback])
.. method:: getint(section, option, *, raw=False, vars=None[, fallback])
A convenience method which coerces the *option* in the specified *section*
to an integer. See :meth:`get` for explanation of *raw*, *vars* and
*fallback*.
.. method:: getfloat(section, option, raw=False, [vars, fallback])
.. method:: getfloat(section, option, *, raw=False, vars=None[, fallback])
A convenience method which coerces the *option* in the specified *section*
to a floating point number. See :meth:`get` for explanation of *raw*,
*vars* and *fallback*.
.. method:: getboolean(section, option, raw=False, [vars, fallback])
.. method:: getboolean(section, option, *, raw=False, vars=None[, fallback])
A convenience method which coerces the *option* in the specified *section*
to a Boolean value. Note that the accepted values for the option are
......@@ -1055,7 +1060,8 @@ ConfigParser Objects
*fallback*.
.. method:: items([section], raw=False, vars=None)
.. method:: items(raw=False, vars=None)
items(section, raw=False, vars=None)
When *section* is not given, return a list of *section_name*,
*section_proxy* pairs, including DEFAULTSECT.
......@@ -1064,6 +1070,10 @@ ConfigParser Objects
given *section*. Optional arguments have the same meaning as for the
:meth:`get` method.
.. versionchanged:: 3.2
Items present in *vars* no longer appear in the result. The previous
behaviour mixed actual parser options with variables provided for
interpolation.
.. method:: set(section, option, value)
......@@ -1149,7 +1159,13 @@ ConfigParser Objects
RawConfigParser Objects
-----------------------
.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configaparser.DEFAULTSECT, interpolation=None)
.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, \
allow_no_value=False, *, delimiters=('=', ':'), \
comment_prefixes=('#', ';'), \
inline_comment_prefixes=None, strict=True, \
empty_lines_in_values=True, \
default_section=configparser.DEFAULTSECT[, \
interpolation])
Legacy variant of the :class:`ConfigParser` with interpolation disabled
by default and unsafe ``add_section`` and ``set`` methods.
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""This library brings the updated configparser from Python 3.2+ to Python 2.6-2.7."""
"""This library brings the updated configparser from Python 3.5 to Python 2.6-3.5."""
from __future__ import absolute_import
from __future__ import division
from __future__ import with_statement
from __future__ import print_function
import codecs
import os
import sys
from setuptools import setup, find_packages
reload(sys)
sys.setdefaultencoding('utf8')
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as ld_file:
readme_filename = os.path.join(os.path.dirname(__file__), 'README.rst')
with codecs.open(readme_filename, encoding='utf8') as ld_file:
long_description = ld_file.read()
requirements = []
if sys.version_info[:2] < (2, 7):
requirements.append('ordereddict')
setup (
name = 'configparser',
version = '3.3.0r2',
author = u'Łukasz Langa',
author_email = 'lukasz@langa.pl',
description = __doc__,
long_description = long_description,
url = 'http://docs.python.org/3/library/configparser.html',
keywords = 'configparser ini parsing conf cfg configuration file',
platforms = ['any'],
license = 'MIT',
py_modules = ('configparser', 'configparser_helpers'),
zip_safe = True,
install_requires = requirements,
classifiers = [
if sys.version_info[0] == 2:
# bail on UTF-8 and enable `import configparser` for Python 2
author = 'Lukasz Langa'
modules = ['configparser']
if sys.version_info[1] < 7:
requirements.append('ordereddict')
else:
author = 'Łukasz Langa'
modules = []
setup(
name='configparser',
version='3.5.0',
author=author,
author_email='lukasz@langa.pl',
description=__doc__,
long_description=long_description,
url='http://docs.python.org/3/library/configparser.html',
keywords='configparser ini parsing conf cfg configuration file',
platforms=['any'],
license='MIT',
py_modules=modules,
package_dir={'': 'src'},
packages=find_packages('src'),
namespace_packages=['backports'],
include_package_data=True,
zip_safe=False,
install_requires=requirements,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
......@@ -45,7 +56,10 @@ setup (
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
]
],
)
# A Python "namespace package" http://www.python.org/dev/peps/pep-0382/
# This always goes inside of a namespace package's __init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
pass
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from collections import MutableMapping
try:
from collections import UserDict
except ImportError:
from UserDict import UserDict
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from io import open
import sys
try:
from thread import get_ident
except ImportError:
......@@ -10,9 +27,23 @@ except ImportError:
except ImportError:
from _dummy_thread import get_ident
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
str = type('str')
def from_none(exc):
"""raise from_none(ValueError('a')) == raise ValueError('a') from None"""
exc.__cause__ = None
exc.__suppress_context__ = True
return exc
# from reprlib 3.2.1
def recursive_repr(fillvalue=u'...'):
u'Decorator to make a repr function return fillvalue for a recursive call'
def recursive_repr(fillvalue='...'):
'Decorator to make a repr function return fillvalue for a recursive call'
def decorating_function(user_function):
repr_running = set()
......@@ -29,17 +60,17 @@ def recursive_repr(fillvalue=u'...'):
return result
# Can't use functools.wraps() here because of bootstrap issues
wrapper.__module__ = getattr(user_function, u'__module__')
wrapper.__doc__ = getattr(user_function, u'__doc__')
wrapper.__name__ = getattr(user_function, u'__name__')
wrapper.__annotations__ = getattr(user_function, u'__annotations__', {})
wrapper.__module__ = getattr(user_function, '__module__')
wrapper.__doc__ = getattr(user_function, '__doc__')
wrapper.__name__ = getattr(user_function, '__name__')
wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
return wrapper
return decorating_function
# from collections 3.2.1
class _ChainMap(MutableMapping):
u''' A ChainMap groups multiple dicts (or other mappings) together
''' A ChainMap groups multiple dicts (or other mappings) together
to create a single, updateable view.
The underlying mappings are stored in a list. That list is public and can
......@@ -52,7 +83,7 @@ class _ChainMap(MutableMapping):
'''
def __init__(self, *maps):
u'''Initialize a ChainMap by setting *maps* to the given mappings.
'''Initialize a ChainMap by setting *maps* to the given mappings.
If no mappings are provided, a single empty dictionary is used.
'''
......@@ -83,27 +114,27 @@ class _ChainMap(MutableMapping):
@recursive_repr()
def __repr__(self):
return u'{0.__class__.__name__}({1})'.format(
self, u', '.join(map(repr, self.maps)))
return '{0.__class__.__name__}({1})'.format(
self, ', '.join(map(repr, self.maps)))
@classmethod
def fromkeys(cls, iterable, *args):
u'Create a ChainMap with a single dict created from the iterable.'
'Create a ChainMap with a single dict created from the iterable.'
return cls(dict.fromkeys(iterable, *args))
def copy(self):
u'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
return self.__class__(self.maps[0].copy(), *self.maps[1:])
__copy__ = copy
def new_child(self): # like Django's Context.push()
u'New ChainMap with a new dict followed by all previous maps.'
'New ChainMap with a new dict followed by all previous maps.'
return self.__class__({}, *self.maps)
@property
def parents(self): # like Django's Context.pop()
u'New ChainMap from maps[1:].'
'New ChainMap from maps[1:].'
return self.__class__(*self.maps[1:])
def __setitem__(self, key, value):
......@@ -113,22 +144,28 @@ class _ChainMap(MutableMapping):
try:
del self.maps[0][key]
except KeyError:
raise KeyError(u'Key not found in the first mapping: {!r}'.format(key))
raise KeyError('Key not found in the first mapping: {!r}'.format(key))
def popitem(self):
u'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
try:
return self.maps[0].popitem()
except KeyError:
raise KeyError(u'No keys found in the first mapping.')
raise KeyError('No keys found in the first mapping.')
def pop(self, key, *args):
u'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
try:
return self.maps[0].pop(key, *args)
except KeyError:
raise KeyError(u'Key not found in the first mapping: {!r}'.format(key))
raise KeyError('Key not found in the first mapping: {!r}'.format(key))
def clear(self):
u'Clear maps[0], leaving maps[1:] intact.'
'Clear maps[0], leaving maps[1:] intact.'
self.maps[0].clear()
try:
from collections import ChainMap
except ImportError:
ChainMap = _ChainMap
MANIFEST.in
README.rst
configparser.rst
setup.py
src/configparser.py
src/backports/__init__.py
src/backports/configparser/__init__.py
src/backports/configparser/helpers.py
src/configparser.egg-info/PKG-INFO
src/configparser.egg-info/SOURCES.txt
src/configparser.egg-info/dependency_links.txt
src/configparser.egg-info/namespace_packages.txt
src/configparser.egg-info/not-zip-safe
src/configparser.egg-info/top_level.txt
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Convenience module importing everything from backports.configparser."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from backports.configparser import (
RawConfigParser,
ConfigParser,
SafeConfigParser,
SectionProxy,
Interpolation,
BasicInterpolation,
ExtendedInterpolation,
LegacyInterpolation,
Error,
NoSectionError,
DuplicateSectionError,
DuplicateOptionError,
NoOptionError,
InterpolationError,
InterpolationMissingOptionError,
InterpolationSyntaxError,
InterpolationDepthError,
ParsingError,
MissingSectionHeaderError,
ConverterMapping,
_UNSET,
DEFAULTSECT,
MAX_INTERPOLATION_DEPTH,
_default_dict,
_ChainMap,
)
__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
"NoOptionError", "InterpolationError", "InterpolationDepthError",
"InterpolationMissingOptionError", "InterpolationSyntaxError",
"ParsingError", "MissingSectionHeaderError",
"ConfigParser", "SafeConfigParser", "RawConfigParser",
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
# NOTE: names missing from __all__ imported anyway for backwards compatibility.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment