Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asdict breaks with defaultdicts #144

Open
seansfkelley opened this issue May 7, 2019 · 0 comments
Open

asdict breaks with defaultdicts #144

seansfkelley opened this issue May 7, 2019 · 0 comments

Comments

@seansfkelley
Copy link

seansfkelley commented May 7, 2019

https://bugs.python.org/issue35540 is the official bug report on the stdlib implementation in 3.7, copied below. There's a proposed fix at python/cpython#11361 to special-case defaultdict.

_asdict_inner attempts to manually recursively deepcopy dicts by calling type(obj) with a generator of transformed keyvalue tuples @ https://github.com/python/cpython/blob/b2f642ccd2f65d2f3bf77bbaa103dd2bc2733734/Lib/dataclasses.py#L1080 . defaultdicts are dicts so this runs but unlike other dicts their first arg has to be a callable or None:

import collections
import dataclasses as dc

@dc.dataclass()
class C:
    d: dict

c = C(collections.defaultdict(lambda: 3, {}))
d = dc.asdict(c)

assert isinstance(d['d'], collections.defaultdict)
assert d['d']['a'] == 3

=>

Traceback (most recent call last):
  File "boom.py", line 9, in <module>
    d = dc.asdict(c)
  File "/Users/spinlock/.pyenv/versions/3.7.1/lib/python3.7/dataclasses.py", line 1019, in asdict
    return _asdict_inner(obj, dict_factory)
  File "/Users/spinlock/.pyenv/versions/3.7.1/lib/python3.7/dataclasses.py", line 1026, in _asdict_inner
    value = _asdict_inner(getattr(obj, f.name), dict_factory)
  File "/Users/spinlock/.pyenv/versions/3.7.1/lib/python3.7/dataclasses.py", line 1058, in _asdict_inner
    for k, v in obj.items())
TypeError: first argument must be callable or None

I understand that it isn't this bit of code's job to support every dict (and list etc.) subclass under the sun but given defaultdict is stdlib it's imo worth supporting explicitly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant