[Python-checkins] bpo-42487: don't call __getitem__ of underlying maps in ChainMap.__iter__ (GH-23534) (GH-23569)
rhettinger
webhook-mailer at python.org
Mon Nov 30 12:07:35 EST 2020
https://github.com/python/cpython/commit/cf22aa3bc698847459a6bf20c166aa80825b810a
commit: cf22aa3bc698847459a6bf20c166aa80825b810a
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: rhettinger <rhettinger at users.noreply.github.com>
date: 2020-11-30T09:07:26-08:00
summary:
bpo-42487: don't call __getitem__ of underlying maps in ChainMap.__iter__ (GH-23534) (GH-23569)
files:
A Misc/NEWS.d/next/Library/2020-11-28-04-31-20.bpo-42487.iqtC4L.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 efd654e8ed739..bc69a6757f294 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -949,7 +949,7 @@ def __len__(self):
def __iter__(self):
d = {}
for mapping in reversed(self.maps):
- d.update(mapping) # reuses stored hash values if possible
+ d.update(dict.fromkeys(mapping)) # reuses stored hash values if possible
return iter(d)
def __contains__(self, key):
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 6aa897927228c..057ec92015cf4 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -195,6 +195,22 @@ def test_order_preservation(self):
('e', 55), ('f', 666), ('g', 777), ('h', 88888),
('i', 9999), ('j', 0)])
+ def test_iter_not_calling_getitem_on_maps(self):
+ class DictWithGetItem(UserDict):
+ def __init__(self, *args, **kwds):
+ self.called = False
+ UserDict.__init__(self, *args, **kwds)
+ def __getitem__(self, item):
+ self.called = True
+ UserDict.__getitem__(self, item)
+
+ d = DictWithGetItem(a=1)
+ c = ChainMap(d)
+ d.called = False
+
+ set(c) # iterate over chain map
+ self.assertFalse(d.called, '__getitem__ was called')
+
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/2020-11-28-04-31-20.bpo-42487.iqtC4L.rst b/Misc/NEWS.d/next/Library/2020-11-28-04-31-20.bpo-42487.iqtC4L.rst
new file mode 100644
index 0000000000000..8c67d747b614e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-11-28-04-31-20.bpo-42487.iqtC4L.rst
@@ -0,0 +1 @@
+ChainMap.__iter__ no longer calls __getitem__ on underlying maps
More information about the Python-checkins
mailing list