konradhalas / dacite

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

Better support for primitive numeric types #222

Open ltn100 opened 1 year ago

ltn100 commented 1 year ago

I'm not sure if dacite's primitive numeric type handling is by design, but it is not what I expected.

Here is an example:

import dacite
from dataclasses import dataclass

@dataclass
class A:
    x: int
    y: float
    z: complex

dubiously_typed_dict = {
    "x": 1,
    "y": 1,
    "z": 1,
}

a = dacite.from_dict(data_class=A, data=dubiously_typed_dict)

print(a)
# prints: A(x=1, y=1, z=1)
# note: all integer values

Even when we use Config(strict=True), no warning or error is produced.

In order to type cast these values as I expect, we need to do:

a = dacite.from_dict(data_class=A, data=dubiously_typed_dict, config=dacite.Config(cast=[float, int, complex]))

print(a)
# prints: A(x=1, y=1.0, z=(1+0j))

Perhaps it would be good to either:

An alternative solution may be to (ab)use some kind of sentinel to enable casting of all types:

Config(cast=[typing.Any])
Config(cast=[...])
Config(cast=[dacite.Any])
Config(cast=[dacite.Primitives])

or even a new option:

Config(cast_all=True)