[Python-checkins] bpo-32792: Preserve mapping order in ChainMap() (GH-5586) (#GH-5617)
Raymond Hettinger
webhook-mailer at python.org
Sun Feb 11 04:10:00 EST 2018
https://github.com/python/cpython/commit/170b3f79506480f78275a801822c9ff1283e16f2
commit: 170b3f79506480f78275a801822c9ff1283e16f2
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Raymond Hettinger <rhettinger at users.noreply.github.com>
date: 2018-02-11T01:09:52-08:00
summary:
bpo-32792: Preserve mapping order in ChainMap() (GH-5586) (#GH-5617)
(cherry picked from commit 3793f95f98c3112ce447288a5bf9899eb9e35423)
Co-authored-by: Raymond Hettinger <rhettinger at users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst
M Lib/collections/__init__.py
M Lib/test/test_collections.py
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
index 8aeee359cd62..c481fe2f2012 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -914,7 +914,10 @@ def __len__(self):
return len(set().union(*self.maps)) # reuses stored hash values if possible
def __iter__(self):
- return iter(set().union(*self.maps))
+ d = {}
+ for mapping in reversed(self.maps):
+ d.update(mapping) # reuses stored hash values if possible
+ return iter(d)
def __contains__(self, key):
return any(key in m for m in self.maps)
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index a55239e57302..2099d236d0c4 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -141,6 +141,23 @@ def __missing__(self, key):
with self.assertRaises(KeyError):
d.popitem()
+ def test_order_preservation(self):
+ d = ChainMap(
+ OrderedDict(j=0, h=88888),
+ OrderedDict(),
+ OrderedDict(i=9999, d=4444, c=3333),
+ OrderedDict(f=666, b=222, g=777, c=333, h=888),
+ OrderedDict(),
+ OrderedDict(e=55, b=22),
+ OrderedDict(a=1, b=2, c=3, d=4, e=5),
+ OrderedDict(),
+ )
+ self.assertEqual(''.join(d), 'abcdefghij')
+ self.assertEqual(list(d.items()),
+ [('a', 1), ('b', 222), ('c', 3333), ('d', 4444),
+ ('e', 55), ('f', 666), ('g', 777), ('h', 88888),
+ ('i', 9999), ('j', 0)])
+
def test_dict_coercion(self):
d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
self.assertEqual(dict(d), dict(a=1, b=2, c=30))
diff --git a/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst b/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst
new file mode 100644
index 000000000000..1f7df62cc3e1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-02-08-00-47-07.bpo-32792.NtyDb4.rst
@@ -0,0 +1 @@
+collections.ChainMap() preserves the order of the underlying mappings.
More information about the Python-checkins
mailing list