From c02c16b0cba21a02d1bd8f6d28cd66c5aa76e4fa Mon Sep 17 00:00:00 2001 From: Kent Huang Date: Thu, 14 Nov 2024 18:59:47 +0800 Subject: [PATCH 1/2] [Fix] decimal_encoder function handle 'NaN' and 'Infinity' edge cases Signed-off-by: Kent Huang --- fastapi/encoders.py | 3 ++- tests/test_jsonable_encoder.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 451ea0760..075ca58fd 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -49,7 +49,8 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]: >>> decimal_encoder(Decimal("1")) 1 """ - if dec_value.as_tuple().exponent >= 0: # type: ignore[operator] + exponent = dec_value.as_tuple().exponent + if isinstance(exponent, int) and exponent >= 0: # type: ignore[operator] return int(dec_value) else: return float(dec_value) diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index 1906d6bf1..29fb90aeb 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -3,6 +3,7 @@ from dataclasses import dataclass from datetime import datetime, timezone from decimal import Decimal from enum import Enum +from math import isinf, isnan from pathlib import PurePath, PurePosixPath, PureWindowsPath from typing import Optional @@ -303,6 +304,20 @@ def test_decimal_encoder_int(): assert jsonable_encoder(data) == {"value": 2} +@needs_pydanticv2 +def test_decimal_encoder_nan(): + data = {"value": Decimal("NaN")} + assert isnan(jsonable_encoder(data)["value"]) + + +@needs_pydanticv2 +def test_decimal_encoder_infinity(): + data = {"value": Decimal("Infinity")} + assert isinf(jsonable_encoder(data)["value"]) + data = {"value": Decimal("-Infinity")} + assert isinf(jsonable_encoder(data)["value"]) + + def test_encode_deque_encodes_child_models(): class Model(BaseModel): test: str From 70037c9d56b629c1e50c77115d664d7779af3276 Mon Sep 17 00:00:00 2001 From: Kent Huang Date: Mon, 25 Nov 2024 19:03:20 +0800 Subject: [PATCH 2/2] [Fix] Lint issue remove unused type: ignore comment Signed-off-by: Kent Huang --- fastapi/encoders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 075ca58fd..814d900a1 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -50,7 +50,7 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]: 1 """ exponent = dec_value.as_tuple().exponent - if isinstance(exponent, int) and exponent >= 0: # type: ignore[operator] + if isinstance(exponent, int) and exponent >= 0: return int(dec_value) else: return float(dec_value)