Skip to content

Commit 8ca8428

Browse files
committed
Improved Fragment logic and added more tests
1 parent 162dea3 commit 8ca8428

File tree

5 files changed

+638
-11
lines changed

5 files changed

+638
-11
lines changed

graphql/execution/querybuilder/fragment.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
from promise import promise_for_dict
2+
13
from functools import partial
24
from ...pyutils.cached_property import cached_property
35
from ..values import get_argument_values, get_variable_values
4-
from ..base import collect_fields, ResolveInfo
6+
from ..base import collect_fields, ResolveInfo, Undefined
7+
from ..executor import is_promise
8+
9+
from ...pyutils.ordereddict import OrderedDict
510
from ...pyutils.default_ordered_dict import DefaultOrderedDict
611

712

@@ -81,10 +86,28 @@ def partial_resolvers(self):
8186
)
8287

8388
def resolve(self, root):
84-
return {
85-
field_name: field_resolver(root, field_args, context, info)
86-
for field_name, field_resolver, field_args, context, info in self.partial_resolvers
87-
}
89+
contains_promise = False
90+
91+
final_results = OrderedDict()
92+
93+
for response_name, field_resolver, field_args, context, info in self.partial_resolvers:
94+
result = field_resolver(root, field_args, context, info)
95+
if result is Undefined:
96+
continue
97+
98+
if is_promise(result):
99+
contains_promise = True
100+
101+
final_results[response_name] = result
102+
103+
if not contains_promise:
104+
return final_results
105+
106+
return promise_for_dict(final_results)
107+
# return {
108+
# field_name: field_resolver(root, field_args, context, info)
109+
# for field_name, field_resolver, field_args, context, info in self.partial_resolvers
110+
# }
88111

89112
def __eq__(self, other):
90113
return isinstance(other, Fragment) and (

graphql/execution/querybuilder/tests/test_benchmark.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def test_querybuilder_big_list_of_objecttypes_with_one_int_field(benchmark):
9595
)
9696
])
9797
query_fragment = Fragment(type=Query, selection_set=selection_set)
98-
resolver = type_resolver(Query, lambda: None, fragment=query_fragment)
98+
resolver = type_resolver(Query, lambda: object(), fragment=query_fragment)
9999
resolved = benchmark(resolver)
100100
assert resolved == {
101101
'nodes': [{

graphql/execution/querybuilder/tests/test_executor.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,31 @@ def test_fragment_resolver_resolves_all_list():
139139
assert str(resolved.errors[0]) == 'Cannot return null for non-nullable field Query.persons.'
140140
# assert str(resolved.errors[0]) == 'could not convert string to float: non'
141141
assert resolved.data == {
142-
'persons': [{
143-
'id': 1
144-
}, {
145-
'id': 1
146-
}, None]
142+
'persons': None
143+
}
144+
145+
146+
def test_fragment_resolver_resolves_all_list_null():
147+
Person = GraphQLObjectType('Person', fields={
148+
'id': GraphQLField(GraphQLInt, resolver=lambda obj, *_, **__: 1),
149+
})
150+
Query = GraphQLObjectType('Query', fields={
151+
'persons': GraphQLField(GraphQLNonNull(GraphQLList(GraphQLNonNull(Person))), resolver=lambda *args: [1, 2, None]),
152+
})
153+
154+
document_ast = parse('''query {
155+
persons {
156+
id
157+
}
158+
}''')
159+
# node_fragment = Fragment(type=Node, field_asts=node_field_asts)
160+
schema = GraphQLSchema(query=Query, types=[Person])
161+
# partial_execute = partial(execute, schema, document_ast, context_value="1")
162+
# resolved = benchmark(partial_execute)
163+
resolved = execute(schema, document_ast)
164+
assert len(resolved.errors) == 1
165+
assert str(resolved.errors[0]) == 'Cannot return null for non-nullable field Query.persons.'
166+
# assert str(resolved.errors[0]) == 'could not convert string to float: non'
167+
assert resolved.data == {
168+
'persons': None
147169
}

0 commit comments

Comments
 (0)