Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I make a field wrapped in Optional without a default value to be required during deserialization? #352

Open
Yura52 opened this issue May 23, 2023 · 3 comments
Labels
enhancement New feature or request

Comments

@Yura52
Copy link

Yura52 commented May 23, 2023

Hi! Thank you for the great library!

Let's consider this snippet:

@serde.serde(type_check=serde.Strict)
@dataclass
class A:
    b: Optional[int]

Here, I require the field b to be explicitly passed to the constructor of A. However, serde allows not passing the field b during deserialization:

serde.from_dict(A, {})
# returns A(b=None)

Knowing that dacite made the same design choice, I assume this is an intentional thing, not a bug. Is there any available workaround to require being explicit whenever a field is missing a default value?

Also, I would like to share why, to me personally, the current behavior is surprising.

First, because of the mismatch between Python and serde: I cannot create the object without passing the required field in Python, but I can do it via serde. In other words, for serde, Optional[int] and Optional[int] = None are equivalent, which is not intuitive to me.

Second, because of the following inconsistency:

serde.to_dict(A(None))
# returns {'b': None}

What do you think?

@Yura52 Yura52 changed the title How can make a field wrapped in Optional without a default value to be required during deserialization? How can I make a field wrapped in Optional without a default value to be required during deserialization? May 24, 2023
@yukinarit
Copy link
Owner

Hi @Yura52!

Do you mean that

With this serde class,

@serde.serde(type_check=serde.Strict)
@dataclass
class A:
    b: Optional[int]

This should raise an error because the dict has no key of "b"? 🤔

serde.from_dict(A, {})

@Yura52
Copy link
Author

Yura52 commented May 25, 2023

Hi @yukinarit , yes, this is what I would expect, since there is no default value for the b field, and I want users to explicitly pass None.

It seems to me that this kind of behavior (implicit Optional filling) is a popular design choice: I have already mentioned dacite, but an even more prominent example is TOML, where null was not added to the format, because "you don't need nil or null, just leave out that assignment".

That said, having a flag to make a required field truly required would be nice!

@yukinarit
Copy link
Owner

Understood, I am okay to have that flag in pyserde, as long as we don't change the default behaviour!

@yukinarit yukinarit added the enhancement New feature or request label May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: No status
Development

No branches or pull requests

2 participants