Skip to content

Commit 651ca5c

Browse files
committed
Transform input objects used as default values (#206)
1 parent d4f8b32 commit 651ca5c

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

src/graphql/execution/values.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
GraphQLDirective,
2727
GraphQLField,
2828
GraphQLSchema,
29+
is_input_object_type,
2930
is_input_type,
3031
is_non_null_type,
3132
)
@@ -171,8 +172,12 @@ def get_argument_values(
171172
argument_node = arg_node_map.get(name)
172173

173174
if argument_node is None:
174-
if arg_def.default_value is not Undefined:
175-
coerced_values[arg_def.out_name or name] = arg_def.default_value
175+
value = arg_def.default_value
176+
if value is not Undefined:
177+
if is_input_object_type(arg_def.type):
178+
# coerce input value so that out_names are used
179+
value = coerce_input_value(value, arg_def.type)
180+
coerced_values[arg_def.out_name or name] = value
176181
elif is_non_null_type(arg_type): # pragma: no cover else
177182
msg = (
178183
f"Argument '{name}' of required type '{arg_type}' was not provided."
@@ -186,8 +191,12 @@ def get_argument_values(
186191
if isinstance(value_node, VariableNode):
187192
variable_name = value_node.name.value
188193
if variable_values is None or variable_name not in variable_values:
189-
if arg_def.default_value is not Undefined:
190-
coerced_values[arg_def.out_name or name] = arg_def.default_value
194+
value = arg_def.default_value
195+
if value is not Undefined:
196+
if is_input_object_type(arg_def.type):
197+
# coerce input value so that out_names are used
198+
value = coerce_input_value(value, arg_def.type)
199+
coerced_values[arg_def.out_name or name] = value
191200
elif is_non_null_type(arg_type): # pragma: no cover else
192201
msg = (
193202
f"Argument '{name}' of required type '{arg_type}'"

tests/execution/test_resolve.py

+87
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
from graphql.type import (
88
GraphQLArgument,
99
GraphQLField,
10+
GraphQLID,
1011
GraphQLInputField,
1112
GraphQLInputObjectType,
1213
GraphQLInt,
14+
GraphQLList,
1315
GraphQLObjectType,
1416
GraphQLSchema,
1517
GraphQLString,
@@ -213,6 +215,91 @@ def execute_query(query: str, root_value: Any = None) -> ExecutionResult:
213215
None,
214216
)
215217

218+
def transforms_default_values_using_out_names():
219+
# This is an extension of GraphQL.js.
220+
resolver_kwargs: Any
221+
222+
def search_resolver(_obj: None, _info, **kwargs):
223+
nonlocal resolver_kwargs
224+
resolver_kwargs = kwargs
225+
return [{"id": "42"}]
226+
227+
filters_type = GraphQLInputObjectType(
228+
"SearchFilters",
229+
{"pageSize": GraphQLInputField(GraphQLInt, out_name="page_size")},
230+
)
231+
result_type = GraphQLObjectType("SearchResult", {"id": GraphQLField(GraphQLID)})
232+
query = GraphQLObjectType(
233+
"Query",
234+
{
235+
"search": GraphQLField(
236+
GraphQLList(result_type),
237+
{
238+
"searchFilters": GraphQLArgument(
239+
filters_type, {"pageSize": 10}, out_name="search_filters"
240+
)
241+
},
242+
resolve=search_resolver,
243+
)
244+
},
245+
)
246+
schema = GraphQLSchema(query)
247+
248+
resolver_kwargs = None
249+
result = execute_sync(schema, parse("{ search { id } }"))
250+
assert result == ({"search": [{"id": "42"}]}, None)
251+
assert resolver_kwargs == {"search_filters": {"page_size": 10}}
252+
253+
resolver_kwargs = None
254+
result = execute_sync(
255+
schema, parse("{ search(searchFilters:{pageSize: 25}) { id } }")
256+
)
257+
assert result == ({"search": [{"id": "42"}]}, None)
258+
assert resolver_kwargs == {"search_filters": {"page_size": 25}}
259+
260+
resolver_kwargs = None
261+
result = execute_sync(
262+
schema,
263+
parse(
264+
"""
265+
query ($searchFilters: SearchFilters) {
266+
search(searchFilters: $searchFilters) { id }
267+
}
268+
"""
269+
),
270+
)
271+
assert result == ({"search": [{"id": "42"}]}, None)
272+
assert resolver_kwargs == {"search_filters": {"page_size": 10}}
273+
274+
resolver_kwargs = None
275+
result = execute_sync(
276+
schema,
277+
parse(
278+
"""
279+
query ($searchFilters: SearchFilters) {
280+
search(searchFilters: $searchFilters) { id }
281+
}
282+
"""
283+
),
284+
variable_values={"searchFilters": {"pageSize": 25}},
285+
)
286+
assert result == ({"search": [{"id": "42"}]}, None)
287+
assert resolver_kwargs == {"search_filters": {"page_size": 25}}
288+
289+
resolver_kwargs = None
290+
result = execute_sync(
291+
schema,
292+
parse(
293+
"""
294+
query ($searchFilters: SearchFilters = {pageSize: 25}) {
295+
search(searchFilters: $searchFilters) { id }
296+
}
297+
"""
298+
),
299+
)
300+
assert result == ({"search": [{"id": "42"}]}, None)
301+
assert resolver_kwargs == {"search_filters": {"page_size": 25}}
302+
216303
def pass_error_from_resolver_wrapped_as_located_graphql_error():
217304
def resolve(_obj, _info):
218305
raise ValueError("Some error")

0 commit comments

Comments
 (0)