konradhalas / dacite

Simple creation of data classes from dictionaries.
MIT License
1.72k stars 106 forks source link

`strict_union_match` shadows the Error raised in `__post_init__` #242

Open DyeKuu opened 1 year ago

DyeKuu commented 1 year ago

Describe the bug strict_union_match shadows the Error raised in __post_init__

To Reproduce

from dacite import from_dict, Config
from dataclasses import dataclass
from typing import Union

@dataclass
class XArgs:
    a: str
    b: str

    def __post_init__(self):
        if self.b not in ["bingo"]:
            raise ValueError("I want bingo")

@dataclass
class YArgs:
    a: str
    b: str
    c: str

@dataclass
class DataArgs:
    dataset: Union[YArgs, XArgs]

dict_data = {
    "dataset": {
        "a": "aaa",
        "b": "bbb",
    },
}

dataclass_data = from_dict(data_class=DataArgs, data=dict_data, config=Config(strict=True, strict_unions_match=True))
print(dataclass_data)

And I got:

Traceback (most recent call last):
  File "test.py", line 32, in <module>
    dataclass_data = from_dict(data_class=DataArgs, data=dict_data, config=Config(strict=True, strict_unions_match=True))
  File "/miniconda/envs/pt2/lib/python3.10/site-packages/dacite/core.py", line 64, in from_dict
    value = _build_value(type_=field_type, data=field_data, config=config)
  File "/miniconda/envs/pt2/lib/python3.10/site-packages/dacite/core.py", line 95, in _build_value
    data = _build_value_for_union(union=type_, data=data, config=config)
  File "/miniconda/envs/pt2/lib/python3.10/site-packages/dacite/core.py", line 132, in _build_value_for_union
    return union_matches.popitem()[1]
KeyError: 'popitem(): dictionary is empty'

Expected behavior raise ValueError("I want bingo")

Environment