dacite
dacite copied to clipboard
Possible bug: Cannot load dataclasses with members of defined generic type
I had a use case where some dataclasses had members with common fields. In order to reduce code duplication, I tried to create a common class using generics. When I tried to load my data - it failed with WrongTypeError, while the type received looks fine.
I wrote simple code example to replicate this behavior:
from dataclasses import dataclass, asdict
from typing import Generic, TypeVar, List
from dacite import from_dict
T = TypeVar('T')
@dataclass
class Common(Generic[T]):
foo: T
bar: T
@dataclass
class A:
elements: List[Common[int]]
a = A([Common[int](1, 2), Common[int](3, 4)])
from_dict(A, asdict(a))
Running the code throws the following exception:
dacite.exceptions.WrongTypeError: wrong value type for field "elements" - should be "typing.List[__main__.Common[int]]" instead of value "[{'foo': 1, 'bar': 2}, {'foo': 3, 'bar': 4}]" of type "list"
I believe this behavior to be a bug, since [{'foo': 1, 'bar': 2}, {'foo': 3, 'bar': 4}]
is of type List[Common[int]]
Note: this example is simplified, in my case I had another class that had a member of type Common[str]
I encountered the same problem. Did you find any workaround yet?
Hi @samuelsd1 - you have right, dacite
doesn't work with custom-made generic types, but it looks like a nice feature to implement. I'm adding it on my list.
Hi @konradhalas. Thanks for the great library! Any update on this issue, or a possible work-around? I have a generic type KeyValuePair(Generic[K, V_co])
(a dataclass), and dacite gets angry when I have a frozenset
of them on a class.
@dataclass(frozen=True)
class SomeThing:
id: UUID
ref: Reference
topics: frozenset[str] = field(default_factory=frozenset)
metadata: frozenset[KeyValuePair[str, str]] = field(default_factory=frozenset)
dacite.from_dict
is OK with the topics
field because its generic type is a "base" (non-generic) type, but it fails when type checking the metadata
field because the generic type is itself a user-defined generic of KeyValuePair[str, str]
.
I hit a similar problem with a delaration like this (running python 3.9) and concerned about running the app in python 3.8.
T = TypeVar('T')
@dataclass
class PagedDTO(Generic[T]):
...
values: List[T]
Only option ATM appears to be to do away with the generics and create N subclasses. <class 'typing._GenericAlias'>
Sad that typing.py does not cope with generics of all sorts... (python 3.9 only appears to support <class 'function'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'module'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'method_descriptor'>)
Not sure how well progressed type hinting is and whether my problem is that there is no current support for PEP-585.