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

[bug] Custom decoder for Optional field always evaluated #353

Closed
rpmcginty opened this issue Apr 19, 2022 · 3 comments · Fixed by #354
Closed

[bug] Custom decoder for Optional field always evaluated #353

rpmcginty opened this issue Apr 19, 2022 · 3 comments · Fixed by #354

Comments

@rpmcginty
Copy link
Contributor

rpmcginty commented Apr 19, 2022

Problem

There is inconsistent behavior in how a custom decoder is used depending on whether the field of the custom decoder has Optional type.

For optional fields which can be None, you are supposed to use the Optional[...] type. However, when doing so, it seems that custom decoders are always evaluated.

It should be noted that fields where the default value is None but no Optional[...] typing is present, a custom decoder will only be used if a non-None value is provided.

Example

Given the following nested dataclass:

from dataclasses import dataclass

@dataclass
class A:
    str_value: str

and top-level dataclass X with three fields:

  1. field a1 with default None / custom decoder
  2. field a2 with Optional typing / default None / custom decoder
  3. field a3 with Optional typing / default None
from dataclasses import dataclass, field
from dataclasses_json import DataClassJsonMixin, config

@dataclass
class X(DataClassJsonMixin):
    # This works as expected
    a1: A = field(default=None, metadata=config(decoder=A))
    # This does not work as expected
    a2: Optional[A] = field(default=None, metadata=config(decoder=A))
    # This works as expected
    a3: Optional[A] = field(default=None)

If I were to deserialize an empty dictionary I would expect to receive to nonetype values for a1 and a2, however this is the result:

>>> x = X.from_dict({})
>>> x
# expected `X(a1=None, a2=None, a3=None)`
X(a1=None, a2=A(s=None), a3=None)
@rpmcginty
Copy link
Contributor Author

#354

@rpmcginty rpmcginty changed the title Custom decoder for Optional field always evaluated [bug] Custom decoder for Optional field always evaluated Apr 21, 2022
@TristanSpeakEasy
Copy link
Contributor

Optional is also an issue with a custom encoder, with it being called when the optional field isn't set

@patricksnape
Copy link

I also agree that I would consider this to be a bug since it generates incorrect objects according to the user provided types - we are ignoring None values in our parsing which is surely not a consistent API.

@matt035343 matt035343 linked a pull request Jun 10, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants