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

Decoder Fails to Deserialize Union with Dataclass variants #255

Closed
mao3267 opened this issue Nov 9, 2024 · 6 comments
Closed

Decoder Fails to Deserialize Union with Dataclass variants #255

mao3267 opened this issue Nov 9, 2024 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@mao3267
Copy link

mao3267 commented Nov 9, 2024

  • mashumaro version: 3.13.1
  • Python version: 3.12.2
  • Operating System: Sequoia 15.0

Description

I'm encountering an issue when using mashumaro to serialize and deserialize a nested dataclass with Union properties that include dataclasses and other non-None variants. While the serialization works as expected, the deserialization does not properly decode the union property. Instead of the expected object, the decoded result falls back to a dict type.

What I Did

Here is a minimal reproducible example:

from mashumaro.codecs.msgpack import MessagePackDecoder, MessagePackEncoder
from dataclasses import dataclass
from typing import Any, Union
import msgpack

def _default_msgpack_decoder(data: bytes) -> Any:
    return msgpack.unpackb(data, raw=False, strict_map_key=False)

@dataclass
class A:
    a: int

@dataclass
class InnerDC:
    a: Union[None, str, A] # or Union[str, A]

@dataclass
class DC:
    inner_dc: InnerDC 
    

# Encoding works
encoder = MessagePackEncoder(DC)
msgpack_bytes = encoder.encode(DC(inner_dc=InnerDC(a=A(a=1))))

# Decoding fails
decoder = MessagePackDecoder(DC, pre_decoder_func=_default_msgpack_decoder)
python_val = decoder.decode(msgpack_bytes)

assert python_val == DC(inner_dc=InnerDC(a=A(a=1)))

Actual Result

The decoded result is:
DC(inner_dc=InnerDC(a={'a': 1}))

The union property a is incorrectly decoded as a dictionary instead of the expected A object.

Expected Result

The decoded result should be:
DC(inner_dc=InnerDC(a=A(a=1)))

It would be helpful to understand whether this is a bug or if additional configuration is required.

@Future-Outlier
Copy link

Hi, @Fatal1ty
Do you know how to fix it?
If you don't have time, @mao3267 can create a PR to do this.
but we need some guidance, for example point out where might exist the bug

@Fatal1ty
Copy link
Owner

Hi @mao3267 @Future-Outlier

This is an old issue related to the default str deserialization as it was described here.

Good news, yesterday I finally decided to put an end to this problem and change the logic for deserializing unions containing str, bool, so we can expect a solution soon. In the next release, when deserializing unions, we will check the type of the input value before returning it as is as a string.

@Fatal1ty Fatal1ty self-assigned this Nov 11, 2024
@Fatal1ty Fatal1ty added the bug Something isn't working label Nov 11, 2024
@Future-Outlier
Copy link

Hi @mao3267 @Future-Outlier

This is an old issue related to the default str deserialization as it was described here.

Good news, yesterday I finally decided to put an end to this problem and change the logic for deserializing unions containing str, bool, so we can expect a solution soon. In the next release, when deserializing unions, we will check the type of the input value before returning it as is as a string.

really love this solution, thank you very much, we will definitely test more if you need us, feel free to ping us <3

@Fatal1ty
Copy link
Owner

we will definitely test more if you need us, feel free to ping us <3

I would appreciate if you check the branch from this PR:

@Fatal1ty
Copy link
Owner

The fix is ​​ready, will be in the next release.

@Future-Outlier
Copy link

The fix is ​​ready, will be in the next release.

Love you, you are a hero

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants