From 9d69e26ee6235cbb3e4ef20c37965f7ff9d55d53 Mon Sep 17 00:00:00 2001 From: lipengyu Date: Tue, 11 Aug 2026 20:50:58 +0800 Subject: [PATCH] gh-155436: Fix configparser.getboolean() for value-less options --- Lib/configparser.py | 2 +- Lib/test/test_configparser.py | 8 ++++++++ .../2026-08-09-22-50-19.gh-issue-155436.gyB8_I.rst | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-08-09-22-50-19.gh-issue-155436.gyB8_I.rst diff --git a/Lib/configparser.py b/Lib/configparser.py index 3c452afe8ade48..2d6b1f121d5aee 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -1222,7 +1222,7 @@ def _unify_values(self, section, vars): def _convert_to_boolean(self, value): """Return a boolean value translating from other types if necessary. """ - if value.lower() not in self.BOOLEAN_STATES: + if value is None or value.lower() not in self.BOOLEAN_STATES: raise ValueError('Not a boolean: %s' % value) return self.BOOLEAN_STATES[value.lower()] diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 4783943f71a109..e4034c0ed3b93d 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1338,6 +1338,14 @@ def test_other_errors(self): class ConfigParserTestCaseNoValue(ConfigParserTestCase): allow_no_value = True + def test_getboolean_with_no_value(self): + cf = self.fromstring("[section]\noption\n") + + with self.assertRaisesRegex(ValueError, "Not a boolean: None"): + cf.getboolean("section", "option") + with self.assertRaisesRegex(ValueError, "Not a boolean: None"): + cf["section"].getboolean("option") + class NoValueAndExtendedInterpolation(CfgParserTestCaseClass): interpolation = configparser.ExtendedInterpolation() diff --git a/Misc/NEWS.d/next/Library/2026-08-09-22-50-19.gh-issue-155436.gyB8_I.rst b/Misc/NEWS.d/next/Library/2026-08-09-22-50-19.gh-issue-155436.gyB8_I.rst new file mode 100644 index 00000000000000..9fffec26eb8950 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-09-22-50-19.gh-issue-155436.gyB8_I.rst @@ -0,0 +1,3 @@ +:class:`configparser.ConfigParser` now raises :exc:`ValueError` instead of +:exc:`AttributeError` when :meth:`~configparser.ConfigParser.getboolean` is +called on an option without a value while ``allow_no_value=True``.