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

union_mode='smart' not honored when calling model_dump_json() #9417

Open
1 task done
mducar opened this issue May 8, 2024 · 2 comments
Open
1 task done

union_mode='smart' not honored when calling model_dump_json() #9417

mducar opened this issue May 8, 2024 · 2 comments
Labels
bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation
Milestone

Comments

@mducar
Copy link

mducar commented May 8, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Running the example code below results int the following output:

float then int: 100 <class `'int'>`
{"value":100.0}
int then float: 100 <class 'int'>
{"value":100}

As you can see, even though the object instance stores value=100 as an int in both classes, FloatThenInt promotes it to a float 100.0 when converting to JSON.

Example Code

from pydantic import BaseModel, Field
from typing import Union


class FloatThenInt(BaseModel):
    value: Union[float, int, str] = Field(union_mode='smart')


class IntThenFloat(BaseModel):
    value: Union[int, float, str] = Field(union_mode='smart')


float_then_int = FloatThenInt(value=100)
print(f'float then int: {float_then_int.value} {type(float_then_int.value)}')
print(float_then_int.model_dump_json())

int_then_float = IntThenFloat(value=100)
print(f'int then float: {int_then_float.value} {type(int_then_float.value)}')
print(int_then_float.model_dump_json())

Python, Pydantic & OS Version

$ python -c "import pydantic.version; print(pydantic.version.version_info())"
             pydantic version: 2.7.1
        pydantic-core version: 2.18.2
          pydantic-core build: profile=release pgo=false
                 install path: /Users/mducar/.venv/shared_python3/lib/python3.9/site-packages/pydantic
               python version: 3.9.6 (default, Feb  3 2024, 15:58:27)  [Clang 15.0.0 (clang-1500.3.9.4)]
                     platform: macOS-14.3-arm64-arm-64bit
             related packages: typing_extensions-4.9.0
                       commit: unknown
@mducar mducar added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels May 8, 2024
@henrybetts
Copy link

I believe I've come across the same issue, but using strict types;

from pydantic import TypeAdapter, StrictStr, StrictFloat, StrictInt, StrictBool
from typing import Union

AttributeType = Union[StrictStr, StrictFloat, StrictInt, StrictBool, None]

TypeAdapter(AttributeType).dump_json('string')  # '"string"' ✅
TypeAdapter(AttributeType).dump_json(1.0)  # '1.0' ✅
TypeAdapter(AttributeType).dump_json(1)  # '1.0' ❌
TypeAdapter(AttributeType).dump_json(True)  # '1.0' ❌
TypeAdapter(AttributeType).dump_json(None)  # 'null' ✅

Seems to just be the StrictFloat type that isn't actually behaving strictly.

@sydney-runkle
Copy link
Member

Hey @mducar @henrybetts,

Thanks for reporting this. Definitely something to be improved. Adding to the union issues milestone!

@sydney-runkle sydney-runkle added this to the Union Issues milestone May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation
Projects
None yet
Development

No branches or pull requests

3 participants