]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Remove an unnecessary copy of the 'namespace' parameter to make_dataclass(). (GH...
authorEric V. Smith <ericvsmith@users.noreply.github.com>
Tue, 13 Apr 2021 01:02:02 +0000 (21:02 -0400)
committerGitHub <noreply@github.com>
Tue, 13 Apr 2021 01:02:02 +0000 (21:02 -0400)
Lib/dataclasses.py
Misc/NEWS.d/next/Library/2021-04-12-18-01-10.bpo-43820.YkqYW4.rst [new file with mode: 0644]

index e8eb2060f6df174f4094c3957483eac795ff773d..3ccfbbd92035a2928cf5352e7faea9f9d5de1a23 100644 (file)
@@ -1233,14 +1233,12 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
 
     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 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
             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 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
             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 (file)
index 0000000..2c870ac
--- /dev/null
@@ -0,0 +1,2 @@
+Remove an unneeded copy of the namespace passed to
+dataclasses.make_dataclass().