konradhalas / dacite

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

Union operator doesn't work for nested dataclasses (Python 3.10) #180

Closed dylanmorroll closed 1 year ago

dylanmorroll commented 2 years ago

In Python 3.10 typing.Union works, but using the operator | does not.

Here is some sample code using the union operator:

from dataclasses import dataclass

import dacite

@dataclass
class NestedSettings:
    two: str | None = None

@dataclass
class Settings:
    one: str | None = None
    nested: NestedSettings | None = None

dacite.from_dict(
    data_class=Settings,
    data={
        "one": "value",
        "nested": {
            "two": "value"
        }
    },
)

The result of this is:

Traceback (most recent call last):
  File "/home/dylan/test_dacite.py", line 17, in <module>
    dacite.from_dict(
  File "/home/dylan/.pyenv/versions/schneider_importer_3.10.2/lib/python3.10/site-packages/dacite/core.py", line 68, in from_dict
    raise WrongTypeError(field_path=field.name, field_type=field.type, value=value)
dacite.exceptions.WrongTypeError: wrong value type for field "nested" - should be "__main__.NestedSettings | None" instead of value "{'two': 'value'}" of type "dict"

However, using typing.Union works fine:

from dataclasses import dataclass
from typing import Union

import dacite

@dataclass
class NestedSettings:
    two: str | None = None

@dataclass
class Settings:
    one: str | None = None
    nested: Union[NestedSettings, None] = None

dacite.from_dict(
    data_class=Settings,
    data={
        "one": "value",
        "nested": {
            "two": "value"
        }
    },
)

The pyupgrade tool for 3.10 automatically changes Optional and Union to the union operator |, see here, so these tools do not work together very well at the moment.

(The rest of the tool is great btw, thanks!)

antonagestam commented 2 years ago

@dylanmorroll I opened a PR with a fix for this issue here. You should be able to install it with pip install https://github.com/antonagestam/dacite/archive/234d486.tar.gz until a fix is released.

konradhalas commented 1 year ago

@dylanmorroll should be fixed with https://github.com/konradhalas/dacite/commit/6e61433b6b1cf9956a33f22510000124f22977b2