Skip to content

bpo-43245: Add keyword argument support to ChainMap.new_child() #24788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Doc/library/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,23 @@ The class can be used to simulate nested scopes and is useful in templating.
be modified to change which mappings are searched. The list should
always contain at least one mapping.

.. method:: new_child(m=None)
.. method:: new_child(m=None, **kwargs)

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.
is equivalent to: ``ChainMap({}, *d.maps)``. If any keyword arguments
are specified, they update passed map or new empty dict. 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.

.. versionchanged:: 3.10
Keyword arguments support was added.

.. attribute:: parents

Property returning a new :class:`ChainMap` containing all of the maps in
Expand Down
7 changes: 5 additions & 2 deletions Lib/collections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,12 +1010,15 @@ def copy(self):

__copy__ = copy

def new_child(self, m=None): # like Django's Context.push()
def new_child(self, m=None, **kwargs): # 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.
Keyword arguments update the map or new empty dict.
'''
if m is None:
m = {}
m = kwargs
elif kwargs:
m.update(kwargs)
return self.__class__(m, *self.maps)

@property
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ def __contains__(self, key):
for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get
self.assertEqual(d.get(k, 100), v)

c = ChainMap({'a': 1, 'b': 2})
d = c.new_child(b=20, c=30)
self.assertEqual(d.maps, [{'b': 20, 'c': 30}, {'a': 1, 'b': 2}])

def test_union_operators(self):
cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4))
cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add keyword arguments support to ``ChainMap.new_child()``.