Skip to content

Commit 5cd5c88

Browse files
committed
from_dict customization per data class
1 parent d2206b2 commit 5cd5c88

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

dacite/core.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def _build_value(type_: Type, data: Any, config: Config) -> Any:
8989
elif is_generic_collection(type_) and is_instance(data, extract_origin_collection(type_)):
9090
return _build_value_for_collection(collection=type_, data=data, config=config)
9191
elif is_dataclass(type_) and is_instance(data, Data):
92+
if hasattr(type_, 'from_dict'):
93+
return type_.from_dict(data_class=type_, data=data, config=config)
9294
return from_dict(data_class=type_, data=data, config=config)
9395
return data
9496

tests/core/test_config.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from dataclasses import dataclass
2+
from datetime import date
23
from enum import Enum
34
from typing import Optional, List, Union
45

@@ -203,3 +204,35 @@ class Z:
203204
result = from_dict(Z, data, Config(strict_unions_match=True))
204205

205206
assert result == Z(u=Y(f=1))
207+
208+
209+
def test_custom_from_dict_in_nested_data_class():
210+
@dataclass
211+
class X:
212+
d: date
213+
t: str
214+
215+
def from_dict(data_class, data, config):
216+
data["t"] = "prefix {}".format(data["t"])
217+
return from_dict(
218+
data_class=data_class,
219+
data=data,
220+
config=Config(type_hooks={date: date.fromtimestamp}),
221+
)
222+
223+
@dataclass
224+
class Y:
225+
d: date
226+
x: X
227+
228+
config = Config(type_hooks={date: date.fromisoformat})
229+
data = {"d": "2020-12-31", "x": {"d": 1607511900.985121, "t": "abc"}}
230+
result = from_dict(Y, data, config=config)
231+
232+
assert result == Y(
233+
d=date(2020, 12, 31),
234+
x=X(
235+
d=date(2020, 12, 9),
236+
t="prefix abc",
237+
),
238+
)

0 commit comments

Comments
 (0)