diff --git a/Lib/configparser.py b/Lib/configparser.py index 3c452afe8ade48..5cfc21b4d663d6 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -471,6 +471,10 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, except KeyError: raise InterpolationMissingOptionError( option, section, rawval, var) from None + + if v is None: + continue + if "%" in v: self._interpolate_some(parser, option, accum, v, section, map, depth + 1) diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 4783943f71a109..9133d8fc43f200 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1379,6 +1379,17 @@ class RawConfigParserNoValueAndExtendedInterpolationTest( ): config_class = configparser.RawConfigParser +class BasicInterpolationWithAllowNoValueTest(unittest.TestCase): + def test_interpolation_with_allow_no_value(self): + cf = configparser.ConfigParser(allow_no_value=True) + cf.read_string(textwrap.dedent(""" + [s] + a + b = x%(a)sy + """)) + self.assertIsNone(cf["s"]["a"]) + self.assertEqual(cf.get("s", "b"), "xy") + class ConfigParserTestCaseTrickyFile(CfgParserTestCaseClass, unittest.TestCase): config_class = configparser.ConfigParser diff --git a/Misc/NEWS.d/next/Library/2026-07-17-18-53-45.gh-issue-153855.h6YZOX.rst b/Misc/NEWS.d/next/Library/2026-07-17-18-53-45.gh-issue-153855.h6YZOX.rst new file mode 100644 index 00000000000000..64d16508ebed00 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-17-18-53-45.gh-issue-153855.h6YZOX.rst @@ -0,0 +1 @@ +Fix :class:`configparser.BasicInterpolation` raising ``TypeError`` when interpolating a reference to a value-less option with ``allow_no_value=True``; it now treats the missing value as empty, like :class:`configparser.ExtendedInterpolation`.