Open kkg4theweb opened 1 year ago
After some bug fixes since 1.7.0, now these lines was responsible for converting dicts.
Clearly, we see that from line 142, key
is not applied with type_hooks
in the config
.
Don't know if the author was intended, but a quick fix would be direct, as chaning line 141-142 to
types = extract_generic(collection, defaults=(Any, Any))
return data_type(
(
_build_value(type_=types[0], data=key, config=config),
_build_value(type_=types[1], data=value, config=config),
)
for key, value in data.items()
)
Below is probably a duplicate from the above issue, just wanted to make sure.
Specifically, using cast=[...]
to configure your dacite config instead of the type_hooks
parameter also causes an issue on 1.8.0 (I have knowledge of it working on 1.6.0, didn't test 1.7.0)
from enum import Enum
from typing import Dict
from dacite import from_dict, Config
class Foo(Enum):
EVALUE = 'enum_value'
@dataclass
class FooConfig:
foo: Dict[Foo, str]
data = {"foo": {"enum_value": "bar"}}
# next line throws error in 1.8.0, doesn't in 1.6.0
config = from_dict(data_class=FooConfig, data=data, config=Config(cast=[Foo]))
After some bug fixes since 1.7.0, now these lines was responsible for converting dicts.
Clearly, we see that from line 142,
key
is not applied withtype_hooks
in theconfig
.Don't know if the author was intended, but a quick fix would be direct, as chaning line 141-142 to
types = extract_generic(collection, defaults=(Any, Any)) return data_type( ( _build_value(type_=types[0], data=key, config=config), _build_value(type_=types[1], data=value, config=config), ) for key, value in data.items() )
Thanks for the details! The issue seems to stem from something else, though, as checking as back as v1.6.0, the key
was never being passed through _build_value
. We'll investigate it some more!
Thanks for the details! The issue seems to stem from something else, though, as checking as back as v1.6.0, the
key
was never being passed through_build_value
. We'll investigate it some more!
@mciszczon Here's some investigation for you. In 1.7.0, the code path was as follows:
from_dict()
is called to deserialize the dict.from_dict()
, transform_value()
is called on field_data
for the field in question.
https://github.com/konradhalas/dacite/blob/85c845079785169677e46b0f1e4e49ab884a376b/dacite/core.py#L65-L69transform_value()
, target_type
is a generic collection subclassing dict
, so this code transforms both the key and the item of value.items()
.
https://github.com/konradhalas/dacite/blob/85c845079785169677e46b0f1e4e49ab884a376b/dacite/types.py#L43-L49So the bug in _build_value_for_collection()
, where the key wasn't being transformed, never actually manifested because the same thing was being done (without the bug) earlier in the process.
In 1.8.1, transform_value()
was removed and its functionality was moved to _build_value()
. The key transformation was overlooked, and this bug was introduced.
Describe the bug
Type hooks don't seem to be respected for dict keys. I have been using type-hooks to map string/name of enum values of a dict to the corresponding python enum. This stopped working in dacite version 1.8 but is fine with version 1.7
To Reproduce Here is the code snippet:
Expected behavior
The
dacite.from_dict
should result in the following:EnumKeyMapTypes(string_int_dict_val={<FooEnum.FOO: 1>: 1, <FooEnum.BAR: 2>: 2})
Environment
dacite
version: 1.8 (broken), 1.7 (working)Additional context
This works as expected for dacite version 1.7 but is broken in version 1.8 with the following error:
Google colab broken (1.8): https://colab.research.google.com/drive/1BBMdjkmZow12V_1UlX1dB_jJWWjBx1cv?usp=sharing Google colab working (1.7): https://colab.research.google.com/drive/1z1-qn5ER-FHj7VdOKKlsv7ZzjXm5wekY?usp=sharing