Skip to content

Commit 1657733

Browse files
committed
Suppress records for deferred fragments that are completely empty
Replicates graphql/graphql-js@2e29180
1 parent f498569 commit 1657733

File tree

3 files changed

+27
-113
lines changed

3 files changed

+27
-113
lines changed

src/graphql/execution/incremental_publisher.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,10 @@ def _publish(self, subsequent_result_record: SubsequentResultRecord) -> None:
10981098
self._introduce(subsequent_result_record)
10991099
elif subsequent_result_record._pending: # noqa: SLF001
11001100
self._introduce(subsequent_result_record)
1101-
else:
1101+
elif (
1102+
subsequent_result_record.deferred_grouped_field_set_records
1103+
or subsequent_result_record.children
1104+
):
11021105
self._push(subsequent_result_record)
11031106

11041107
@staticmethod

tests/execution/test_defer.py

Lines changed: 19 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -786,14 +786,7 @@ async def can_defer_a_fragment_that_is_also_not_deferred_with_deferred_first():
786786
)
787787
result = await complete(document)
788788

789-
assert result == [
790-
{
791-
"data": {"hero": {"name": "Luke"}},
792-
"pending": [{"id": "0", "path": ["hero"], "label": "DeferTop"}],
793-
"hasNext": True,
794-
},
795-
{"completed": [{"id": "0"}], "hasNext": False},
796-
]
789+
assert result == {"data": {"hero": {"name": "Luke"}}}
797790

798791
@pytest.mark.asyncio
799792
async def can_defer_a_fragment_that_is_also_not_deferred_with_non_deferred_first():
@@ -812,14 +805,7 @@ async def can_defer_a_fragment_that_is_also_not_deferred_with_non_deferred_first
812805
)
813806
result = await complete(document)
814807

815-
assert result == [
816-
{
817-
"data": {"hero": {"name": "Luke"}},
818-
"pending": [{"id": "0", "path": ["hero"], "label": "DeferTop"}],
819-
"hasNext": True,
820-
},
821-
{"completed": [{"id": "0"}], "hasNext": False},
822-
]
808+
assert result == {"data": {"hero": {"name": "Luke"}}}
823809

824810
@pytest.mark.asyncio
825811
async def can_defer_an_inline_fragment():
@@ -868,14 +854,7 @@ async def does_not_emit_empty_defer_fragments():
868854
)
869855
result = await complete(document)
870856

871-
assert result == [
872-
{
873-
"data": {"hero": {}},
874-
"pending": [{"id": "0", "path": ["hero"]}],
875-
"hasNext": True,
876-
},
877-
{"completed": [{"id": "0"}], "hasNext": False},
878-
]
857+
assert result == {"data": {"hero": {}}}
879858

880859
@pytest.mark.asyncio
881860
async def separately_emits_defer_fragments_different_labels_varying_fields():
@@ -1118,40 +1097,18 @@ async def can_deduplicate_multiple_defers_on_the_same_object():
11181097
"data": {"hero": {"friends": [{}, {}, {}]}},
11191098
"pending": [
11201099
{"id": "0", "path": ["hero", "friends", 0]},
1121-
{"id": "1", "path": ["hero", "friends", 0]},
1122-
{"id": "2", "path": ["hero", "friends", 0]},
1123-
{"id": "3", "path": ["hero", "friends", 0]},
1124-
{"id": "4", "path": ["hero", "friends", 1]},
1125-
{"id": "5", "path": ["hero", "friends", 1]},
1126-
{"id": "6", "path": ["hero", "friends", 1]},
1127-
{"id": "7", "path": ["hero", "friends", 1]},
1128-
{"id": "8", "path": ["hero", "friends", 2]},
1129-
{"id": "9", "path": ["hero", "friends", 2]},
1130-
{"id": "10", "path": ["hero", "friends", 2]},
1131-
{"id": "11", "path": ["hero", "friends", 2]},
1100+
{"id": "1", "path": ["hero", "friends", 1]},
1101+
{"id": "2", "path": ["hero", "friends", 2]},
11321102
],
11331103
"hasNext": True,
11341104
},
11351105
{
11361106
"incremental": [
11371107
{"data": {"id": "2", "name": "Han"}, "id": "0"},
1138-
{"data": {"id": "3", "name": "Leia"}, "id": "4"},
1139-
{"data": {"id": "4", "name": "C-3PO"}, "id": "8"},
1140-
],
1141-
"completed": [
1142-
{"id": "1"},
1143-
{"id": "2"},
1144-
{"id": "3"},
1145-
{"id": "5"},
1146-
{"id": "6"},
1147-
{"id": "7"},
1148-
{"id": "9"},
1149-
{"id": "10"},
1150-
{"id": "11"},
1151-
{"id": "0"},
1152-
{"id": "4"},
1153-
{"id": "8"},
1108+
{"data": {"id": "3", "name": "Leia"}, "id": "1"},
1109+
{"data": {"id": "4", "name": "C-3PO"}, "id": "2"},
11541110
],
1111+
"completed": [{"id": "0"}, {"id": "1"}, {"id": "2"}],
11551112
"hasNext": False,
11561113
},
11571114
]
@@ -1767,22 +1724,13 @@ async def deduplicates_list_fields():
17671724

17681725
result = await complete(document)
17691726

1770-
assert result == [
1771-
{
1772-
"data": {
1773-
"hero": {
1774-
"friends": [
1775-
{"name": "Han"},
1776-
{"name": "Leia"},
1777-
{"name": "C-3PO"},
1778-
]
1779-
}
1780-
},
1781-
"pending": [{"id": "0", "path": ["hero"]}],
1782-
"hasNext": True,
1727+
assert result == {
1728+
"data": {
1729+
"hero": {
1730+
"friends": [{"name": "Han"}, {"name": "Leia"}, {"name": "C-3PO"}]
1731+
}
17831732
},
1784-
{"completed": [{"id": "0"}], "hasNext": False},
1785-
]
1733+
}
17861734

17871735
async def deduplicates_async_iterable_list_fields():
17881736
document = parse(
@@ -1806,14 +1754,7 @@ async def deduplicates_async_iterable_list_fields():
18061754
document, {"hero": {**hero, "friends": Resolvers.first_friend}}
18071755
)
18081756

1809-
assert result == [
1810-
{
1811-
"data": {"hero": {"friends": [{"name": "Han"}]}},
1812-
"pending": [{"id": "0", "path": ["hero"]}],
1813-
"hasNext": True,
1814-
},
1815-
{"completed": [{"id": "0"}], "hasNext": False},
1816-
]
1757+
assert result == {"data": {"hero": {"friends": [{"name": "Han"}]}}}
18171758

18181759
async def deduplicates_empty_async_iterable_list_fields():
18191760
document = parse(
@@ -1842,14 +1783,7 @@ async def resolve_friends(_info):
18421783
document, {"hero": {**hero, "friends": resolve_friends}}
18431784
)
18441785

1845-
assert result == [
1846-
{
1847-
"data": {"hero": {"friends": []}},
1848-
"pending": [{"id": "0", "path": ["hero"]}],
1849-
"hasNext": True,
1850-
},
1851-
{"completed": [{"id": "0"}], "hasNext": False},
1852-
]
1786+
assert result == {"data": {"hero": {"friends": []}}}
18531787

18541788
async def does_not_deduplicate_list_fields_with_non_overlapping_fields():
18551789
document = parse(
@@ -1916,14 +1850,7 @@ async def deduplicates_list_fields_that_return_empty_lists():
19161850
document, {"hero": {**hero, "friends": lambda _info: []}}
19171851
)
19181852

1919-
assert result == [
1920-
{
1921-
"data": {"hero": {"friends": []}},
1922-
"pending": [{"id": "0", "path": ["hero"]}],
1923-
"hasNext": True,
1924-
},
1925-
{"completed": [{"id": "0"}], "hasNext": False},
1926-
]
1853+
assert result == {"data": {"hero": {"friends": []}}}
19271854

19281855
async def deduplicates_null_object_fields():
19291856
document = parse(
@@ -1946,14 +1873,7 @@ async def deduplicates_null_object_fields():
19461873
document, {"hero": {**hero, "nestedObject": lambda _info: None}}
19471874
)
19481875

1949-
assert result == [
1950-
{
1951-
"data": {"hero": {"nestedObject": None}},
1952-
"pending": [{"id": "0", "path": ["hero"]}],
1953-
"hasNext": True,
1954-
},
1955-
{"completed": [{"id": "0"}], "hasNext": False},
1956-
]
1876+
assert result == {"data": {"hero": {"nestedObject": None}}}
19571877

19581878
async def deduplicates_async_object_fields():
19591879
document = parse(
@@ -1980,14 +1900,7 @@ async def resolve_nested_object(_info):
19801900
document, {"hero": {"nestedObject": resolve_nested_object}}
19811901
)
19821902

1983-
assert result == [
1984-
{
1985-
"data": {"hero": {"nestedObject": {"name": "foo"}}},
1986-
"pending": [{"id": "0", "path": ["hero"]}],
1987-
"hasNext": True,
1988-
},
1989-
{"completed": [{"id": "0"}], "hasNext": False},
1990-
]
1903+
assert result == {"data": {"hero": {"nestedObject": {"name": "foo"}}}}
19911904

19921905
@pytest.mark.asyncio
19931906
async def handles_errors_thrown_in_deferred_fragments():

tests/execution/test_stream.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,21 +1854,19 @@ async def get_nested_friend_list(_info):
18541854
{
18551855
"data": {"nestedObject": {"nestedFriendList": []}},
18561856
"pending": [
1857-
{"id": "0", "path": ["nestedObject"]},
1858-
{"id": "1", "path": ["nestedObject", "nestedFriendList"]},
1857+
{"id": "0", "path": ["nestedObject", "nestedFriendList"]},
18591858
],
18601859
"hasNext": True,
18611860
},
18621861
{
1863-
"incremental": [{"items": [{"id": "1", "name": "Luke"}], "id": "1"}],
1864-
"completed": [{"id": "0"}],
1862+
"incremental": [{"items": [{"id": "1", "name": "Luke"}], "id": "0"}],
18651863
"hasNext": True,
18661864
},
18671865
{
1868-
"incremental": [{"items": [{"id": "2", "name": "Han"}], "id": "1"}],
1866+
"incremental": [{"items": [{"id": "2", "name": "Han"}], "id": "0"}],
18691867
"hasNext": True,
18701868
},
1871-
{"completed": [{"id": "1"}], "hasNext": False},
1869+
{"completed": [{"id": "0"}], "hasNext": False},
18721870
]
18731871

18741872
@pytest.mark.asyncio

0 commit comments

Comments
 (0)