https://github.com/python/cpython/commit/c35c7353eb8fbccff2d3a6ab664426b31af00d4d commit: c35c7353eb8fbccff2d3a6ab664426b31af00d4d branch: main author: sobolevn <m...@sobolevn.me> committer: ambv <luk...@langa.pl> date: 2025-04-16T12:39:11+02:00 summary:
gh-130941: Fix `configparser` parsing values with `allow_no_value` and `interpolation` set (GH-130949) files: A Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst M Lib/configparser.py M Lib/test/test_configparser.py diff --git a/Lib/configparser.py b/Lib/configparser.py index 70cc651edabd86..239fda60a02ca0 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -541,6 +541,8 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, 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)), diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 1313ec2b9e884e..23904d17d326d8 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -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 index 00000000000000..4f0cda8d03e902 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst @@ -0,0 +1,2 @@ +Fix :class:`configparser.ConfigParser` parsing empty interpolation with +``allow_no_value`` set to ``True``. _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com