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

Using Union with int/float casts to whichever appears first #190

Closed
ggydush opened this issue Jan 26, 2024 · 3 comments
Closed

Using Union with int/float casts to whichever appears first #190

ggydush opened this issue Jan 26, 2024 · 3 comments
Labels
question Just a question

Comments

@ggydush
Copy link

ggydush commented Jan 26, 2024

  • mashumaro version: 3.11
  • Python version: 3.11.5
  • Operating System: MacOS

Description

Using a dataclass with Union comprised of int/float causes the value to be cast to whichever appears first in the Union definition. Looking at the pack_union method, the output makes sense, but wondering if special cases should be added to preserve int/float types.

What I Did

from dataclasses import dataclass

from mashumaro.mixins.json import DataClassJSONMixin


@dataclass
class Example(DataClassJSONMixin):
    val1: float | int
    val2: int | float


print(Example(val1=3, val2=3.5).to_dict())

Output:

{'val1': 3.0, 'val2': 3}
@Fatal1ty
Copy link
Owner

Default converters for int and float types on serialization are int and float functions respectively. It has its roots in how Union types are currently processed. Imagine that you have Union[int, <another_dataclass>]. If int values were passing as is, then we would be passing <another_dataclass> values as is because "passing through" strategy appears first. I have plans to rework Union types and get rid of explicit converters for int, float types but before that you can use pass_through helper:

from dataclasses import dataclass

from mashumaro import pass_through
from mashumaro.config import BaseConfig
from mashumaro.mixins.json import DataClassJSONMixin


@dataclass
class Example(DataClassJSONMixin):
    val1: float | int
    val2: int | float

    class Config(BaseConfig):
        serialization_strategy = {
            int: {"serialize": pass_through},
            float: {"serialize": pass_through},
        }


print(Example(val1=3, val2=3.5).to_dict())

@ggydush
Copy link
Author

ggydush commented Jan 26, 2024

That makes total sense, and the Config overrides should work fine for my use case! Thanks for the prompt response and providing a solution!

@ggydush ggydush closed this as completed Jan 26, 2024
@Fatal1ty
Copy link
Owner

Fatal1ty commented Mar 1, 2024

@ggydush you might be interested in this pull request:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Just a question
Projects
None yet
Development

No branches or pull requests

2 participants