summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/dataclasses.py17
-rw-r--r--Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst2
2 files changed, 14 insertions, 5 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index b0b8a77..3eacba8 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1324,11 +1324,18 @@ def _asdict_inner(obj, dict_factory):
if type(obj) in _ATOMIC_TYPES:
return obj
elif _is_dataclass_instance(obj):
- result = []
- for f in fields(obj):
- value = _asdict_inner(getattr(obj, f.name), dict_factory)
- result.append((f.name, value))
- return dict_factory(result)
+ # fast path for the common case
+ if dict_factory is dict:
+ return {
+ f.name: _asdict_inner(getattr(obj, f.name), dict)
+ for f in fields(obj)
+ }
+ else:
+ result = []
+ for f in fields(obj):
+ value = _asdict_inner(getattr(obj, f.name), dict_factory)
+ result.append((f.name, value))
+ return dict_factory(result)
elif isinstance(obj, tuple) and hasattr(obj, '_fields'):
# obj is a namedtuple. Recurse into it, but the returned
# object is another namedtuple of the same type. This is
diff --git a/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst b/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst
new file mode 100644
index 0000000..f84ec5c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-10-19-33-36.gh-issue-103000.j0KSfD.rst
@@ -0,0 +1,2 @@
+Improve performance of :func:`dataclasses.asdict` for the common case where
+*dict_factory* is ``dict``. Patch by David C Ellis.