Skip to content

bpo-43820: Remove an unnecessary copy of the 'namespace' parameter to make_dataclass() #25372

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
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
21 changes: 13 additions & 8 deletions Lib/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}')

Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove an unneeded copy of the namespace passed to
dataclasses.make_dataclass().