From da0847048aa7f934573fa449cea8643def056aa5 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 27 Mar 2019 08:02:28 +0200 Subject: [PATCH] bpo-36431: Use PEP 448 dict unpacking for merging two dicts. (GH-12553) --- Lib/functools.py | 21 +++++++-------------- Lib/idlelib/rpc.py | 3 +-- Lib/pdb.py | 6 ++---- Lib/urllib/request.py | 3 +-- Lib/xml/etree/ElementTree.py | 7 ++----- Lib/xml/sax/saxutils.py | 3 +-- 6 files changed, 14 insertions(+), 29 deletions(-) diff --git a/Lib/functools.py b/Lib/functools.py index fe47600caa1..426653f13f6 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -285,10 +285,7 @@ class partial: if hasattr(func, "func"): args = func.args + args - tmpkw = func.keywords.copy() - tmpkw.update(keywords) - keywords = tmpkw - del tmpkw + keywords = {**func.keywords, **keywords} func = func.func self = super(partial, cls).__new__(cls) @@ -302,9 +299,8 @@ class partial: if not args: raise TypeError("descriptor '__call__' of partial needs an argument") self, *args = args - newkeywords = self.keywords.copy() - newkeywords.update(keywords) - return self.func(*self.args, *args, **newkeywords) + keywords = {**self.keywords, **keywords} + return self.func(*self.args, *args, **keywords) @recursive_repr() def __repr__(self): @@ -371,8 +367,7 @@ class partialmethod(object): # it's also more efficient since only one function will be called self.func = func.func self.args = func.args + args - self.keywords = func.keywords.copy() - self.keywords.update(keywords) + self.keywords = {**func.keywords, **keywords} else: self.func = func self.args = args @@ -391,11 +386,9 @@ class partialmethod(object): def _make_unbound_method(self): def _method(*args, **keywords): - call_keywords = self.keywords.copy() - call_keywords.update(keywords) - cls_or_self, *rest = args - call_args = (cls_or_self,) + self.args + tuple(rest) - return self.func(*call_args, **call_keywords) + cls_or_self, *args = args + keywords = {**self.keywords, **keywords} + return self.func(cls_or_self, *self.args, *args, **keywords) _method.__isabstractmethod__ = self.__isabstractmethod__ _method._partialmethod = self return _method diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 9962477cc56..f035bde4a0a 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -64,8 +64,7 @@ def dumps(obj, protocol=None): class CodePickler(pickle.Pickler): - dispatch_table = {types.CodeType: pickle_code} - dispatch_table.update(copyreg.dispatch_table) + dispatch_table = {types.CodeType: pickle_code, **copyreg.dispatch_table} BUFSIZE = 8*1024 diff --git a/Lib/pdb.py b/Lib/pdb.py index bf3219af398..f5d33c27fc1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -491,8 +491,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): # Collect globals and locals. It is usually not really sensible to also # complete builtins, and they clutter the namespace quite heavily, so we # leave them out. - ns = self.curframe.f_globals.copy() - ns.update(self.curframe_locals) + ns = {**self.curframe.f_globals, **self.curframe_locals} if '.' in text: # Walk an attribute chain up to the last part, similar to what # rlcompleter does. This will bail if any of the parts are not @@ -1377,8 +1376,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): Start an interactive interpreter whose global namespace contains all the (global and local) names found in the current scope. """ - ns = self.curframe.f_globals.copy() - ns.update(self.curframe_locals) + ns = {**self.curframe.f_globals, **self.curframe_locals} code.interact("*interactive*", local=ns) def do_alias(self, arg): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 9a3d399f018..df2ff06f0fc 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -426,8 +426,7 @@ class Request: self.unredirected_hdrs.pop(header_name, None) def header_items(self): - hdrs = self.unredirected_hdrs.copy() - hdrs.update(self.headers) + hdrs = {**self.unredirected_hdrs, **self.headers} return list(hdrs.items()) class OpenerDirector: diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index c1cf483cf56..b5ad8e1d140 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -169,10 +169,8 @@ class Element: if not isinstance(attrib, dict): raise TypeError("attrib must be dict, not %s" % ( attrib.__class__.__name__,)) - attrib = attrib.copy() - attrib.update(extra) self.tag = tag - self.attrib = attrib + self.attrib = {**attrib, **extra} self._children = [] def __repr__(self): @@ -451,8 +449,7 @@ def SubElement(parent, tag, attrib={}, **extra): additional attributes given as keyword arguments. """ - attrib = attrib.copy() - attrib.update(extra) + attrib = {**attrib, **extra} element = parent.makeelement(tag, attrib) parent.append(element) return element diff --git a/Lib/xml/sax/saxutils.py b/Lib/xml/sax/saxutils.py index a69c7f76217..b4fc2da7640 100644 --- a/Lib/xml/sax/saxutils.py +++ b/Lib/xml/sax/saxutils.py @@ -56,8 +56,7 @@ def quoteattr(data, entities={}): the optional entities parameter. The keys and values must all be strings; each key will be replaced with its corresponding value. """ - entities = entities.copy() - entities.update({'\n': ' ', '\r': ' ', '\t':' '}) + entities = {**entities, '\n': ' ', '\r': ' ', '\t':' '} data = escape(data, entities) if '"' in data: if "'" in data: