@@ -1233,14 +1233,12 @@ class C(Base):
1233
1233
1234
1234
if namespace is None :
1235
1235
namespace = {}
1236
- else :
1237
- # Copy namespace since we're going to mutate it.
1238
- namespace = namespace .copy ()
1239
1236
1240
1237
# While we're looking through the field names, validate that they
1241
1238
# are identifiers, are not keywords, and not duplicates.
1242
1239
seen = set ()
1243
- anns = {}
1240
+ annotations = {}
1241
+ defaults = {}
1244
1242
for item in fields :
1245
1243
if isinstance (item , str ):
1246
1244
name = item
@@ -1249,7 +1247,7 @@ class C(Base):
1249
1247
name , tp , = item
1250
1248
elif len (item ) == 3 :
1251
1249
name , tp , spec = item
1252
- namespace [name ] = spec
1250
+ defaults [name ] = spec
1253
1251
else :
1254
1252
raise TypeError (f'Invalid field: { item !r} ' )
1255
1253
@@ -1261,12 +1259,19 @@ class C(Base):
1261
1259
raise TypeError (f'Field name duplicated: { name !r} ' )
1262
1260
1263
1261
seen .add (name )
1264
- anns [name ] = tp
1262
+ annotations [name ] = tp
1263
+
1264
+ # Update 'ns' with the user-supplied namespace plus our calculated values.
1265
+ def exec_body_callback (ns ):
1266
+ ns .update (namespace )
1267
+ ns .update (defaults )
1268
+ ns ['__annotations__' ] = annotations
1265
1269
1266
- namespace ['__annotations__' ] = anns
1267
1270
# We use `types.new_class()` instead of simply `type()` to allow dynamic creation
1268
1271
# of generic dataclassses.
1269
- cls = types .new_class (cls_name , bases , {}, lambda ns : ns .update (namespace ))
1272
+ cls = types .new_class (cls_name , bases , {}, exec_body_callback )
1273
+
1274
+ # Apply the normal decorator.
1270
1275
return dataclass (cls , init = init , repr = repr , eq = eq , order = order ,
1271
1276
unsafe_hash = unsafe_hash , frozen = frozen ,
1272
1277
match_args = match_args )
0 commit comments