From 3f714ddd72ef25bf07f39f153ad726f8bf6949ac Mon Sep 17 00:00:00 2001 From: Rogdham <3994389+Rogdham@users.noreply.github.com> Date: Fri, 19 Dec 2025 13:44:03 +0100 Subject: [PATCH] gh-136282: Configparser: create unnamed sections via mapping protocol access (GH-136313) (cherry picked from commit 4aef13832521b4e7785c9643f6a995c92b4a691d) Co-authored-by: Rogdham <3994389+Rogdham@users.noreply.github.com> --- Lib/configparser.py | 3 ++- Lib/test/test_configparser.py | 13 +++++++++++++ .../2025-07-05-08-30-07.gh-issue-136282.K3JKyD.rst | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-07-05-08-30-07.gh-issue-136282.K3JKyD.rst diff --git a/Lib/configparser.py b/Lib/configparser.py index 18af1eadaad111..d435a5c2fe0da2 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -794,7 +794,8 @@ def read_dict(self, dictionary, source=''): """ elements_added = set() for section, keys in dictionary.items(): - section = str(section) + if section is not UNNAMED_SECTION: + section = str(section) try: self.add_section(section) except (DuplicateSectionError, ValueError): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index e7364e18742c16..1bfb53ccbb1398 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -2215,6 +2215,16 @@ def test_add_section(self): cfg.add_section(configparser.UNNAMED_SECTION) cfg.set(configparser.UNNAMED_SECTION, 'a', '1') self.assertEqual('1', cfg[configparser.UNNAMED_SECTION]['a']) + output = io.StringIO() + cfg.write(output) + self.assertEqual(output.getvalue(), 'a = 1\n\n') + + cfg = configparser.ConfigParser(allow_unnamed_section=True) + cfg[configparser.UNNAMED_SECTION] = {'a': '1'} + self.assertEqual('1', cfg[configparser.UNNAMED_SECTION]['a']) + output = io.StringIO() + cfg.write(output) + self.assertEqual(output.getvalue(), 'a = 1\n\n') def test_disabled_error(self): with self.assertRaises(configparser.MissingSectionHeaderError): @@ -2223,6 +2233,9 @@ def test_disabled_error(self): with self.assertRaises(configparser.UnnamedSectionDisabledError): configparser.ConfigParser().add_section(configparser.UNNAMED_SECTION) + with self.assertRaises(configparser.UnnamedSectionDisabledError): + configparser.ConfigParser()[configparser.UNNAMED_SECTION] = {'a': '1'} + def test_multiple_configs(self): cfg = configparser.ConfigParser(allow_unnamed_section=True) cfg.read_string('a = 1') diff --git a/Misc/NEWS.d/next/Library/2025-07-05-08-30-07.gh-issue-136282.K3JKyD.rst b/Misc/NEWS.d/next/Library/2025-07-05-08-30-07.gh-issue-136282.K3JKyD.rst new file mode 100644 index 00000000000000..b5589b47716c70 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-05-08-30-07.gh-issue-136282.K3JKyD.rst @@ -0,0 +1,2 @@ +Add support for :const:`~configparser.UNNAMED_SECTION` when creating a +section via the mapping protocol access