mirror of https://github.com/python/cpython
gh-89336: Remove configparser APIs that were deprecated for 3.12 (#92503)
https://github.com/python/cpython/issue/89336: Remove configparser 3.12 deprecations. Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
This commit is contained in:
parent
4abab6b603
commit
296e4efebb
|
@ -1206,28 +1206,6 @@ ConfigParser Objects
|
||||||
names is stripped before :meth:`optionxform` is called.
|
names is stripped before :meth:`optionxform` is called.
|
||||||
|
|
||||||
|
|
||||||
.. method:: readfp(fp, filename=None)
|
|
||||||
|
|
||||||
.. deprecated:: 3.2
|
|
||||||
Use :meth:`read_file` instead.
|
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
|
||||||
:meth:`readfp` now iterates on *fp* instead of calling ``fp.readline()``.
|
|
||||||
|
|
||||||
For existing code calling :meth:`readfp` with arguments which don't
|
|
||||||
support iteration, the following generator may be used as a wrapper
|
|
||||||
around the file-like object::
|
|
||||||
|
|
||||||
def readline_generator(fp):
|
|
||||||
line = fp.readline()
|
|
||||||
while line:
|
|
||||||
yield line
|
|
||||||
line = fp.readline()
|
|
||||||
|
|
||||||
Instead of ``parser.readfp(fp)`` use
|
|
||||||
``parser.read_file(readline_generator(fp))``.
|
|
||||||
|
|
||||||
|
|
||||||
.. data:: MAX_INTERPOLATION_DEPTH
|
.. data:: MAX_INTERPOLATION_DEPTH
|
||||||
|
|
||||||
The maximum depth for recursive interpolation for :meth:`get` when the *raw*
|
The maximum depth for recursive interpolation for :meth:`get` when the *raw*
|
||||||
|
@ -1361,10 +1339,9 @@ Exceptions
|
||||||
|
|
||||||
Exception raised when errors occur attempting to parse a file.
|
Exception raised when errors occur attempting to parse a file.
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.12
|
||||||
The ``filename`` attribute and :meth:`__init__` argument were renamed to
|
The ``filename`` attribute and :meth:`__init__` constructor argument were
|
||||||
``source`` for consistency.
|
removed. They have been available using the name ``source`` since 3.2.
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,16 @@ although there is currently no date scheduled for their removal.
|
||||||
Removed
|
Removed
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
* Several names deprecated in the :mod:`configparser` way back in 3.2 have
|
||||||
|
been removed per :gh:`89336`:
|
||||||
|
|
||||||
|
* :class:`configparser.ParsingError` no longer has a ``filename`` attribute
|
||||||
|
or argument. Use the ``source`` attribute and argument instead.
|
||||||
|
* :mod:`configparser` no longer has a ``SafeConfigParser`` class. Use the
|
||||||
|
shorter :class:`~configparser.ConfigParser` name instead.
|
||||||
|
* :class:`configparser.ConfigParser` no longer has a ``readfp`` method.
|
||||||
|
Use :meth:`~configparser.ConfigParser.read_file` instead.
|
||||||
|
|
||||||
* The following undocumented :mod:`sqlite3` features, deprecated in Python
|
* The following undocumented :mod:`sqlite3` features, deprecated in Python
|
||||||
3.10, are now removed:
|
3.10, are now removed:
|
||||||
|
|
||||||
|
|
|
@ -148,14 +148,14 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
|
__all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
|
||||||
"NoOptionError", "InterpolationError", "InterpolationDepthError",
|
"NoOptionError", "InterpolationError", "InterpolationDepthError",
|
||||||
"InterpolationMissingOptionError", "InterpolationSyntaxError",
|
"InterpolationMissingOptionError", "InterpolationSyntaxError",
|
||||||
"ParsingError", "MissingSectionHeaderError",
|
"ParsingError", "MissingSectionHeaderError",
|
||||||
"ConfigParser", "SafeConfigParser", "RawConfigParser",
|
"ConfigParser", "RawConfigParser",
|
||||||
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
|
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
|
||||||
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
|
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
|
||||||
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
|
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH")
|
||||||
|
|
||||||
_default_dict = dict
|
_default_dict = dict
|
||||||
DEFAULTSECT = "DEFAULT"
|
DEFAULTSECT = "DEFAULT"
|
||||||
|
@ -297,41 +297,12 @@ class InterpolationDepthError(InterpolationError):
|
||||||
class ParsingError(Error):
|
class ParsingError(Error):
|
||||||
"""Raised when a configuration file does not follow legal syntax."""
|
"""Raised when a configuration file does not follow legal syntax."""
|
||||||
|
|
||||||
def __init__(self, source=None, filename=None):
|
def __init__(self, source):
|
||||||
# Exactly one of `source'/`filename' arguments has to be given.
|
super().__init__(f'Source contains parsing errors: {source!r}')
|
||||||
# `filename' kept for compatibility.
|
|
||||||
if filename and source:
|
|
||||||
raise ValueError("Cannot specify both `filename' and `source'. "
|
|
||||||
"Use `source'.")
|
|
||||||
elif not filename and not source:
|
|
||||||
raise ValueError("Required argument `source' not given.")
|
|
||||||
elif filename:
|
|
||||||
source = filename
|
|
||||||
Error.__init__(self, 'Source contains parsing errors: %r' % source)
|
|
||||||
self.source = source
|
self.source = source
|
||||||
self.errors = []
|
self.errors = []
|
||||||
self.args = (source, )
|
self.args = (source, )
|
||||||
|
|
||||||
@property
|
|
||||||
def filename(self):
|
|
||||||
"""Deprecated, use `source'."""
|
|
||||||
warnings.warn(
|
|
||||||
"The 'filename' attribute will be removed in Python 3.12. "
|
|
||||||
"Use 'source' instead.",
|
|
||||||
DeprecationWarning, stacklevel=2
|
|
||||||
)
|
|
||||||
return self.source
|
|
||||||
|
|
||||||
@filename.setter
|
|
||||||
def filename(self, value):
|
|
||||||
"""Deprecated, user `source'."""
|
|
||||||
warnings.warn(
|
|
||||||
"The 'filename' attribute will be removed in Python 3.12. "
|
|
||||||
"Use 'source' instead.",
|
|
||||||
DeprecationWarning, stacklevel=2
|
|
||||||
)
|
|
||||||
self.source = value
|
|
||||||
|
|
||||||
def append(self, lineno, line):
|
def append(self, lineno, line):
|
||||||
self.errors.append((lineno, line))
|
self.errors.append((lineno, line))
|
||||||
self.message += '\n\t[line %2d]: %s' % (lineno, line)
|
self.message += '\n\t[line %2d]: %s' % (lineno, line)
|
||||||
|
@ -768,15 +739,6 @@ class RawConfigParser(MutableMapping):
|
||||||
elements_added.add((section, key))
|
elements_added.add((section, key))
|
||||||
self.set(section, key, value)
|
self.set(section, key, value)
|
||||||
|
|
||||||
def readfp(self, fp, filename=None):
|
|
||||||
"""Deprecated, use read_file instead."""
|
|
||||||
warnings.warn(
|
|
||||||
"This method will be removed in Python 3.12. "
|
|
||||||
"Use 'parser.read_file()' instead.",
|
|
||||||
DeprecationWarning, stacklevel=2
|
|
||||||
)
|
|
||||||
self.read_file(fp, source=filename)
|
|
||||||
|
|
||||||
def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET):
|
def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET):
|
||||||
"""Get an option value for a given section.
|
"""Get an option value for a given section.
|
||||||
|
|
||||||
|
@ -1239,19 +1201,6 @@ class ConfigParser(RawConfigParser):
|
||||||
self._interpolation = hold_interpolation
|
self._interpolation = hold_interpolation
|
||||||
|
|
||||||
|
|
||||||
class SafeConfigParser(ConfigParser):
|
|
||||||
"""ConfigParser alias for backwards compatibility purposes."""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
warnings.warn(
|
|
||||||
"The SafeConfigParser class has been renamed to ConfigParser "
|
|
||||||
"in Python 3.2. This alias will be removed in Python 3.12."
|
|
||||||
" Use ConfigParser directly instead.",
|
|
||||||
DeprecationWarning, stacklevel=2
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SectionProxy(MutableMapping):
|
class SectionProxy(MutableMapping):
|
||||||
"""A proxy for a single section from a parser."""
|
"""A proxy for a single section from a parser."""
|
||||||
|
|
||||||
|
|
|
@ -1612,23 +1612,12 @@ class CoverageOneHundredTestCase(unittest.TestCase):
|
||||||
self.assertEqual(error.section, 'section')
|
self.assertEqual(error.section, 'section')
|
||||||
|
|
||||||
def test_parsing_error(self):
|
def test_parsing_error(self):
|
||||||
with self.assertRaises(ValueError) as cm:
|
with self.assertRaises(TypeError) as cm:
|
||||||
configparser.ParsingError()
|
configparser.ParsingError()
|
||||||
self.assertEqual(str(cm.exception), "Required argument `source' not "
|
error = configparser.ParsingError(source='source')
|
||||||
"given.")
|
self.assertEqual(error.source, 'source')
|
||||||
with self.assertRaises(ValueError) as cm:
|
error = configparser.ParsingError('source')
|
||||||
configparser.ParsingError(source='source', filename='filename')
|
|
||||||
self.assertEqual(str(cm.exception), "Cannot specify both `filename' "
|
|
||||||
"and `source'. Use `source'.")
|
|
||||||
error = configparser.ParsingError(filename='source')
|
|
||||||
self.assertEqual(error.source, 'source')
|
self.assertEqual(error.source, 'source')
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always", DeprecationWarning)
|
|
||||||
self.assertEqual(error.filename, 'source')
|
|
||||||
error.filename = 'filename'
|
|
||||||
self.assertEqual(error.source, 'filename')
|
|
||||||
for warning in w:
|
|
||||||
self.assertTrue(warning.category is DeprecationWarning)
|
|
||||||
|
|
||||||
def test_interpolation_validation(self):
|
def test_interpolation_validation(self):
|
||||||
parser = configparser.ConfigParser()
|
parser = configparser.ConfigParser()
|
||||||
|
@ -1647,27 +1636,6 @@ class CoverageOneHundredTestCase(unittest.TestCase):
|
||||||
self.assertEqual(str(cm.exception), "bad interpolation variable "
|
self.assertEqual(str(cm.exception), "bad interpolation variable "
|
||||||
"reference '%(()'")
|
"reference '%(()'")
|
||||||
|
|
||||||
def test_readfp_deprecation(self):
|
|
||||||
sio = io.StringIO("""
|
|
||||||
[section]
|
|
||||||
option = value
|
|
||||||
""")
|
|
||||||
parser = configparser.ConfigParser()
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always", DeprecationWarning)
|
|
||||||
parser.readfp(sio, filename='StringIO')
|
|
||||||
for warning in w:
|
|
||||||
self.assertTrue(warning.category is DeprecationWarning)
|
|
||||||
self.assertEqual(len(parser), 2)
|
|
||||||
self.assertEqual(parser['section']['option'], 'value')
|
|
||||||
|
|
||||||
def test_safeconfigparser_deprecation(self):
|
|
||||||
with warnings.catch_warnings(record=True) as w:
|
|
||||||
warnings.simplefilter("always", DeprecationWarning)
|
|
||||||
parser = configparser.SafeConfigParser()
|
|
||||||
for warning in w:
|
|
||||||
self.assertTrue(warning.category is DeprecationWarning)
|
|
||||||
|
|
||||||
def test_legacyinterpolation_deprecation(self):
|
def test_legacyinterpolation_deprecation(self):
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
warnings.simplefilter("always", DeprecationWarning)
|
warnings.simplefilter("always", DeprecationWarning)
|
||||||
|
@ -1841,7 +1809,7 @@ class ExceptionPicklingTestCase(unittest.TestCase):
|
||||||
self.assertEqual(e1.source, e2.source)
|
self.assertEqual(e1.source, e2.source)
|
||||||
self.assertEqual(e1.errors, e2.errors)
|
self.assertEqual(e1.errors, e2.errors)
|
||||||
self.assertEqual(repr(e1), repr(e2))
|
self.assertEqual(repr(e1), repr(e2))
|
||||||
e1 = configparser.ParsingError(filename='filename')
|
e1 = configparser.ParsingError('filename')
|
||||||
e1.append(1, 'line1')
|
e1.append(1, 'line1')
|
||||||
e1.append(2, 'line2')
|
e1.append(2, 'line2')
|
||||||
e1.append(3, 'line3')
|
e1.append(3, 'line3')
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Removed :mod:`configparser` module APIs:
|
||||||
|
the ``SafeConfigParser`` class alias, the ``ParsingError.filename``
|
||||||
|
property and parameter, and the ``ConfigParser.readfp`` method, all
|
||||||
|
of which were deprecated since Python 3.2.
|
Loading…
Reference in New Issue