konradhalas / dacite

Simple creation of data classes from dictionaries.
MIT License
1.76k stars 106 forks source link

field type convert #126

Closed flashpixx closed 3 years ago

flashpixx commented 3 years ago

Hello,

I have got the following dict:

{
   "id": "e9e7a203-99f8-42d7-bab0-05cf90824ebe"
   "text": "any long text"
}

in this case I would like to convert the id into a UUID, but type_hooks does not work, because it would convert the text field and this will break and casting does not work, because the string cannot be casted into a UUID.

May it possible to add to the dacite.Config a new field convert of the type Dict[str, Callable] -> Any so I can add a field converting callable?

BrutalSimplicity commented 3 years ago

Maybe this will work for you.

RecordID = TypeVar("RecordID", str)

@dataclass
class Record:
  id: RecordID
  text: str

config = Config(type_hooks={RecordID: lambda v: uuid.uuid4(v)})
data = {
   "id": "e9e7a203-99f8-42d7-bab0-05cf90824ebe"
   "text": "any long text"
}
result = from_dict(Record, data, config)
konradhalas commented 3 years ago

hi @flashpixx - thank you for reporting this issue.

TBH I like that current solution is "type-based", not "field-based" (both type_hooks and cast).

You can achieve what you want with following approach (similar to @BrutalSimplicity but a little shorter solution):

import uuid
from dataclasses import dataclass

from dacite import Config, from_dict

@dataclass
class Record:
    id: uuid.UUID
    text: str

config = Config(cast=[uuid.UUID])

data = {
    "id": "e9e7a203-99f8-42d7-bab0-05cf90824ebe",
    "text": "any long text",
}
result = from_dict(Record, data, config)