Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3a8479a

Browse files
committed
Fixes parser.clean() reported in issue #16820.
1 parent 3057469 commit 3a8479a

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

Doc/library/configparser.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,13 @@ However, there are a few differences that should be taken into account:
389389
the default value to be visible again. Trying to delete a default value
390390
causes a ``KeyError``.
391391

392-
* Trying to delete the ``DEFAULTSECT`` raises ``ValueError``.
392+
* ``DEFAULTSECT`` cannot be removed from the parser:
393+
394+
* trying to delete it raises ``ValueError``,
395+
396+
* ``parser.clear()`` leaves it intact,
397+
398+
* ``parser.popitem()`` never returns it.
393399

394400
* ``parser.get(section, option, **kwargs)`` - the second argument is **not**
395401
a fallback value. Note however that the section-level ``get()`` methods are

Lib/configparser.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,19 @@ def items(self, section=_UNSET, raw=False, vars=None):
851851
value_getter = lambda option: d[option]
852852
return [(option, value_getter(option)) for option in d.keys()]
853853

854+
def popitem(self):
855+
"""Remove a section from the parser and return it as
856+
a (section_name, section_proxy) tuple. If no section is present, raise
857+
KeyError.
858+
859+
The section DEFAULT is never returned because it cannot be removed.
860+
"""
861+
for key in self.sections():
862+
value = self[key]
863+
del self[key]
864+
return key, value
865+
raise KeyError
866+
854867
def optionxform(self, optionstr):
855868
return optionstr.lower()
856869

Lib/test/test_cfgparser.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,33 @@ def check_items_config(self, expected):
770770
with self.assertRaises(configparser.NoSectionError):
771771
cf.items("no such section")
772772

773+
def test_popitem(self):
774+
cf = self.fromstring("""
775+
[section1]
776+
name1 {0[0]} value1
777+
[section2]
778+
name2 {0[0]} value2
779+
[section3]
780+
name3 {0[0]} value3
781+
""".format(self.delimiters), defaults={"default": "<default>"})
782+
self.assertEqual(cf.popitem()[0], 'section1')
783+
self.assertEqual(cf.popitem()[0], 'section2')
784+
self.assertEqual(cf.popitem()[0], 'section3')
785+
with self.assertRaises(KeyError):
786+
cf.popitem()
787+
788+
def test_clear(self):
789+
cf = self.newconfig({"foo": "Bar"})
790+
self.assertEqual(
791+
cf.get(self.default_section, "Foo"), "Bar",
792+
"could not locate option, expecting case-insensitive option names")
793+
cf['zing'] = {'option1': 'value1', 'option2': 'value2'}
794+
self.assertEqual(cf.sections(), ['zing'])
795+
self.assertEqual(set(cf['zing'].keys()), {'option1', 'option2', 'foo'})
796+
cf.clear()
797+
self.assertEqual(set(cf.sections()), set())
798+
self.assertEqual(set(cf[self.default_section].keys()), {'foo'})
799+
773800

774801
class StrictTestCase(BasicTestCase):
775802
config_class = configparser.RawConfigParser

0 commit comments

Comments
 (0)