Skip to content

Commit 3df7f26

Browse 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

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Lib/collections/__init__.py

Lines 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

Lines 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))
Lines 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy