Skip to content

asdict() on dataclass with defaultdict raises TypeError: "first argument must be callable or None " #106113

Closed as not planned
@johentsch

Description

@johentsch

Bug report

Minimal working example:

from dataclasses import dataclass, field, asdict
from typing import DefaultDict
from collections import defaultdict

def default_list_dict():
    return defaultdict(list)

@dataclass
class Data:
    metadata: DefaultDict = field(default_factory=default_list_dict)
    
D = Data() # => Data(metadata=defaultdict(<class 'list'>, {}))
asdict(D)
  • Expected output: {'metadata': defaultdict(list, {})}
  • Got instead: TypeError: first argument must be callable or None
Display traceback
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[1], line 13
     10     metadata: DefaultDict = field(default_factory=default_list_dict)
     12 D = Data()
---> 13 asdict(D)

File ~/miniconda3/lib/python3.10/dataclasses.py:1238, in asdict(obj, dict_factory)
   1236 if not _is_dataclass_instance(obj):
   1237     raise TypeError("asdict() should be called on dataclass instances")
-> 1238 return _asdict_inner(obj, dict_factory)

File ~/miniconda3/lib/python3.10/dataclasses.py:1245, in _asdict_inner(obj, dict_factory)
   1243 result = []
   1244 for f in fields(obj):
-> 1245     value = _asdict_inner(getattr(obj, f.name), dict_factory)
   1246     result.append((f.name, value))
   1247 return dict_factory(result)

File ~/miniconda3/lib/python3.10/dataclasses.py:1275, in _asdict_inner(obj, dict_factory)
   1273     return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
   1274 elif isinstance(obj, dict):
-> 1275     return type(obj)((_asdict_inner(k, dict_factory),
   1276                       _asdict_inner(v, dict_factory))
   1277                      for k, v in obj.items())
   1278 else:
   1279     return copy.deepcopy(obj)

TypeError: first argument must be callable or None

Your environment

  • CPython versions tested on: Python 3.10.11 [GCC 11.2.0] on linux
  • Operating system and architecture: Linux 6.1.31-2-MANJARO Support "bpo-" in Misc/NEWS #1 SMP PREEMPT_DYNAMIC Sun Jun 4 12:31:46 UTC 2023 x86_64 GNU/Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions