Skip to content

Commit

Permalink
from_dict customization per data class
Browse files Browse the repository at this point in the history
  • Loading branch information
trojkat committed Jan 27, 2023
1 parent c076b8c commit 45db12a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
5 changes: 4 additions & 1 deletion dacite/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ def _build_value(type_: Type, data: Any, config: Config) -> Any:
elif is_generic_collection(type_):
data = _build_value_for_collection(collection=type_, data=data, config=config)
elif cache(is_dataclass)(type_) and isinstance(data, Mapping):
data = from_dict(data_class=type_, data=data, config=config)
if hasattr(type_, "from_dict"):
data = type_.from_dict(data_class=type_, data=data, config=config)
else:
data = from_dict(data_class=type_, data=data, config=config)
for cast_type in config.cast:
if is_subclass(type_, cast_type):
if is_generic_collection(type_):
Expand Down
33 changes: 33 additions & 0 deletions tests/core/test_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
from datetime import date
from enum import Enum
from typing import Optional, List, Union

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

assert result == Z(u=Y(f=1))


def test_custom_from_dict_in_nested_data_class():
@dataclass
class X:
d: date
t: str

def from_dict(data_class, data, config):
data["t"] = "prefix {}".format(data["t"])
return from_dict(
data_class=data_class,
data=data,
config=Config(type_hooks={date: date.fromtimestamp}),
)

@dataclass
class Y:
d: date
x: X

config = Config(type_hooks={date: date.fromordinal})
data = {"d": 737790, "x": {"d": 1607511900.985121, "t": "abc"}}
result = from_dict(Y, data, config=config)

assert result == Y(
d=date(2020, 12, 31),
x=X(
d=date(2020, 12, 9),
t="prefix abc",
),
)

0 comments on commit 45db12a

Please sign in to comment.