Browse Source

Skip set(obj.keys()) allocation in jsonable_encoder when include/exclude are not set

pull/15476/head
Vittoria 1 month ago
committed by Vittoria Lanzo
parent
commit
e9cdebb73e
  1. 14
      fastapi/encoders.py
  2. 38
      tests/test_jsonable_encoder.py

14
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,

38
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

Loading…
Cancel
Save