]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-130941: Fix `configparser` parsing values with `allow_no_value` and `interp...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 16 Apr 2025 12:19:46 +0000 (14:19 +0200)
committerGitHub <noreply@github.com>
Wed, 16 Apr 2025 12:19:46 +0000 (14:19 +0200)
gh-130941: Fix `configparser` parsing values with `allow_no_value` and `interpolation` set (GH-130949)
(cherry picked from commit c35c7353eb8fbccff2d3a6ab664426b31af00d4d)

Co-authored-by: sobolevn <mail@sobolevn.me>
Lib/configparser.py
Lib/test/test_configparser.py
Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst [new file with mode: 0644]

index 42d0ae1c0b52fba3253e7dd9091084338bb6ce79..05b86acb919bfdc0be7e2b72c5d9acb807a95695 100644 (file)
@@ -526,6 +526,8 @@ class ExtendedInterpolation(Interpolation):
                 except (KeyError, NoSectionError, NoOptionError):
                     raise InterpolationMissingOptionError(
                         option, section, rawval, ":".join(path)) from None
+                if v is None:
+                    continue
                 if "$" in v:
                     self._interpolate_some(parser, opt, accum, v, sect,
                                            dict(parser.items(sect, raw=True)),
index ab86d7f1af39816dc6aaa49f29ea132c337016db..89f9f1247b55ea766909c572b61d9150cc22e426 100644 (file)
@@ -1328,6 +1328,47 @@ class ConfigParserTestCaseNoValue(ConfigParserTestCase):
     allow_no_value = True
 
 
+class NoValueAndExtendedInterpolation(CfgParserTestCaseClass):
+    interpolation = configparser.ExtendedInterpolation()
+    allow_no_value = True
+
+    def test_interpolation_with_allow_no_value(self):
+        config = textwrap.dedent("""
+            [dummy]
+            a
+            b = ${a}
+        """)
+        cf = self.fromstring(config)
+
+        self.assertIs(cf["dummy"]["a"], None)
+        self.assertEqual(cf["dummy"]["b"], "")
+
+    def test_explicit_none(self):
+        config = textwrap.dedent("""
+            [dummy]
+            a = None
+            b = ${a}
+        """)
+        cf = self.fromstring(config)
+
+        self.assertEqual(cf["dummy"]["a"], "None")
+        self.assertEqual(cf["dummy"]["b"], "None")
+
+
+class ConfigParserNoValueAndExtendedInterpolationTest(
+    NoValueAndExtendedInterpolation,
+    unittest.TestCase,
+):
+    config_class = configparser.ConfigParser
+
+
+class RawConfigParserNoValueAndExtendedInterpolationTest(
+    NoValueAndExtendedInterpolation,
+    unittest.TestCase,
+):
+    config_class = configparser.RawConfigParser
+
+
 class ConfigParserTestCaseTrickyFile(CfgParserTestCaseClass, unittest.TestCase):
     config_class = configparser.ConfigParser
     delimiters = {'='}
diff --git a/Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst b/Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst
new file mode 100644 (file)
index 0000000..4f0cda8
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :class:`configparser.ConfigParser` parsing empty interpolation with
+``allow_no_value`` set to ``True``.