From 9fb68618a5095c81a7aa6ef364c4837ff0c5e2e6 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Sat, 12 May 2018 09:58:15 -0700 Subject: [PATCH 01/10] bpo-33463: warn _asdict --> dict, not OrderedDict Now that dict is tracking insertion order, namedtuple._asdict can be switched to returning a basic dict instead of an OrderedDict. The interface is largely similar, but some minor differences will require a deprecation cycle before making the change. --- Lib/collections/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 3109054e20c148e..a866bee94155b96 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -25,6 +25,7 @@ from _weakref import proxy as _proxy from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr +import warnings try: from _collections import deque @@ -425,6 +426,9 @@ def __repr__(self): def _asdict(self): 'Return a new OrderedDict which maps field names to their values.' + # https://bugs.python.org/issue33463 + warnings.warn('_asdict will return a basic dict instead of OrderedDict', + PendingDeprecationWarning) return OrderedDict(zip(self._fields, self)) def __getnewargs__(self): From af20cb9158becfcf0397c739c57570c5d98c2a74 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Wed, 23 May 2018 13:55:50 -0700 Subject: [PATCH 02/10] Change namedtuple._asdict to return dict not OrderedDict As per @serhiy-storchaka's suggestion, a warning here is too noisy. The difference between OrderedDict and dict is now negligible. --- Lib/collections/__init__.py | 8 ++------ .../next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) create mode 100644 Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index a866bee94155b96..80f7be74e6a2e85 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -25,7 +25,6 @@ from _weakref import proxy as _proxy from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr -import warnings try: from _collections import deque @@ -425,11 +424,8 @@ def __repr__(self): return self.__class__.__name__ + repr_fmt % self def _asdict(self): - 'Return a new OrderedDict which maps field names to their values.' - # https://bugs.python.org/issue33463 - warnings.warn('_asdict will return a basic dict instead of OrderedDict', - PendingDeprecationWarning) - return OrderedDict(zip(self._fields, self)) + 'Return a new dict which maps field names to their values.' + return dict(zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' diff --git a/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst b/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst new file mode 100644 index 000000000000000..4f1c4cb30fb2b8e --- /dev/null +++ b/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst @@ -0,0 +1 @@ +namedtuple._asdict returns dict instead of OrderedDict \ No newline at end of file From 029b9216ed36bf6f469d5740684c6cbc0504c75a Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Thu, 28 Jun 2018 12:29:00 -0700 Subject: [PATCH 03/10] add author note --- .../next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst b/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst index 4f1c4cb30fb2b8e..ca2c689514235cd 100644 --- a/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst +++ b/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst @@ -1 +1,2 @@ -namedtuple._asdict returns dict instead of OrderedDict \ No newline at end of file +namedtuple._asdict returns dict instead of OrderedDict. +Patch by Michael Selik. \ No newline at end of file From 39079a4b8f87ac87423acfa9866c34134bf20575 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 13:27:46 -0700 Subject: [PATCH 04/10] update docs to say _asdict returns dict not OrderedDict Added versioning info and fixed the doctest example. --- Doc/library/collections.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 2a83d30372770ba..7ffa335d56de2ae 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -886,18 +886,21 @@ field names, the method and attribute names start with an underscore. .. method:: somenamedtuple._asdict() - Return a new :class:`OrderedDict` which maps field names to their corresponding + Return a new :class:`dict` which maps field names to their corresponding values: .. doctest:: >>> p = Point(x=11, y=22) >>> p._asdict() - OrderedDict([('x', 11), ('y', 22)]) + {'x': 11, 'y': 22} .. versionchanged:: 3.1 Returns an :class:`OrderedDict` instead of a regular :class:`dict`. + .. versionchanged:: 3.8 + Returns an :class:`dict` instead of a regular :class:`OrderedDict`. + .. method:: somenamedtuple._replace(**kwargs) Return a new instance of the named tuple replacing specified fields with new From fe155d5ab2995505883a416803ec547fc370f7ca Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 13:30:27 -0700 Subject: [PATCH 05/10] blurb add --- .../next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst diff --git a/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst b/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst new file mode 100644 index 000000000000000..102efda78932588 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst @@ -0,0 +1,2 @@ +namedtuple._asdict returns dict instead of OrderedDict. Patch by Michael +Selik. From eb8f84b42939f2f84a7097a5efd4151b6a7136ff Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Wed, 12 Sep 2018 17:12:50 -0700 Subject: [PATCH 06/10] wording changed per Serhiy's suggestion --- Doc/library/collections.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 7ffa335d56de2ae..ecc4adf187d0744 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -886,8 +886,8 @@ field names, the method and attribute names start with an underscore. .. method:: somenamedtuple._asdict() - Return a new :class:`dict` which maps field names to their corresponding - values: + Return a new ordered dictionary which maps field names to their + corresponding values: .. doctest:: @@ -899,7 +899,8 @@ field names, the method and attribute names start with an underscore. Returns an :class:`OrderedDict` instead of a regular :class:`dict`. .. versionchanged:: 3.8 - Returns an :class:`dict` instead of a regular :class:`OrderedDict`. + Returns an :class:`dict` instead of a :class:`OrderedDict`, + since it can now keep keys the same order as namedtuple fields. .. method:: somenamedtuple._replace(**kwargs) From c014656fa162eeae33ef94c6720ff4223fa5daf1 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Wed, 12 Sep 2018 17:16:11 -0700 Subject: [PATCH 07/10] remove duplate news entry --- .../next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst diff --git a/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst b/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst deleted file mode 100644 index ca2c689514235cd..000000000000000 --- a/Misc/News.d/next/Library/2018-05-23-13-46-10.bpo-33463.34haT9.rst +++ /dev/null @@ -1,2 +0,0 @@ -namedtuple._asdict returns dict instead of OrderedDict. -Patch by Michael Selik. \ No newline at end of file From ab6315635e9e38d79be390cba2cb3879d379f178 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Wed, 12 Sep 2018 17:19:26 -0700 Subject: [PATCH 08/10] clarify reason for update --- .../next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst b/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst index 102efda78932588..1dd0efd393602dc 100644 --- a/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst +++ b/Misc/NEWS.d/next/Library/2018-06-29-13-30-14.bpo-33463.b_BpgK.rst @@ -1,2 +1,3 @@ -namedtuple._asdict returns dict instead of OrderedDict. Patch by Michael +namedtuple._asdict returns dict instead of OrderedDict, since dict now +keeps keys in insertion order, the same as OrderedDict. Patch by Michael Selik. From e6af4b01a7c8edbdfc566c480320c46d0b8cd3a9 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Tue, 18 Sep 2018 18:43:15 -0700 Subject: [PATCH 09/10] test _asdict ordering --- Lib/test/test_collections.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 2099d236d0c4a1f..6ef40952bcdd911 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -331,6 +331,7 @@ def test_instance(self): self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method + self.assertEqual(list(p._asdict()), ['x', 'y']) # test _asdict ordering try: p._replace(x=1, error=2) From 9b50f6babea61b815702c9478c68bb2aac0b2cd8 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Tue, 18 Sep 2018 18:50:51 -0700 Subject: [PATCH 10/10] note lack of move_to_end --- Doc/whatsnew/3.8.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 11538e26691c182..f09489c06e6cd8d 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -146,6 +146,13 @@ Changes in the Python API a database if it does not exist. (Contributed by Serhiy Storchaka in :issue:`32749`.) +* The :meth:`~collections.namedtuple._asdict` method returns a :class:`dict` + instead of :class:`collections.OrderedDict`, because :class:`dict` keeps + insertion order, which is the same behavior as + :class:`collections.OrderedDict`. Anyone relying on + :meth:`~collections.OrderedDict.move_to_end` will want to explicitly construct + an :class:`collections.OrderedDict`. + CPython bytecode changes ------------------------