Closes #16613: Added optional mapping argument to ChainMap.new_child.
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 6ef114e..ea4a311 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -76,14 +76,19 @@
         be modified to change which mappings are searched.  The list should
         always contain at least one mapping.
 
-    .. method:: new_child()
+    .. method:: new_child(m=None)
 
-        Returns a new :class:`ChainMap` containing a new :class:`dict` followed by
-        all of the maps in the current instance.  A call to ``d.new_child()`` is
-        equivalent to: ``ChainMap({}, *d.maps)``.  This method is used for
+        Returns a new :class:`ChainMap` containing a new map followed by
+        all of the maps in the current instance.  If ``m`` is specified,
+        it becomes the new map at the front of the list of mappings; if not
+        specified, an empty dict is used, so that a call to ``d.new_child()``
+        is equivalent to: ``ChainMap({}, *d.maps)``.  This method is used for
         creating subcontexts that can be updated without altering values in any
         of the parent mappings.
 
+        .. versionchanged:: 3.4
+           The optional ``m`` parameter was added.
+
     .. attribute:: parents
 
         Property returning a new :class:`ChainMap` containing all of the maps in
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
index 53083e4..0612e1f 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -821,9 +821,14 @@
 
     __copy__ = copy
 
-    def new_child(self):                        # like Django's Context.push()
-        'New ChainMap with a new dict followed by all previous maps.'
-        return self.__class__({}, *self.maps)
+    def new_child(self, m=None):                # like Django's Context.push()
+        '''
+        New ChainMap with a new map followed by all previous maps. If no
+        map is provided, an empty dict is used.
+        '''
+        if m is None:
+            m = {}
+        return self.__class__(m, *self.maps)
 
     @property
     def parents(self):                          # like Django's Context.pop()
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 8850e8b..dfad78e 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -112,6 +112,38 @@
         self.assertEqual(dict(d), dict(a=1, b=2, c=30))
         self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30))
 
+    def test_new_child(self):
+        'Tests for changes for issue #16613.'
+        c = ChainMap()
+        c['a'] = 1
+        c['b'] = 2
+        m = {'b':20, 'c': 30}
+        d = c.new_child(m)
+        self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}])  # check internal state
+        self.assertIs(m, d.maps[0])
+
+        # Use a different map than a dict
+        class lowerdict(dict):
+            def __getitem__(self, key):
+                if isinstance(key, str):
+                    key = key.lower()
+                return dict.__getitem__(self, key)
+            def __contains__(self, key):
+                if isinstance(key, str):
+                    key = key.lower()
+                return dict.__contains__(self, key)
+
+        c = ChainMap()
+        c['a'] = 1
+        c['b'] = 2
+        m = lowerdict(b=20, c=30)
+        d = c.new_child(m)
+        self.assertIs(m, d.maps[0])
+        for key in 'abc':                                             # check contains
+            self.assertIn(key, d)
+        for k, v in dict(a=1, B=20, C=30, z=100).items():             # check get
+            self.assertEqual(d.get(k, 100), v)
+
 
 ################################################################################
 ### Named Tuples