konradhalas / dacite

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

WrongTypeError after correctly casting dict keys #192

Closed sh-at-cs closed 1 year ago

sh-at-cs commented 1 year ago

This is probably closely related to #187 but anyway:

If a dictionary's keys contain types that must be cast (enums, UUIDs, ...), the casting itself works, but afterwards, when type checking the dict as a whole, dacite will complain that the type doesn't match despite it actually matching perfectly.

Minimal reproducible example (Python 3.10+ required):

from dataclasses import dataclass
from enum import Enum

import dacite

class E(Enum):
    a = "a"
    b = "b"

@dataclass
class C:
    d: dict[E, str]

c_dict = {"d": {"a": 0}}

c = dacite.from_dict(C, c_dict, config=dacite.Config(cast=[E]))

This yields:

Traceback (most recent call last):
  File "/home/sh/bugs/dacite-enum-dict-keys/minimal-example.py", line 19, in <module>
    c = dacite.from_dict(C, c_dict, config=dacite.Config(cast=[E]))
  File "/home/sh/.pyenv/versions/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 "d" - should be "dict" instead of value "{<E.a: 'a'>: 0}" of type "dict"

So it did cast the key to one of our enum values as desired, but then failed to understand that the resulting dict does in fact match the declared type.

As I said in the introduction, the same thing happens with UUIDs and other types that need to be cast, not just enums.

sh-at-cs commented 1 year ago

Never mind, the mistake was actually in the dict's value type :facepalm: str instead of int