Skip to content

Commit 45db12a

Browse files
committed
from_dict customization per data class
1 parent c076b8c commit 45db12a

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

dacite/core.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ def _build_value(type_: Type, data: Any, config: Config) -> Any:
9696
elif is_generic_collection(type_):
9797
data = _build_value_for_collection(collection=type_, data=data, config=config)
9898
elif cache(is_dataclass)(type_) and isinstance(data, Mapping):
99-
data = from_dict(data_class=type_, data=data, config=config)
99+
if hasattr(type_, "from_dict"):
100+
data = type_.from_dict(data_class=type_, data=data, config=config)
101+
else:
102+
data = from_dict(data_class=type_, data=data, config=config)
100103
for cast_type in config.cast:
101104
if is_subclass(type_, cast_type):
102105
if is_generic_collection(type_):

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

@@ -225,3 +226,35 @@ class Z:
225226
result = from_dict(Z, data, Config(strict_unions_match=True))
226227

227228
assert result == Z(u=Y(f=1))
229+
230+
231+
def test_custom_from_dict_in_nested_data_class():
232+
@dataclass
233+
class X:
234+
d: date
235+
t: str
236+
237+
def from_dict(data_class, data, config):
238+
data["t"] = "prefix {}".format(data["t"])
239+
return from_dict(
240+
data_class=data_class,
241+
data=data,
242+
config=Config(type_hooks={date: date.fromtimestamp}),
243+
)
244+
245+
@dataclass
246+
class Y:
247+
d: date
248+
x: X
249+
250+
config = Config(type_hooks={date: date.fromordinal})
251+
data = {"d": 737790, "x": {"d": 1607511900.985121, "t": "abc"}}
252+
result = from_dict(Y, data, config=config)
253+
254+
assert result == Y(
255+
d=date(2020, 12, 31),
256+
x=X(
257+
d=date(2020, 12, 9),
258+
t="prefix abc",
259+
),
260+
)

0 commit comments

Comments
 (0)