diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 43f24101b6..329f96ace2 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -280,11 +280,13 @@ def jsonable_encoder( return None if isinstance(obj, dict): encoded_dict = {} - allowed_keys = set(obj.keys()) - if include is not None: - allowed_keys &= set(include) - if exclude is not None: - allowed_keys -= set(exclude) + allowed_keys: set[Any] | None = None + if include is not None or exclude is not None: + allowed_keys = set(obj.keys()) + if include is not None: + allowed_keys &= set(include) + if exclude is not None: + allowed_keys -= set(exclude) for key, value in obj.items(): if ( ( @@ -293,7 +295,7 @@ def jsonable_encoder( or (not key.startswith("_sa")) ) and (value is not None or not exclude_none) - and key in allowed_keys + and (allowed_keys is None or key in allowed_keys) ): encoded_key = jsonable_encoder( key, diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index c23a9e5d79..dde6fe3f8e 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -329,3 +329,41 @@ def test_encode_color(module_path): data = {"color": Color("blue")} assert jsonable_encoder(data) == {"color": "blue"} + + +def test_dict_no_filter_returns_all_keys(): + result = jsonable_encoder({"a": 1, "b": 2, "c": 3}) + assert result == {"a": 1, "b": 2, "c": 3} + + +def test_dict_include_filters_correctly(): + result = jsonable_encoder({"a": 1, "b": 2}, include={"a"}) + assert result == {"a": 1} + + +def test_dict_exclude_filters_correctly(): + result = jsonable_encoder({"a": 1, "b": 2}, exclude={"b"}) + assert result == {"a": 1} + + +def test_dict_empty_include_returns_empty(): + result = jsonable_encoder({"a": 1}, include=set()) + assert result == {} + + +def test_dict_empty_exclude_returns_all(): + result = jsonable_encoder({"a": 1}, exclude=set()) + assert result == {"a": 1} + + +def test_dict_both_include_and_exclude(): + result = jsonable_encoder( + {"a": 1, "b": 2, "c": 3}, include={"a", "b"}, exclude={"b"} + ) + assert result == {"a": 1} + + +def test_encode_nested_dict(): + nested = {"level1": {"level2": {"level3": 42}}} + result = jsonable_encoder(nested) + assert result == nested