From 7f85aeab6419cff32d2eed5ae488354ec747d3c2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 7 Mar 2025 17:48:11 +0300 Subject: [PATCH 1/2] gh-130941: Fix `configparser` parsing values with `allow_no_value` and `interpolation` --- Lib/configparser.py | 2 ++ Lib/test/test_configparser.py | 16 ++++++++++++++++ ...025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst | 2 ++ 3 files changed, 20 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-03-07-17-47-32.gh-issue-130941.7_GvhW.rst diff --git a/Lib/configparser.py b/Lib/configparser.py index 70cc651edabd86..6bc920661a2203 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 not v: + 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..468da9bd749434 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1328,6 +1328,22 @@ class ConfigParserTestCaseNoValue(ConfigParserTestCase): allow_no_value = True +class ConfigParserTestCaseNoValueAndInterpolation(ConfigParserTestCase): + allow_no_value = True + interpolation = configparser.ExtendedInterpolation() + + 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"], "") + + 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``. From 1621a0f0e8bbe4b38229ee502b4e863266a5adf2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 7 Mar 2025 18:08:40 +0300 Subject: [PATCH 2/2] Fix CI --- Lib/configparser.py | 2 +- Lib/test/test_configparser.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index 6bc920661a2203..239fda60a02ca0 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -541,7 +541,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, except (KeyError, NoSectionError, NoOptionError): raise InterpolationMissingOptionError( option, section, rawval, ":".join(path)) from None - if not v: + if v is None: continue if "$" in v: self._interpolate_some(parser, opt, accum, v, sect, diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 468da9bd749434..23904d17d326d8 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1328,9 +1328,9 @@ class ConfigParserTestCaseNoValue(ConfigParserTestCase): allow_no_value = True -class ConfigParserTestCaseNoValueAndInterpolation(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(""" @@ -1343,6 +1343,31 @@ def test_interpolation_with_allow_no_value(self): 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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy