I'm trying to instantiate a class inheriting from BaseModel that has one member variable. I want this to be an immutable mapping type; currently, I'm using FrozenDict from flax while waiting for PEP 603.
The problem is that pydantic seems to recognise this type as a dict, and tries to cast to a dict as stated in the docs when typing.Dict is used for a field. This works regardless of setting arbitrary_types_allowed to True or False. Is there any way I can circumvent this behaviour in this one case, while still having the isinstance check I would expect for arbitrary_types_allowed = True?
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.7.3
pydantic compiled: True
install path: /Users/phinate/.venvs/clarinet/lib/python3.8/site-packages/pydantic
python version: 3.8.3 (default, May 19 2020, 13:54:14) [Clang 10.0.0 ]
platform: macOS-10.15.7-x86_64-i386-64bit
optional deps. installed: []
from pydantic import BaseModel
from flax.core import FrozenDict, freeze
​
class Example(BaseModel):
dct: FrozenDict[str, int]
​
d = freeze(dict(x=3))
type(d)
> flax.core.frozen_dict.FrozenDict
class_d = Example(dct=d).dct
type(class_d)
> dict
...
Hi @phinate!
Yeah it's currently expected from _pydantic_. I guess we could try to keep the original type by adding
elif issubclass(type(v), Mapping):
return type(v)(result), None
In the meantime the easiest workaround is to add a validator
class Example(BaseModel):
dct: FrozenDict[str, int]
@validator('dct')
def to_frozendict(cls, v):
return FrozenDict(v)
Hope it helps!
Thanks, this works great!
I'd say from a user perspective, it would be nice to not have implicit casting (you could lose access to class methods, for example), but that's ultimately your decision.
Oh and thanks for working on pydantic, its pretty awesome :)