python-3.xpydantic

Pydantic Model Field Of Type Union[int, float] : How To Prevent Field From Rounding To int When Initialised With float Value?


I have the following pydantic model which contains a result typed as Union[int,float] as listed below.

from typing import Union

from pydantic import BaseModel


class Calculation(BaseModel):
    arg1: int 
    arg2: int 


class CalculationResult(Calculation):
    op: str 
    result: Union[int, float]


if __name__ == "__main__":

    arg1 = 1 
    arg2 = 2 
    result = arg1 / arg2

    # this displays type of result := <class 'float'> when program is run
    print(f"type of result := {type(result)}")

    x = CalculationResult(**{"arg1": arg1, "arg2": arg2, "op": "divide", "result": result}) 

    print(f"result := {x.result}")

When the result property of CalculationResult has a value of 0.5 it is rounded to 0.

How do I get pydantic to recognise that 0.5 is a float for the typing hint Union[int, float]?


Solution

  • Modifying the order as mention in @anon_dcs3spp's answer may not be ideal as Union[float, int] would lead to all integers being coerced to floats.

    Pydantic added support for smart_union recently which prevents the type-coercion and preserves original types.

    So something like below, should work!

    class CalculationResult(Calculation): op: str result: Union[int, float]

    class CalculationResult(Calculation):
        op: str 
        result: Union[int, float]
    
        class Config:
           smart_union = True