Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3df7f26

Browse filesBrowse files
ap--miss-islington
authored andcommitted
bpo-42487: don't call __getitem__ of underlying maps in ChainMap.__iter__ (pythonGH-23534)
(cherry picked from commit 0be9ce3) Co-authored-by: Andreas Poehlmann <andreas@poehlmann.io>
1 parent 03ae7e4 commit 3df7f26
Copy full SHA for 3df7f26

File tree

Expand file treeCollapse file tree

3 files changed

+18
-1
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+18
-1
lines changed

‎Lib/collections/__init__.py

Copy file name to clipboardExpand all lines: Lib/collections/__init__.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ def __len__(self):
949949
def __iter__(self):
950950
d = {}
951951
for mapping in reversed(self.maps):
952-
d.update(mapping) # reuses stored hash values if possible
952+
d.update(dict.fromkeys(mapping)) # reuses stored hash values if possible
953953
return iter(d)
954954

955955
def __contains__(self, key):

‎Lib/test/test_collections.py

Copy file name to clipboardExpand all lines: Lib/test/test_collections.py
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,22 @@ def test_order_preservation(self):
195195
('e', 55), ('f', 666), ('g', 777), ('h', 88888),
196196
('i', 9999), ('j', 0)])
197197

198+
def test_iter_not_calling_getitem_on_maps(self):
199+
class DictWithGetItem(UserDict):
200+
def __init__(self, *args, **kwds):
201+
self.called = False
202+
UserDict.__init__(self, *args, **kwds)
203+
def __getitem__(self, item):
204+
self.called = True
205+
UserDict.__getitem__(self, item)
206+
207+
d = DictWithGetItem(a=1)
208+
c = ChainMap(d)
209+
d.called = False
210+
211+
set(c) # iterate over chain map
212+
self.assertFalse(d.called, '__getitem__ was called')
213+
198214
def test_dict_coercion(self):
199215
d = ChainMap(dict(a=1, b=2), dict(b=20, c=30))
200216
self.assertEqual(dict(d), dict(a=1, b=2, c=30))
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ChainMap.__iter__ no longer calls __getitem__ on underlying maps

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.