konradhalas / dacite

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

Dacite does not support containers of containers #50

Closed AngelEzquerra closed 5 years ago

AngelEzquerra commented 5 years ago

The following code does not work as I would expect:

from dataclasses import dataclass, field
import dacite

@dataclass
class item:
    item_field: str = 'default_value'

@dataclass
class container:
    dict_of_dict_of_dataclass: Dict[str, Dict[str, item]] = field(default_factory=dict)

complex_dict = {'dict_of_dict_of_dataclass': {'outer': {'inner': {'item_field': 'a value'}}}}

obj = dacite.from_dict(container, complex_dict)
type(obj.dict_of_dict_of_dataclass['outer']['inner'])  # should return 'item' but it returns 'dict'

If I remove one dict level from the structure, it works as expected:

from dataclasses import dataclass, field
import dacite

@dataclass
class item:
    item_field: str = 'default_value'

@dataclass
class simpler_container:
    dict_of_dataclass: Dict[str, item] = field(default_factory=dict)

simpler_dict = {'dict_of_dataclass': {'inner': {'item_field': 'a value'}}}

obj = dacite.from_dict(simpler_container, simpler_dict)

type(obj.dict_of_dataclass['inner'])  # returns 'item'
konradhalas commented 5 years ago

hi @AngelEzquerra :) Could you reformat your code? It's hard to read.

AngelEzquerra commented 5 years ago

Sorry about that. It is fixed now :-)

konradhalas commented 5 years ago

@AngelEzquerra i checked your example and it works like it should.

This test works for me:

def test_from_dict_issue_50():
    @dataclass
    class item:
        item_field: str = 'default_value'

    @dataclass
    class container:
        dict_of_dict_of_dataclass: Dict[str, Dict[str, item]] = field(default_factory=dict)

    complex_dict = {'dict_of_dict_of_dataclass': {'outer': {'inner': {'item_field': 'a value'}}}}

    obj = from_dict(container, complex_dict)

    assert type(obj.dict_of_dict_of_dataclass['outer']['inner']) == item

Which version of dacite are you using?