konradhalas / dacite

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

Cannot cast sets #94

Closed jasisz closed 1 year ago

jasisz commented 4 years ago

There is a problem with casting sets/frozensets, for which is quite common that lists are used for json when serializing.

This fails in dacite as iterables are casted before inner values are transformed.

An example of failing code:

from dataclasses import dataclass
from typing import Set

from dacite import Config, from_dict

@dataclass(frozen=True)
class A:
    x: int

@dataclass
class SetOfA:
    set_a: Set[A]

from_dict(data_class=SetOfA, data={"set_a": [{"x": 1}]}, config=Config(cast=[set]))

which fails with:

TypeError: unhashable type: 'dict'
konradhalas commented 4 years ago

Dear @jasisz - thank you very much for reporting this issue :)

You have right, it's a bug. Hope to fix it in the next release.

BTW - thank you for using my lib!

louhow commented 3 years ago

👋 I think the same can be said of lists

@dataclass
class A:
  x: int

@dataclass
class ListOfA:
  some_list: [A]

from_dict(ListOfA, {"some_list": [{"x": 1}]}, config=Config(cast=[list])) # Tried with and without Config

which fails with the same:

TypeError: unhashable type: 'list'
louhow commented 3 years ago

Nevermind, I see what I was doing wrong now (needed type_hooks). This works:

@dataclass
class A:
  x: int

@dataclass
class ListOfA:
  some_list: List[A]

print(from_dict(ListOfA, {"some_list": [{"x": 1}]}, config=Config(type_hooks={List: List})))
MaciejHanszke commented 2 years ago

Hey, I've created a PR for that: https://github.com/konradhalas/dacite/pull/174 Would you mind checking it? I'd love to know if there are any edge-cases regarding that issue

konradhalas commented 1 year ago

@jasisz should be OK now.

jasisz commented 1 year ago

@konradhalas Much appreciated! It will simplify my code a lot!