You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I atttached a snippet of code that illustrates the issue.
Basically, a Union has dataclasses that have exactly the same field names. When dumping to json, pydantic just dumps it assentially as dictionary, erasing any type information. As a result, during deserializing, it just picks the first compatible element of the union, so the type Country gets deserialized as City:
original object : Country(name='UK')
as json : {'name': 'UK'}
restored from json: City(name='UK')
Traceback (most recent call last):
File "/project/pyd.py", line 24, in <module>
assert obj == restored
AssertionError
I've read the documentation on discriminated Unions, but the issue in my case is that I don't control the types I need to serialize, so I can't add a discriminator field.
Ideally I'd like to have something that discriminates based on class name, e.g. it would dump Country(name='UK') as {'__type__': '__main__.Country', name='UK'} or something like that.
E.g. similar to what cattrs doesn, it allows 'configuring' to discriminate a Union, although it's a bit clunky if you don't know all types in advance, I'd rather have it as an option for TypeAdapter or something like that so it would apply to all Unions.
karlicoss
changed the title
Elements of Union that have the same structure
Elements of Union that have the same structure aren't deserialized correctly
Sep 11, 2023
Well the fundamental problem here is that Schema.dump_python when dumping a dataclass converts it to a dictionary, and the dictionaries created for City and Country are the same. You might be able to use a custom serializer to change how City and Country are serialized.
While your issue isn't that clear about what you want, I think this case or similar cases could be supported by a discriminator function - this is supported in pydantic-core, but doesn't seem to be well supported in Pydantic V2. I create an issue for that now - see #7462.
Initial Checks
Description
I atttached a snippet of code that illustrates the issue.
Basically, a
Union
has dataclasses that have exactly the same field names. When dumping to json, pydantic just dumps it assentially as dictionary, erasing any type information. As a result, during deserializing, it just picks the first compatible element of the union, so the typeCountry
gets deserialized asCity
:I've read the documentation on discriminated Unions, but the issue in my case is that I don't control the types I need to serialize, so I can't add a discriminator field.
Ideally I'd like to have something that discriminates based on class name, e.g. it would dump
Country(name='UK')
as{'__type__': '__main__.Country', name='UK'}
or something like that.E.g. similar to what
cattrs
doesn, it allows 'configuring' to discriminate a Union, although it's a bit clunky if you don't know all types in advance, I'd rather have it as an option forTypeAdapter
or something like that so it would apply to all Unions.Is that possible with Pydantic?
Possibly relevant issues:
Example Code
Python, Pydantic & OS Version
The text was updated successfully, but these errors were encountered: