dataclasses-json
dataclasses-json copied to clipboard
feat: use default value when a not optional field is null from json.
Case 1: The upstream has passed a value that may be empty. This empty value has no business meaning. It is hoped that the dataclass_json layer can be completed instead of introducing more types to reduce the complexity of subsequent business logic.
Case 1: The upstream has passed a value that may be empty. This empty value has no business meaning. It is hoped that the dataclass_json layer can be completed instead of introducing more types to reduce the complexity of subsequent business logic.
{
"a": null
}
{
"a": ["1,2,3"]
}
a: Tuple[str] = ()
then with always get the type as Tuple[str]
.
@Bidaya0 I'm not sure I understand your problem. Could you please come up with a code sample of the behaviour you want vs the behaviour you see when using the library?
@dataclass_json
class A:
a = Tuple[str] = ()
Case 1 input json:
{
"a": null
}
library output:
obj = A().from_json()
print(obj.a) # None here
except :
obj = A().from_json()
print(obj.a) # empty Tuple () here
@george-zubrienko
Alright I see what you want to do, and I would actually like to do some work on that, but in the opposite direction of what you want :)
In your case, library should throw an exception, as null
and Tuple
are different types and assigning null fields to an empty list is a semantic error and should be treated as such. But what you want should be achievable with post_init. So, tldr:
@dataclass_json
class A1:
a: Tuple[str] = ()
@dataclass_json
class A2:
a: Optional[Tuple[str]] = None
@dataclass_json
class A3:
a: Optional[Tuple[str]] = None
def __post_init__(self):
self.a = () if not self.a else self.a
data_str = '{"a": null }'
data_obj1 = A1.from_json(data_str) # FormatException: Received `null` in the non-nullable field
data_obj2 = A2.from_json(data_str) # A2(a: None)
data_obj3 = A3.from_json(data_str) # A3(a: ())
I'll create an issue to enforce correct type semantics as a follow-up.
@george-zubrienko
Ok, I kind of misunderstood this part of the docs. Although some means are really provided here to fill in the value, but for typing, it is still either verified or not verified at all.
Person.from_json('{"name": 42}') # This is ok. 42 is not a `str`, but
# dataclass creation does not validate types
Person.schema().loads('{"name": 42}') # Error! Raises `ValidationError`
btw, perhaps I should define the deserialization work of these in the field provided by marshmallow and keep the dataclass tidy.
Thanks for answering.
btw, perhaps I should define the deserialization work of these in the field provided by marshmallow and keep the dataclass tidy.
I think it is a good idea, and thank you as well for raising the issue, as we know now there is some improvement we should work on :)