dacite icon indicating copy to clipboard operation
dacite copied to clipboard

With strict_unions_match, KeyError is raised instead of UnionMatchError

Open object-Object opened this issue 1 year ago • 3 comments

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.

object-Object avatar Jun 16 '23 00:06 object-Object

Ah, #233 should fix this I think. Missed that.

object-Object avatar Jun 19 '23 04:06 object-Object

Can someone review https://github.com/konradhalas/dacite/pull/233 and merge it if it looks ok ? It is a simple fix.

kkg4theweb avatar Apr 02 '24 18:04 kkg4theweb

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.

object-Object avatar Apr 02 '24 19:04 object-Object