lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON
MIT License
1.34k stars 150 forks source link

[BUG] No way to default explicit nulls/Nones to a value #497

Open PatrickF1 opened 8 months ago

PatrickF1 commented 8 months ago

Description

If a field is explicitly set to a null in JSON or a None in a dict, the decoder on that field is always ignored and so either there the field becomes a None once decoded or a validation error is raised.

This was originally written here https://stackoverflow.com/questions/65345984/convert-null-into-np-nan-when-decoding-json-in-python-dataclass.

Code snippet that reproduces the issue

@dataclass
class ToyDataclass(DataClassJsonMixin):
    value: Optional[int] = field(
        default=1,
        metadata=config(
            decoder=lambda val: val if val else 1,
        ),
    )

if __name__ == '__main__':
    print(ToyDataclass.schema().load({"value": None}))
    print(ToyDataclass.from_dict({"value": None}))
    print(ToyDataclass.schema().loads('{"value": null}'))
    print(ToyDataclass.from_json('{"value": null}'))

Output is

ToyDataclass(value=None)
ToyDataclass(value=None)
ToyDataclass(value=None)
ToyDataclass(value=None)

And if I remove the Optional from value: Optional[int] dataclasses-json raises a ValidationError with the .schema() calls.

I have tried multiple versions of recent dataclasses-json. I think this is a bug because I think the decoder should be called even when the field is an explicit null/None.

Describe the results you expected

The decoder function should be evaluated on its field even if the value set for the field is null/None at least for the non-schema from_dict calls.

Python version you are using

3.11.5

Environment description

dataclasses-json==0.6.1