mirror of https://github.com/python/cpython
gh-104886: Remove deprecated configparser.LegacyInterpolation (#104887)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
0242e9a57a
commit
3f9c60f51e
|
@ -118,6 +118,11 @@ Removed
|
|||
* Remove support for using :class:`pathlib.Path` objects as context managers.
|
||||
This functionality was deprecated and made a no-op in Python 3.9.
|
||||
|
||||
* Remove the undocumented :class:`!configparser.LegacyInterpolation` class,
|
||||
deprecated in the docstring since Python 3.2,
|
||||
and with a deprecation warning since Python 3.11.
|
||||
(Contributed by Hugo van Kemenade in :gh:`104886`.)
|
||||
|
||||
* Remove the :meth:`!turtle.RawTurtle.settiltangle` method,
|
||||
deprecated in docs since Python 3.1
|
||||
and with a deprecation warning since Python 3.11.
|
||||
|
@ -135,6 +140,8 @@ Removed
|
|||
* :meth:`unittest.TestLoader.loadTestsFromTestCase`
|
||||
* :meth:`unittest.TestLoader.getTestCaseNames`
|
||||
|
||||
(Contributed by Hugo van Kemenade in :gh:`104835`.)
|
||||
|
||||
* :pep:`594`: Remove the :mod:`!cgi`` and :mod:`!cgitb` modules,
|
||||
deprecated in Python 3.11.
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ __all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
|
|||
"ParsingError", "MissingSectionHeaderError",
|
||||
"ConfigParser", "RawConfigParser",
|
||||
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
|
||||
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
|
||||
"SectionProxy", "ConverterMapping",
|
||||
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH")
|
||||
|
||||
_default_dict = dict
|
||||
|
@ -491,53 +491,6 @@ class ExtendedInterpolation(Interpolation):
|
|||
"found: %r" % (rest,))
|
||||
|
||||
|
||||
class LegacyInterpolation(Interpolation):
|
||||
"""Deprecated interpolation used in old versions of ConfigParser.
|
||||
Use BasicInterpolation or ExtendedInterpolation instead."""
|
||||
|
||||
_KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
warnings.warn(
|
||||
"LegacyInterpolation has been deprecated since Python 3.2 "
|
||||
"and will be removed from the configparser module in Python 3.13. "
|
||||
"Use BasicInterpolation or ExtendedInterpolation instead.",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
|
||||
def before_get(self, parser, section, option, value, vars):
|
||||
rawval = value
|
||||
depth = MAX_INTERPOLATION_DEPTH
|
||||
while depth: # Loop through this until it's done
|
||||
depth -= 1
|
||||
if value and "%(" in value:
|
||||
replace = functools.partial(self._interpolation_replace,
|
||||
parser=parser)
|
||||
value = self._KEYCRE.sub(replace, value)
|
||||
try:
|
||||
value = value % vars
|
||||
except KeyError as e:
|
||||
raise InterpolationMissingOptionError(
|
||||
option, section, rawval, e.args[0]) from None
|
||||
else:
|
||||
break
|
||||
if value and "%(" in value:
|
||||
raise InterpolationDepthError(option, section, rawval)
|
||||
return value
|
||||
|
||||
def before_set(self, parser, section, option, value):
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def _interpolation_replace(match, parser):
|
||||
s = match.group(1)
|
||||
if s is None:
|
||||
return match.group()
|
||||
else:
|
||||
return "%%(%s)s" % parser.optionxform(s)
|
||||
|
||||
|
||||
class RawConfigParser(MutableMapping):
|
||||
"""ConfigParser that does not do interpolation."""
|
||||
|
||||
|
|
|
@ -907,9 +907,6 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase):
|
|||
if self.interpolation == configparser._UNSET:
|
||||
self.assertEqual(e.args, ("bar11", "Foo",
|
||||
"something %(with11)s lots of interpolation (11 steps)"))
|
||||
elif isinstance(self.interpolation, configparser.LegacyInterpolation):
|
||||
self.assertEqual(e.args, ("bar11", "Foo",
|
||||
"something %(with11)s lots of interpolation (11 steps)"))
|
||||
|
||||
def test_interpolation_missing_value(self):
|
||||
cf = self.get_interpolation_config()
|
||||
|
@ -921,9 +918,6 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase):
|
|||
if self.interpolation == configparser._UNSET:
|
||||
self.assertEqual(e.args, ('name', 'Interpolation Error',
|
||||
'%(reference)s', 'reference'))
|
||||
elif isinstance(self.interpolation, configparser.LegacyInterpolation):
|
||||
self.assertEqual(e.args, ('name', 'Interpolation Error',
|
||||
'%(reference)s', 'reference'))
|
||||
|
||||
def test_items(self):
|
||||
self.check_items_config([('default', '<default>'),
|
||||
|
@ -942,9 +936,6 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase):
|
|||
self.assertEqual(cf.get("section", "ok"), "xxx/%s")
|
||||
if self.interpolation == configparser._UNSET:
|
||||
self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
|
||||
elif isinstance(self.interpolation, configparser.LegacyInterpolation):
|
||||
with self.assertRaises(TypeError):
|
||||
cf.get("section", "not_ok")
|
||||
|
||||
def test_set_malformatted_interpolation(self):
|
||||
cf = self.fromstring("[sect]\n"
|
||||
|
@ -1025,31 +1016,6 @@ class ConfigParserTestCaseNoInterpolation(BasicTestCase, unittest.TestCase):
|
|||
cf.read_string(self.ini)
|
||||
self.assertMatchesIni(cf)
|
||||
|
||||
|
||||
class ConfigParserTestCaseLegacyInterpolation(ConfigParserTestCase):
|
||||
config_class = configparser.ConfigParser
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
interpolation = configparser.LegacyInterpolation()
|
||||
|
||||
def test_set_malformatted_interpolation(self):
|
||||
cf = self.fromstring("[sect]\n"
|
||||
"option1{eq}foo\n".format(eq=self.delimiters[0]))
|
||||
|
||||
self.assertEqual(cf.get('sect', "option1"), "foo")
|
||||
|
||||
cf.set("sect", "option1", "%foo")
|
||||
self.assertEqual(cf.get('sect', "option1"), "%foo")
|
||||
cf.set("sect", "option1", "foo%")
|
||||
self.assertEqual(cf.get('sect', "option1"), "foo%")
|
||||
cf.set("sect", "option1", "f%oo")
|
||||
self.assertEqual(cf.get('sect', "option1"), "f%oo")
|
||||
|
||||
# bug #5741: double percents are *not* malformed
|
||||
cf.set("sect", "option2", "foo%%bar")
|
||||
self.assertEqual(cf.get("sect", "option2"), "foo%%bar")
|
||||
|
||||
|
||||
class ConfigParserTestCaseInvalidInterpolationType(unittest.TestCase):
|
||||
def test_error_on_wrong_type_for_interpolation(self):
|
||||
for value in [configparser.ExtendedInterpolation, 42, "a string"]:
|
||||
|
@ -1636,14 +1602,6 @@ class CoverageOneHundredTestCase(unittest.TestCase):
|
|||
self.assertEqual(str(cm.exception), "bad interpolation variable "
|
||||
"reference '%(()'")
|
||||
|
||||
def test_legacyinterpolation_deprecation(self):
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always", DeprecationWarning)
|
||||
configparser.LegacyInterpolation()
|
||||
self.assertGreaterEqual(len(w), 1)
|
||||
for warning in w:
|
||||
self.assertIs(warning.category, DeprecationWarning)
|
||||
|
||||
def test_sectionproxy_repr(self):
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string("""
|
||||
|
|
|
@ -989,7 +989,7 @@ references in :ref:`PEP 585 generic aliases <types-genericalias>`.
|
|||
.. nonce: xnhT4a
|
||||
.. section: Library
|
||||
|
||||
Add :exc:`DeprecationWarning` to :class:`LegacyInterpolation`, deprecated in
|
||||
Add :exc:`DeprecationWarning` to :class:`!LegacyInterpolation`, deprecated in
|
||||
the docstring since Python 3.2. Will be removed in Python 3.13. Use
|
||||
:class:`BasicInterpolation` or :class:`ExtendedInterpolation` instead.
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Remove the undocumented :class:`!configparser.LegacyInterpolation` class,
|
||||
deprecated in the docstring since Python 3.2, and with a deprecation warning
|
||||
since Python 3.11. Patch by Hugo van Kemenade.
|
Loading…
Reference in New Issue