Browse Source

🐛 Fix jsonable_encoder not encoding Enum values that are not JSON-serializable

pull/15918/head
serverestaa 3 weeks ago
parent
commit
f3c2a32628
  1. 6
      fastapi/encoders.py
  2. 27
      tests/test_jsonable_encoder.py

6
fastapi/encoders.py

@ -271,7 +271,11 @@ def jsonable_encoder(
sqlalchemy_safe=sqlalchemy_safe, sqlalchemy_safe=sqlalchemy_safe,
) )
if isinstance(obj, Enum): if isinstance(obj, Enum):
return obj.value return jsonable_encoder(
obj.value,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
if isinstance(obj, PurePath): if isinstance(obj, PurePath):
return str(obj) return str(obj)
if isinstance(obj, (str, int, float, type(None))): if isinstance(obj, (str, int, float, type(None))):

27
tests/test_jsonable_encoder.py

@ -1,7 +1,7 @@
import warnings import warnings
from collections import deque from collections import deque
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timezone from datetime import date, datetime, timezone
from decimal import Decimal from decimal import Decimal
from enum import Enum from enum import Enum
from math import isinf, isnan from math import isinf, isnan
@ -240,6 +240,31 @@ def test_custom_enum_encoders():
assert encoded_instance == custom_enum_encoder(instance) assert encoded_instance == custom_enum_encoder(instance)
def test_encode_enum_with_non_primitive_values():
class DateEnum(Enum):
release = date(2024, 1, 1)
class DecimalEnum(Enum):
half = Decimal("0.5")
class BytesEnum(Enum):
data = b"data"
assert jsonable_encoder(DateEnum.release) == "2024-01-01"
assert jsonable_encoder(DecimalEnum.half) == 0.5
assert jsonable_encoder(BytesEnum.data) == "data"
def test_encode_enum_value_with_custom_encoder():
class DateEnum(Enum):
release = date(2024, 1, 1)
encoded_instance = jsonable_encoder(
DateEnum.release, custom_encoder={date: lambda o: o.strftime("%d/%m/%Y")}
)
assert encoded_instance == "01/01/2024"
def test_encode_model_with_pure_path(): def test_encode_model_with_pure_path():
class ModelWithPath(BaseModel): class ModelWithPath(BaseModel):
path: PurePath path: PurePath

Loading…
Cancel
Save