Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions fastapi/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ def isoformat(o: Union[datetime.date, datetime.time]) -> str:
return o.isoformat()


# Taken from Pydantic v1 as is
# Adapted from Pydantic v1
# TODO: pv2 should this return strings instead?
def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
"""
Encodes a Decimal as int of there's no exponent, otherwise float
Encodes a Decimal as int if there's no exponent, otherwise float

This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
where a integer (but not int typed) is used. Encoding this as a float
where an integer (but not int typed) is used. Encoding this as a float
results in failed round-tripping between encode and parse.
Our Id type is a prime example of this.

Expand All @@ -48,8 +48,12 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]:

>>> decimal_encoder(Decimal("1"))
1

>>> decimal_encoder(Decimal("NaN"))
nan
Comment thread
kentwelcome marked this conversation as resolved.
"""
if dec_value.as_tuple().exponent >= 0: # type: ignore[operator]
exponent = dec_value.as_tuple().exponent
if isinstance(exponent, int) and exponent >= 0:
return int(dec_value)
else:
return float(dec_value)
Expand Down
15 changes: 15 additions & 0 deletions tests/test_jsonable_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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

Expand Down Expand Up @@ -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
Expand Down