From e2bc688a57de023496e641cf0de3d38ff894d59b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 20 Feb 2019 22:40:01 -0800 Subject: [PATCH 1/4] Update ChainMap() docs to discuss ordering. Add related tests --- Doc/library/collections.rst | 16 ++++++++++++++++ Lib/test/test_collections.py | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index bde7b6e90082de6..d99e333b7e348fa 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -100,6 +100,22 @@ The class can be used to simulate nested scopes and is useful in templating. :func:`super` function. A reference to ``d.parents`` is equivalent to: ``ChainMap(*d.maps[1:])``. + Note, the iteration order of a :class:`ChainMap()` is determined by + scanning the mappings last to first:: + + + >>> baseline = {'music': 'bach', 'art': 'rembrandt'} + >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'} + >>> list(ChainMap(adjustments, baseline)) + ['music', 'art', 'opera'] + + This gives the same ordering as a series of :meth:`dict.update` calls + starting with the last mapping:: + + >>> combined = baseline.copy() + >>> combined.update(adjustments) + >>> list(combined) + ['music', 'art', 'opera'] .. seealso:: diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 74372d28ed050d5..59fb23e42bb2c73 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -113,6 +113,20 @@ def test_basics(self): self.assertEqual(f['b'], 5) # find first in chain self.assertEqual(f.parents['b'], 2) # look beyond maps[0] + def test_ordering(self): + # The combined order is the same a series of dict updates from last to first. + # This test relies on the ordering of the underlying dicts. + + baseline = {'music': 'bach', 'art': 'rembrandt'} + adjustments = {'art': 'van gogh', 'opera': 'carmen'} + + cm = ChainMap(adjustments, baseline) + + combined = baseline.copy() + combined.update(adjustments) + + self.assertEqual(list(combined.items()), list(cm.items())) + def test_constructor(self): self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list From 6b5a581c0d7227038e633a03402de88d1bdd7a86 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 20 Feb 2019 22:42:55 -0800 Subject: [PATCH 2/4] Spurious blank line --- Doc/library/collections.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index d99e333b7e348fa..e6887c24cb644cc 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -103,7 +103,6 @@ The class can be used to simulate nested scopes and is useful in templating. Note, the iteration order of a :class:`ChainMap()` is determined by scanning the mappings last to first:: - >>> baseline = {'music': 'bach', 'art': 'rembrandt'} >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'} >>> list(ChainMap(adjustments, baseline)) From 0d9dbdafaffa9ca480492fa91181e5d1b8e14936 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 20 Feb 2019 23:09:49 -0800 Subject: [PATCH 3/4] Fix whitespace --- Lib/test/test_collections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 59fb23e42bb2c73..b38330525b4dc0f 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -116,7 +116,7 @@ def test_basics(self): def test_ordering(self): # The combined order is the same a series of dict updates from last to first. # This test relies on the ordering of the underlying dicts. - + baseline = {'music': 'bach', 'art': 'rembrandt'} adjustments = {'art': 'van gogh', 'opera': 'carmen'} From 7bf2c584a6a13c24e7e873c47b0b56dd4e5df2f1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 21 Feb 2019 00:24:54 -0800 Subject: [PATCH 4/4] Fix typo in comment and make more concise --- Lib/test/test_collections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index b38330525b4dc0f..2d5a2661b6898e4 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -114,7 +114,7 @@ def test_basics(self): self.assertEqual(f.parents['b'], 2) # look beyond maps[0] def test_ordering(self): - # The combined order is the same a series of dict updates from last to first. + # Combined order matches a series of dict updates from last to first. # This test relies on the ordering of the underlying dicts. baseline = {'music': 'bach', 'art': 'rembrandt'}