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

This commit is contained in:
Eric V. Smith 2021-04-12 21:02:02 -04:00 committed by GitHub
parent 85918e4ab6
commit c1a66bdd6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 8 deletions

View 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)

View File

@ -0,0 +1,2 @@
Remove an unneeded copy of the namespace passed to
dataclasses.make_dataclass().