@@ -222,6 +222,29 @@ def __repr__(self):
222
222
# https://bugs.python.org/issue33453 for details.
223
223
_MODULE_IDENTIFIER_RE = re .compile (r'^(?:\s*(\w+)\s*\.)?\s*(\w+)' )
224
224
225
+ # Atomic immutable types which don't require any recursive handling and for which deepcopy
226
+ # returns the same object. We can provide a fast-path for these types in asdict and astuple.
227
+ _ATOMIC_TYPES = frozenset ({
228
+ # Common JSON Serializable types
229
+ types .NoneType ,
230
+ bool ,
231
+ int ,
232
+ float ,
233
+ str ,
234
+ # Other common types
235
+ complex ,
236
+ bytes ,
237
+ # Other types that are also unaffected by deepcopy
238
+ types .EllipsisType ,
239
+ types .NotImplementedType ,
240
+ types .CodeType ,
241
+ types .BuiltinFunctionType ,
242
+ types .FunctionType ,
243
+ type ,
244
+ range ,
245
+ property ,
246
+ })
247
+
225
248
# This function's logic is copied from "recursive_repr" function in
226
249
# reprlib module to avoid dependency.
227
250
def _recursive_repr (user_function ):
@@ -1291,7 +1314,9 @@ class C:
1291
1314
1292
1315
1293
1316
def _asdict_inner (obj , dict_factory ):
1294
- if _is_dataclass_instance (obj ):
1317
+ if type (obj ) in _ATOMIC_TYPES :
1318
+ return obj
1319
+ elif _is_dataclass_instance (obj ):
1295
1320
result = []
1296
1321
for f in fields (obj ):
1297
1322
value = _asdict_inner (getattr (obj , f .name ), dict_factory )
@@ -1363,7 +1388,9 @@ class C:
1363
1388
1364
1389
1365
1390
def _astuple_inner (obj , tuple_factory ):
1366
- if _is_dataclass_instance (obj ):
1391
+ if type (obj ) in _ATOMIC_TYPES :
1392
+ return obj
1393
+ elif _is_dataclass_instance (obj ):
1367
1394
result = []
1368
1395
for f in fields (obj ):
1369
1396
value = _astuple_inner (getattr (obj , f .name ), tuple_factory )
0 commit comments