dacite
dacite copied to clipboard
With strict_unions_match, KeyError is raised instead of UnionMatchError
Describe the bug
If strict_unions_match=True
is present and a union type containing at least one non-primitive type fails to match, the following exception is raised:
Traceback (most recent call last):
File "[redacted]\foo.py", line 57, in <module>
from_dict(Class, {"value": True}, Config(strict_unions_match=True))
File "[redacted]\venv\Lib\site-packages\dacite\core.py", line 69, in from_dict
value = _build_value(type_=field.type, data=transformed_value, config=config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[redacted]\venv\Lib\site-packages\dacite\core.py", line 94, in _build_value
return _build_value_for_union(union=type_, data=data, config=config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[redacted]\venv\Lib\site-packages\dacite\core.py", line 127, in _build_value_for_union
return union_matches.popitem()[1]
^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'popitem(): dictionary is empty'
To Reproduce
@dataclass
class Class:
value: list | dict
from_dict(Class, {"value": True}, Config(strict_unions_match=True))
Expected behavior
UnionMatchError should be raised, like what happens if strict_unions_match
is removed from the Config.
Environment
- Python version: 3.11.0
-
dacite
version: 1.7.0
Additional context
Here's the responsible code. The issue seems to be that there are two different cases when this code is reached: when strict_unions_match is enabled, and when none of the union types were matched. It could probably be fixed by adding something like and union_matches
to line 129.
https://github.com/konradhalas/dacite/blob/10a9ec40fc5874ae434aa68b975d1b1bf667a42f/dacite/core.py#L129-L135
Also, I'm on 1.7.0 instead of 1.8.1 because of #217. I haven't tested this on 1.8.1, but from looking at the code I'm pretty sure the issue should still be present.
Ah, #233 should fix this I think. Missed that.
Can someone review https://github.com/konradhalas/dacite/pull/233 and merge it if it looks ok ? It is a simple fix.
I will note that I ended up switching from Dacite to Pydantic for my use case for this and other reasons, and I haven't encountered any real issues. It also happens to be far more actively maintained.