From 3f3f98d196316577365127d78eae90b426f03eaf Mon Sep 17 00:00:00 2001 From: Pedro Lobato <69770518+Lob26@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:20:11 -0500 Subject: [PATCH] More tests for coverage --- fastapi/encoders.py | 11 +++++------ tests/test_jsonable_encoder.py | 27 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 66ab01b14..f9e309e31 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -38,10 +38,7 @@ try: from pydantic_extra_types import coordinate encoders_by_extra_type: dict[type[Any], Callable[[Any], Any]] = { - coordinate.Coordinate: lambda o: { - "latitude": o.latitude, - "longitude": o.longitude, - }, + coordinate.Coordinate: str, et_color.Color: str, } except ImportError: @@ -273,6 +270,10 @@ def jsonable_encoder( exclude_defaults=exclude_defaults, sqlalchemy_safe=sqlalchemy_safe, ) + # The extra types have their own encoders, so we check for them before checking for dataclasses, + # because some of them are also dataclasses, and we want to use their custom encoders instead of encoding them as dataclasses. + if type(obj) in encoders_by_extra_type: + return encoders_by_extra_type[type(obj)](obj) if dataclasses.is_dataclass(obj): assert not isinstance(obj, type) obj_dict = dataclasses.asdict(obj) @@ -369,8 +370,6 @@ def jsonable_encoder( ) return encoded_list - if type(obj) in encoders_by_extra_type: - return encoders_by_extra_type[type(obj)](obj) if type(obj) in ENCODERS_BY_TYPE: return ENCODERS_BY_TYPE[type(obj)](obj) for encoder, classes_tuple in encoders_by_class_tuples.items(): diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index 564b5d81d..5b65758c4 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -1,3 +1,4 @@ +import sys import warnings from collections import deque, namedtuple from collections.abc import Sequence @@ -423,5 +424,27 @@ def test_encode_sqlalchemy_row_as_dict(): def test_encode_pydantic_extra_types_coordinate(): coordinate = pytest.importorskip("pydantic_extra_types.coordinate") coord = coordinate.Coordinate(latitude=1.0, longitude=2.0) - assert jsonable_encoder(coord) != str(coord) - assert jsonable_encoder(coord) == {"latitude": 1.0, "longitude": 2.0} + # Dataclass output shouldn't be the result + assert jsonable_encoder(coord) != {"latitude": 1.0, "longitude": 2.0} + # The custom encoder should be the result + assert jsonable_encoder(coord) == str(coord) + + +@pytest.mark.skipif( + sys.version_info > (3, 9), + reason="Tested via pydantic_extra_types on Python > 3.9", +) +def test_encode_pydantic_color(): + pydantic_color = pytest.importorskip("pydantic.color") + color = pydantic_color.Color("red") + assert jsonable_encoder(color) == str(color) + + +@pytest.mark.skipif( + sys.version_info <= (3, 9), + reason="pydantic_extra_types.color not available on Python <= 3.9", +) +def test_encode_pydantic_extra_types_color(): + et_color = pytest.importorskip("pydantic_extra_types.color") + color = et_color.Color("red") + assert jsonable_encoder(color) == str(color)