konradhalas / dacite

Simple creation of data classes from dictionaries.
MIT License
1.72k stars 107 forks source link

Unable to cast list of values #20

Closed condemil closed 5 years ago

condemil commented 5 years ago

I am trying to cast a list of strings to UUIDs and get the error. Here is the example:

>>> from dataclasses import dataclass
>>> from typing import List
>>> from uuid import UUID
>>>
>>> import dacite
>>>
>>>
>>> @dataclass
... class A:
...     uuid_list: List[UUID]
...
...
>>> data = {'uuid_list': ['3416bc37-9d53-49dc-8361-ad2fb261fb71', 'e81bdbb7-14cd-480b-81ff-369ff49a0bcc']}
>>>
>>> dacite.from_dict(data_class=A, data=data, config=dacite.Config(cast=['uuid_list']))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    dacite.from_dict(data_class=A, data=data, config=dacite.Config(cast=['uuid_list']))
  File "/Users/dmitry/.local/pyenv/versions/3.7.0/envs/sandbox/lib/python3.7/site-packages/dacite.py", line 93, in from_dict
    value = cls(value)
  File "/Users/dmitry/.local/pyenv/versions/3.7.0/lib/python3.7/typing.py", line 668, in __call__
    raise TypeError(f"Type {self._name} cannot be instantiated; "
TypeError: Type List cannot be instantiated; use list() instead
>>>
konradhalas commented 5 years ago

@condemil interesting.

I don't know should dacite handle cast for collections. I have to think about it.

For now you can use Config.transform:

import uuid
from dataclasses import dataclass
from typing import List

import dacite

@dataclass
class X:
    ids: List[uuid.UUID]

data = {
    'ids': [
        '715d2862-cae0-4d61-8491-a6aa2311e859',
        '715d2862-cae0-4d61-8491-a6aa2311e859',
    ],
}

def transform_uuids_list(uuids):
    return [
        uuid.UUID(value)
        for value in uuids
    ]

x = dacite.from_dict(
    data_class=X,
    data=data,
    config=dacite.Config(transform={'ids': transform_uuids_list}),
)