[Python-checkins] Remove an unnecessary copy of the 'namespace' parameter to make_dataclass(). (GH-25372)

ericvsmith webhook-mailer at python.org
Mon Apr 12 21:02:10 EDT 2021


https://github.com/python/cpython/commit/c1a66bdd6f884e2ec813891c5c7e2b1ceeede8f1
commit: c1a66bdd6f884e2ec813891c5c7e2b1ceeede8f1
branch: master
author: Eric V. Smith <ericvsmith at users.noreply.github.com>
committer: ericvsmith <ericvsmith at users.noreply.github.com>
date: 2021-04-12T21:02:02-04:00
summary:

Remove an unnecessary copy of the 'namespace' parameter to make_dataclass(). (GH-25372)

files:
A Misc/NEWS.d/next/Library/2021-04-12-18-01-10.bpo-43820.YkqYW4.rst
M Lib/dataclasses.py

diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index e8eb2060f6df1..3ccfbbd92035a 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1233,14 +1233,12 @@ class C(Base):
 
     if namespace is None:
         namespace = {}
-    else:
-        # Copy namespace since we're going to mutate it.
-        namespace = namespace.copy()
 
     # While we're looking through the field names, validate that they
     # are identifiers, are not keywords, and not duplicates.
     seen = set()
-    anns = {}
+    annotations = {}
+    defaults = {}
     for item in fields:
         if isinstance(item, str):
             name = item
@@ -1249,7 +1247,7 @@ class C(Base):
             name, tp, = item
         elif len(item) == 3:
             name, tp, spec = item
-            namespace[name] = spec
+            defaults[name] = spec
         else:
             raise TypeError(f'Invalid field: {item!r}')
 
@@ -1261,12 +1259,19 @@ class C(Base):
             raise TypeError(f'Field name duplicated: {name!r}')
 
         seen.add(name)
-        anns[name] = tp
+        annotations[name] = tp
+
+    # Update 'ns' with the user-supplied namespace plus our calculated values.
+    def exec_body_callback(ns):
+        ns.update(namespace)
+        ns.update(defaults)
+        ns['__annotations__'] = annotations
 
-    namespace['__annotations__'] = anns
     # We use `types.new_class()` instead of simply `type()` to allow dynamic creation
     # of generic dataclassses.
-    cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace))
+    cls = types.new_class(cls_name, bases, {}, exec_body_callback)
+
+    # Apply the normal decorator.
     return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
                      unsafe_hash=unsafe_hash, frozen=frozen,
                      match_args=match_args)
diff --git a/Misc/NEWS.d/next/Library/2021-04-12-18-01-10.bpo-43820.YkqYW4.rst b/Misc/NEWS.d/next/Library/2021-04-12-18-01-10.bpo-43820.YkqYW4.rst
new file mode 100644
index 0000000000000..2c870ac8b97de
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-04-12-18-01-10.bpo-43820.YkqYW4.rst
@@ -0,0 +1,2 @@
+Remove an unneeded copy of the namespace passed to
+dataclasses.make_dataclass().



More information about the Python-checkins mailing list