diff options
author | T <tnie@tuta.io> | 2023-03-13 20:46:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-13 20:46:35 (GMT) |
commit | 71e37d907905b0504c5bb7b25681adeea2157492 (patch) | |
tree | 02f0f081a14cf8909aed93b5cddc9e62a7fb7cf8 /Lib/dataclasses.py | |
parent | 85ba8a3e03707092800cbf2a29d95e0b495e3cb7 (diff) | |
download | cpython-71e37d907905b0504c5bb7b25681adeea2157492.zip cpython-71e37d907905b0504c5bb7b25681adeea2157492.tar.gz cpython-71e37d907905b0504c5bb7b25681adeea2157492.tar.bz2 |
gh-98169 dataclasses.astuple support DefaultDict (#98170)
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Diffstat (limited to 'Lib/dataclasses.py')
-rw-r--r-- | Lib/dataclasses.py | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index f4617b1..7c3285c 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1321,15 +1321,14 @@ def _asdict_inner(obj, dict_factory): # generator (which is not true for namedtuples, handled # above). return type(obj)(_asdict_inner(v, dict_factory) for v in obj) - elif isinstance(obj, dict) and hasattr(type(obj), 'default_factory'): - # obj is a defaultdict, which has a different constructor from - # dict as it requires the default_factory as its first arg. - # https://bugs.python.org/issue35540 - result = type(obj)(getattr(obj, 'default_factory')) - for k, v in obj.items(): - result[_asdict_inner(k, dict_factory)] = _asdict_inner(v, dict_factory) - return result elif isinstance(obj, dict): + if hasattr(type(obj), 'default_factory'): + # obj is a defaultdict, which has a different constructor from + # dict as it requires the default_factory as its first arg. + result = type(obj)(getattr(obj, 'default_factory')) + for k, v in obj.items(): + result[_asdict_inner(k, dict_factory)] = _asdict_inner(v, dict_factory) + return result return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory)) for k, v in obj.items()) @@ -1382,7 +1381,15 @@ def _astuple_inner(obj, tuple_factory): # above). return type(obj)(_astuple_inner(v, tuple_factory) for v in obj) elif isinstance(obj, dict): - return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) + obj_type = type(obj) + if hasattr(obj_type, 'default_factory'): + # obj is a defaultdict, which has a different constructor from + # dict as it requires the default_factory as its first arg. + result = obj_type(getattr(obj, 'default_factory')) + for k, v in obj.items(): + result[_astuple_inner(k, tuple_factory)] = _astuple_inner(v, tuple_factory) + return result + return obj_type((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) for k, v in obj.items()) else: return copy.deepcopy(obj) |