Comments (9)
Hi Diogo,
first of all, thank you for creating the very first issue in this project :) It's good to know that someone is using (or trying to use!) dacite
.
Regarding your question: I see your problem, but to be honest, I really don't know is it a good idea or maybe I should say - I don't know how to solve it properly.
I was trying to find a solution to a similar issue with Union
type, my case looks like this:
from typing import Union
@dataclass
class Container:
box: Union[Car, Person]
Currently dacite
is looking for a data class on the provided list of types, if there is any, it takes first one and it tries to convert provided data into this inner data class. Of course, this is not the perfect solution, but it works.
But maybe dacite
should try to convert data into each of this data class, and if it fails with the first one, it should take next on the list? Does it sound OK or is too "magic"?
We can also support TypeVar
, but I thought it was mainly designed to handle "generic" functions and methods. Can you use Union
in your case?
from dacite.
First of all, double thank you! 1), because of the quick reply and 2) because I've been trying to use TypeVar
for the wrong purpose, without knowing that what I need is actually Union
😄 (I'm still inexperienced with type hinting in Python 3)
So your idea sounds very good to me - to try to convert to each type on the list, until one of them succeeds. The only problem I can think of, with this approach, is if it ends up returning an instance for the wrong type because the list of types is ambiguous, but, to be honest, it's the user's responsibility to make sure that they don't have ambiguity in their types or, if they do, it's up to them to do the proper conversions.
By the way, just to let you know what I'm trying to use your library for: I'm experimenting with it to know whether it's a good approach to have dicts converted to dataclass instances after validating them with OpenAPI 3. I've been struggling to have Marshmallow and other side libraries working well for my case - specially because I need the oneOf
feature of OpenAPI 3 -, and now I'm experimenting with approaching it by starting with the JSON schema first (instead of having Python schemas determining the resulting schema for OpenAPI).
from dacite.
Good to hear that I could help :)
I implemented proper unions handling in feature/handle-unions branch. You can install this version with the following command:
pip install git+https://github.com/konradhalas/dacite@feature/handle-unions
It would be great if you found the time to test it in your case :) Let me know if it works as you want and as we described.
from dacite.
Hey man,
So, I created this file:
#!/usr/bin/env python
from typing import (
List,
Union,
)
import dacite
from dataclasses import dataclass
@dataclass
class Car:
name: str
@dataclass
class Person:
age: int
@dataclass
class Container:
contained: Union[Car, Person]
@dataclass
class Containers:
containers: List[Container]
raw_data = {
'containers': [
{
'contained': {
'name': 'Ford',
},
},
{
'contained': {
'age': '21',
},
},
]
}
containers = dacite.from_dict(Containers, raw_data)
assert isinstance(containers.containers[0].contained, Car)
assert isinstance(containers.containers[1].contained, Person)
and running it I get:
$ ./test-union-dacite.py
Traceback (most recent call last):
File "./test-union-dacite.py", line 48, in <module>
containers = dacite.from_dict(Containers, raw_data)
File "/home/diogobaeder/Envs/tmp/lib/python3.6/site-packages/dacite.py", line 79, in from_dict
field=field,
File "/home/diogobaeder/Envs/tmp/lib/python3.6/site-packages/dacite.py", line 171, in _inner_from_dict_for_collection
) for item in data)
File "/home/diogobaeder/Envs/tmp/lib/python3.6/site-packages/dacite.py", line 171, in <genexpr>
) for item in data)
File "/home/diogobaeder/Envs/tmp/lib/python3.6/site-packages/dacite.py", line 72, in from_dict
outer_config=config,
File "/home/diogobaeder/Envs/tmp/lib/python3.6/site-packages/dacite.py", line 195, in _inner_from_dict_for_union
raise UnionMatchError(field)
dacite.UnionMatchError: can not match the data to any type of "contained" union: typing.Union[__main__.Car, __main__.Person]
If I did anything wrong in that script, please let me know, but so far it doesn't seem to be working.
from dacite.
It looks like age
(in raw_data
) should be int
instead of str
. Am I right? ;)
from dacite.
Oh my gosh, I'm sorry, completely overlooked that...
Aaaaand it works beautifully! Good job! :-)
from dacite.
Awesome! I released new version 0.0.14
. It's on PyPI now. Thank you once again :)
from dacite.
Awesome! Good job, man! :-)
from dacite.
Sorry to comment on a closed ticket again, but, man, what a terrific job! That change is working really well to me, and I'm even using it in nested dataclass models, with Config(transform=...)
. :-)
from dacite.
Related Issues (20)
- With strict_unions_match, KeyError is raised instead of UnionMatchError HOT 3
- missing pypi source tarball for 1.8.1 release HOT 3
- Subsequent calls of from_dict on dataclasses that contain Optional[type] and type | None breaks behaviour because of caching HOT 1
- Add missing value factory for from_dict()
- dict cannot be matched if keys are specified as enums in dataclass HOT 3
- Using dacite fails at runtime with pkg_resources.DistributionNotFound HOT 2
- DefaultValueNotFoundError for Optional fields
- `strict_union_match` shadows the Error raised in `__post_init__`
- ValueError: dictionary update sequence element #0 has length 1; 2 is required HOT 1
- from_dict resets `dataclasses.field` with argument `init=False` and `default_factory` HOT 1
- Dacite will put an `int` into an `Optional[float]` field but not a `float | None` field.
- Should it work with Dict[sometype, sometype]?
- Add support for Python 3.12 HOT 2
- dataclass does not accept union of dataclasses?
- Dictionary matching errors with object type key
- dacite.from_dict: `NamedTuple` type hook does not work with `cast=[tuple]` (regression from v1.7.0)
- `WrongTypeError` - `should be "str" instead of value ... of type "int"` - Important when loading data from yaml HOT 1
- subclassing support for type_hooks HOT 1
- Python 3.9+ style collections with forward references fails to resolve types HOT 1
- Missing sdist for `dacite==1.8.1`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dacite.