]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-104886: Remove deprecated configparser.LegacyInterpolation (#104887)
authorHugo van Kemenade <hugovk@users.noreply.github.com>
Fri, 26 May 2023 06:06:32 +0000 (09:06 +0300)
committerGitHub <noreply@github.com>
Fri, 26 May 2023 06:06:32 +0000 (06:06 +0000)
Co-authored-by: Victor Stinner <vstinner@python.org>
Doc/whatsnew/3.13.rst
Lib/configparser.py
Lib/test/test_configparser.py
Misc/NEWS.d/3.11.0a7.rst
Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst [new file with mode: 0644]

index 29ad0febb8b4328d63c4922eee12af64cf17abe6..0e78a080c4304b6e4363922254b66477ab6b3af0 100644 (file)
@@ -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.
 
index dee5a0db7e7ddc552b6b8ebf22187bf8cb77ebd2..9640f71adc771810ffb5455234c7400650dccdb2 100644 (file)
@@ -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."""
 
index da17c00063c56db5078b25ac7365bb149240dc5c..eef439412528d3dae5d1b43d17dc79084dd4779c 100644 (file)
@@ -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("""
index 8e7ccd4d6771ee891cbefc78c998e72d8c98b570..5e9aadf63956596322c2b61c7a286ae9d3574e0b 100644 (file)
@@ -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.
 
diff --git a/Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst b/Misc/NEWS.d/next/Library/2023-05-24-21-30-40.gh-issue-104886.8TuV-_.rst
new file mode 100644 (file)
index 0000000..2f6796b
--- /dev/null
@@ -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.