konradhalas / dacite

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

Does not handle string enum fields #183

Closed dddvision closed 1 year ago

dddvision commented 2 years ago

Thanks for producing this tool. Unfortunately, it currently does not seem to handle string enum fields.

#!/usr/bin/env python3

import dataclasses
import enum
import dacite

class MyEnum(str, enum.Enum):
    INVALID = "INVALID"
    FOO = "FOO"
    BAR = "BAR"

@dataclasses.dataclass
class MyDataClass:
    my_enum: MyEnum = MyEnum.INVALID

x = dacite.from_dict(MyDataClass, {"my_enum": "INVALID"})

Exception has occurred: WrongTypeError (note: full exception trace is shown but execution is paused at: _run_module_as_main) wrong value type for field "my_enum" - should be "MyEnum" instead of value "INVALID" of type "str" File "/home/diel.david@aurora.aero/anaconda3/lib/python3.9/site-packages/dacite/core.py", line 68, in from_dict raise WrongTypeError(field_path=field.name, field_type=field.type, value=value)

bytinbit commented 2 years ago

It does :)

Here's how:

class MyEnum(Enum): INVALID = "INVALID" FOO = "FOO" BAR = "BAR"

@dataclasses.dataclass class MyDataClass: my_enum: MyEnum = MyEnum.INVALID

invalidclass = MyDataClass(my_enum=MyEnum.INVALID)

x = from_dict(MyDataClass, {"my_enum": "INVALID"}, config=Config(cast=[Enum])) # cast it here

assert x == invalidclass # passes

konradhalas commented 1 year ago

@bytinbit thank you for the good answer :)

JCBrouwer commented 3 months ago

Is there a way to automate this?

In this case MyDataClass knows exactly which Enum it expects, why doesn't it just try this cast automatically?

It's a little cumbersome to have a list of 12 enums in the Config for every call to from_dict.