Skip to content

Commit 92480d7

Browse files
committed
gh-82113: Fix ConfigParser.items() returning '' for value-less options
ConfigParser.items() always ran the option value through interpolation, which turned a None value (a value-less option under allow_no_value=True) into an empty string. get(), mapping access and dict(section) all return None in that case. Skip interpolation when the stored value is None so items() is consistent with the other accessors.
1 parent 30aeeb3 commit 92480d7

3 files changed

Lines changed: 19 additions & 2 deletions

File tree

Lib/configparser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -908,8 +908,10 @@ def items(self, section=_UNSET, raw=False, vars=None):
908908
if vars:
909909
for key, value in vars.items():
910910
d[self.optionxform(key)] = value
911-
value_getter = lambda option: self._interpolation.before_get(self,
912-
section, option, d[option], d)
911+
value_getter = lambda option: (
912+
d[option] if d[option] is None
913+
else self._interpolation.before_get(self, section, option,
914+
d[option], d))
913915
if raw:
914916
value_getter = lambda option: d[option]
915917
return [(option, value_getter(option)) for option in orig_keys]

Lib/test/test_configparser.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,17 @@ def test_other_errors(self):
13271327
class ConfigParserTestCaseNoValue(ConfigParserTestCase):
13281328
allow_no_value = True
13291329

1330+
def test_items_reports_none_for_no_value(self):
1331+
# gh-82113: items() must report None (not '') for value-less options,
1332+
# consistent with get(), mapping access and dict(section).
1333+
cf = self.fromstring("[s]\nno_value\nspam = ham\n")
1334+
self.assertIsNone(cf.get("s", "no_value"))
1335+
self.assertIsNone(cf["s"]["no_value"])
1336+
self.assertEqual(sorted(cf.items("s")),
1337+
[("no_value", None), ("spam", "ham")])
1338+
self.assertEqual(sorted(cf.items("s", raw=True)),
1339+
[("no_value", None), ("spam", "ham")])
1340+
13301341

13311342
class NoValueAndExtendedInterpolation(CfgParserTestCaseClass):
13321343
interpolation = configparser.ExtendedInterpolation()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:meth:`configparser.ConfigParser.items` now reports ``None`` rather than an
2+
empty string for value-less options when ``allow_no_value`` is enabled, making
3+
it consistent with :meth:`~configparser.ConfigParser.get`, mapping access and
4+
``dict()`` conversion of a section.

0 commit comments

Comments
 (0)