Describe the bug
When trying to deserialize a dictionary into a dataclass, if the class structure includes a dictionary with its key being an object, then a WrongTypeError exception is raised.
To Reproduce
from dataclasses import dataclass
from dacite import Config, from_dict
from bson import ObjectId
@dataclass
class NiceObj:
a: str
b: str
@dataclass
class Foo:
d: dict[ObjectId, NiceObj]
tc = from_dict(Foo, {'d': {'4142434445464748494a4b4c': {"a": "1", "b": "2"}}}, config=Config(cast=[ObjectId]))
print(tc)
Expected behavior
In Dacite 1.7.0, this correctly gives the output
dacite.exceptions.WrongTypeError: wrong value type for field "d" - should be "dict" instead of value "{'4142434445464748494a4b4c': NiceObj(a='1', b='2')}" of type "dict"
Environment
Python version: 3.11.4
dacite version: 1.8.0
Additional context
I think this is similar to #239 and #217
Modifying the function _build_value_for_collection in core.py to
def _build_value_for_collection(collection: Type, data: Any, config: Config) -> Any:
data_type = data.__class__
if isinstance(data, Mapping) and is_subclass(collection, Mapping):
key_type, item_type = extract_generic(collection, defaults=(Any, Any))
return data_type(
(_build_value(type_=key_type, data=key, config=config), # Modified this line
_build_value(type_=item_type, data=value, config=config))
for key, value in data.items())
elif isinstance(data, tuple) and is_subclass(collection, tuple):
if not data:
return data_type()
types = extract_generic(collection)
if len(types) == 2 and types[1] == Ellipsis:
return data_type(_build_value(type_=types[0], data=item, config=config) for item in data)
return data_type(
_build_value(type_=type_, data=item, config=config) for item, type_ in zip_longest(data, types)
)
elif isinstance(data, Collection) and is_subclass(collection, Collection):
item_type = extract_generic(collection, defaults=(Any,))[0]
return data_type(_build_value(type_=item_type, data=item, config=config) for item in data)
return data
helped. I essentially added a line to recursive build the key in addition to the value that was already being done in the isinstance(data, Mapping) and is_subclass(collection, Mapping) condition. This was also noted in https://github.com/konradhalas/dacite/issues/217#issuecomment-1606140697
Describe the bug When trying to deserialize a dictionary into a dataclass, if the class structure includes a dictionary with its key being an object, then a
WrongTypeError
exception is raised.To Reproduce
Expected behavior In Dacite 1.7.0, this correctly gives the output
but in v1.8.0+ it outputs the following error
Environment
dacite
version: 1.8.0Additional context
_build_value_for_collection
incore.py
tohelped. I essentially added a line to recursive build the key in addition to the value that was already being done in the
isinstance(data, Mapping) and is_subclass(collection, Mapping)
condition. This was also noted in https://github.com/konradhalas/dacite/issues/217#issuecomment-1606140697