summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/collections.rst15
-rw-r--r--Lib/test/test_collections.py14
2 files changed, 29 insertions, 0 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index d847d6b..ca2f116 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -100,6 +100,21 @@ 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 74372d2..2d5a266 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -113,6 +113,20 @@ class TestChainMap(unittest.TestCase):
self.assertEqual(f['b'], 5) # find first in chain
self.assertEqual(f.parents['b'], 2) # look beyond maps[0]
+ def test_ordering(self):
+ # 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'}
+ 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