Open pingretispec opened 9 months ago
I was able to reproduce this bug with a few simplifications to the code snippet:
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import Union
import uuid
import json
@dataclass_json
@dataclass
class Record1:
id: uuid.UUID
count: int
@dataclass_json
@dataclass
class Record2:
id: uuid.UUID
qty: int
@dataclass_json
@dataclass
class Message:
type: str
op: str
record: Union[Record1, Record2]
record = Record2(id=uuid.UUID(int=1), qty=10)
message = Message(type='count', op='create', record=record)
msg_json = json.dumps(message.to_dict())
msg = Message.from_json(msg_json)
Which results in:
dataclasses_json/core.py:325: UserWarning: Failed to decode {'id': '001', 'qty': 10} Union dataclasses.Expected Union to include a matching dataclass and it didn't.
warnings.warn(
>>> msg
Message(type='count', op='create', record={'id': '001', 'qty': 10})
For @pingretispec I would recommend using the schema
as a workaround:
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import Union
import uuid
import json
@dataclass_json
@dataclass
class Record1:
id: uuid.UUID
count: int
@dataclass_json
@dataclass
class Record2:
id: uuid.UUID
qty: int
@dataclass_json
@dataclass
class Message:
type: str
op: str
record: Union[Record1, Record2]
record = Record2(id=uuid.UUID(int=1), qty=10)
message = Message(type='count', op='create', record=record)
schema = message.schema()
schema_json = schema.dump(message)
msg = schema.load(schema_json)
Which does the encoding and decoding successfully:
>>> msg
Message(type='count', op='create', record=Record2(id=UUID('00000000-0000-0000-0000-000000000001'), qty=10))
Description
I have a Message json dataclass that has a field namely "record" that can be dataclass Record1, Record2, or Record3. The code fails trying to infer record with dataclass Record1.
Code snippet that reproduces the issue
@dataclass_json @dataclass class Message: type: MessageType op: Operation record: Union[Record1, Record2]
@dataclass_json @dataclass class Record1: id: uuid.UUID date: datetime.date count: int
@dataclass_json @dataclass class Record2: id: uuid.UUID date: datetime.date qty: int
record = Record2(id='001', date=datetime.date(2022,9,22), qty=10) message = Message(type=MessageType.COUNT, op=Operation.CREATE, record=record) msg_json = json.dump(message.to_dict(), json_path) with open(json_path) as json_f: msg = Message.from_json(json_f.read())
Describe the results you expected
msg = Message(type="COUNT", op="CREATE", record=Record2(id="001", date=datetime.date(2022,9,22), qty=10))
Python version you are using
python --version 3.10.10
Environment description
dataclasses-json==0.6.0