Skip to content

bpo-33504: Migrate configparser from OrderedDict to dict. #6819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 9 additions & 41 deletions Doc/library/configparser.rst
Original file line number Diff line number Diff line change
Expand Up @@ -445,20 +445,19 @@ the :meth:`__init__` options:
Hint: if you want to specify default values for a specific section, use
:meth:`read_dict` before you read the actual file.

* *dict_type*, default value: :class:`collections.OrderedDict`
* *dict_type*, default value: :class:`dict`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to reword the rest of this section. It suggests below that "you can also use a regular dictionary" (but we already are!) and that "When you use a regular dictionary in those operations, the order of the keys may be random." which is no longer true.

Would be good to change this to describe what is actually happening

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding .. versionchanged:: would be also nice.


This option has a major impact on how the mapping protocol will behave and how
the written configuration files look. With the default ordered
dictionary, every section is stored in the order they were added to the
parser. Same goes for options within sections.
the written configuration files look. With the standard dictionary, every
section is stored in the order they were added to the parser. Same goes for
options within sections.

An alternative dictionary type can be used for example to sort sections and
options on write-back. You can also use a regular dictionary for performance
reasons.
options on write-back.

Please note: there are ways to add a set of key-value pairs in a single
operation. When you use a regular dictionary in those operations, the order
of the keys may be random. For example:
of the keys will be ordered. For example:

.. doctest::

Expand All @@ -474,40 +473,9 @@ the :meth:`__init__` options:
... 'baz': 'z'}
... })
>>> parser.sections() # doctest: +SKIP
['section3', 'section2', 'section1']
>>> [option for option in parser['section3']] # doctest: +SKIP
['baz', 'foo', 'bar']

In these operations you need to use an ordered dictionary as well:

.. doctest::

>>> from collections import OrderedDict
>>> parser = configparser.ConfigParser()
>>> parser.read_dict(
... OrderedDict((
... ('s1',
... OrderedDict((
... ('1', '2'),
... ('3', '4'),
... ('5', '6'),
... ))
... ),
... ('s2',
... OrderedDict((
... ('a', 'b'),
... ('c', 'd'),
... ('e', 'f'),
... ))
... ),
... ))
... )
>>> parser.sections() # doctest: +SKIP
['s1', 's2']
>>> [option for option in parser['s1']] # doctest: +SKIP
['1', '3', '5']
>>> [option for option in parser['s2'].values()] # doctest: +SKIP
['b', 'd', 'f']
['section1', 'section2', 'section3']
>>> [option for option in parser['section3']] # doctest: +SKIP
['foo', 'bar', 'baz']

* *allow_no_value*, default value: ``False``

Expand Down
3 changes: 2 additions & 1 deletion Lib/configparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
"""

from collections.abc import MutableMapping
from collections import OrderedDict as _default_dict, ChainMap as _ChainMap
from collections import ChainMap as _ChainMap
import functools
import io
import itertools
Expand All @@ -157,6 +157,7 @@
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]

_default_dict = dict
DEFAULTSECT = "DEFAULT"

MAX_INTERPOLATION_DEPTH = 10
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_configparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ def test_set_nonstring_types(self):
self.assertEqual(cf.get(123, 'this is sick'), True)
if cf._dict is configparser._default_dict:
# would not work for SortedDict; only checking for the most common
# default dictionary (OrderedDict)
# default dictionary (dict)
cf.optionxform = lambda x: x
cf.set('non-string', 1, 1)
self.assertEqual(cf.get('non-string', 1), 1)
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ Marc Recht
John Redford
Terry J. Reedy
Gareth Rees
John Reese
Steve Reeves
Lennart Regebro
John Regehr
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Switch the default dictionary implementation for :mod:`configparser` from
:class:`collections.OrderedDict` to the standard :class:`dict` type.