Return value of custom type hook is discarded when decoding generic type in union.
To Reproduce
In the following example, a generic dataclass Foo[T] is defined and used as a field in another dataclass Bar. In the example, only the type Foo[int] is actually used and for that type, a custom type hook is defined that decodes a value from a JSON int:
from typing import TypeVar, Generic, Union
from dataclasses import dataclass
import dacite
T = TypeVar('T')
@dataclass
class Foo(Generic[T]):
value: T
@dataclass
class Bar:
foo: Union[Foo[int], str]
def _read_int_foo(data):
assert isinstance(data, int)
result = Foo(data)
print(f'_read_int_foo: {data} -> {result}')
return result
_dacite_type_hooks = {
Foo[int]: _read_int_foo}
dacite_config = dacite.Config(type_hooks=_dacite_type_hooks, check_types=False)
data = {
'foo': 123
}
print(dacite.from_dict(Bar, data, dacite_config))
Running this prints the following:
_read_int_foo: 123 -> Foo(value=123)
Bar(foo=123)
I.e. the field foo has been set to the original int value from the data instead of the value returned by _read_int_foo(). This only happens when check_types is set to False (otherwise a UnionMatchError is raised).
Describe the bug
Return value of custom type hook is discarded when decoding generic type in union.
To Reproduce
In the following example, a generic dataclass
Foo[T]
is defined and used as a field in another dataclassBar
. In the example, only the typeFoo[int]
is actually used and for that type, a custom type hook is defined that decodes a value from a JSON int:Running this prints the following:
I.e. the field
foo
has been set to the original int value from the data instead of the value returned by_read_int_foo()
. This only happens whencheck_types
is set toFalse
(otherwise aUnionMatchError
is raised).Expected behavior
IMHO, the returned value should be used:
Environment