Skip to content

Commit cba6b50

Browse files
committed
Make get_argument/variable_values algorithm linear
Replicates graphql/graphql-js@38cee97
1 parent 97be979 commit cba6b50

File tree

1 file changed

+85
-80
lines changed

1 file changed

+85
-80
lines changed

src/graphql/execution/values.py

Lines changed: 85 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from ..error import GraphQLError, INVALID
44
from ..language import (
5-
ArgumentNode,
65
DirectiveNode,
76
ExecutableDefinitionNode,
87
FieldNode,
@@ -53,49 +52,59 @@ def get_variable_values(
5352
if not is_input_type(var_type):
5453
# Must use input types for variables. This should be caught during
5554
# validation, however is checked again here for safety.
55+
var_type_str = print_ast(var_def_node.type)
5656
errors.append(
5757
GraphQLError(
58-
f"Variable '${var_name}' expected value of type"
59-
f" '{print_ast(var_def_node.type)}'"
58+
f"Variable '${var_name}' expected value of type '{var_type_str}'"
6059
" which cannot be used as an input type.",
6160
var_def_node.type,
6261
)
6362
)
64-
else:
65-
var_type = cast(GraphQLInputType, var_type)
66-
has_value = var_name in inputs
67-
value = inputs[var_name] if has_value else INVALID
68-
if not has_value and var_def_node.default_value:
69-
# If no value was provided to a variable with a default value, use the
70-
# default value.
63+
continue
64+
65+
var_type = cast(GraphQLInputType, var_type)
66+
if var_name not in inputs:
67+
if var_def_node.default_value:
7168
coerced_values[var_name] = value_from_ast(
7269
var_def_node.default_value, var_type
7370
)
74-
elif (not has_value or value is None) and is_non_null_type(var_type):
71+
72+
if is_non_null_type(var_type):
73+
var_type_str = inspect(var_type)
7574
errors.append(
7675
GraphQLError(
77-
f"Variable '${var_name}' of non-null type"
78-
f" '{var_type}' must not be null."
79-
if has_value
80-
else f"Variable '${var_name}' of required type"
81-
f" '{var_type}' was not provided.",
76+
f"Variable '${var_name}' of required type '{var_type_str}'"
77+
" was not provided.",
8278
var_def_node,
8379
)
8480
)
85-
elif has_value:
86-
# Otherwise, a non-null value was provided, coerce it to the expected
87-
# type or report an error if coercion fails.
88-
coerced = coerce_value(value, var_type, var_def_node)
89-
coercion_errors = coerced.errors
90-
if coercion_errors:
91-
for error in coercion_errors:
92-
error.message = (
93-
f"Variable '${var_name}' got invalid"
94-
f" value {inspect(value)}; {error.message}"
95-
)
96-
errors.extend(coercion_errors)
97-
else:
98-
coerced_values[var_name] = coerced.value
81+
continue
82+
83+
value = inputs[var_name]
84+
if value is None and is_non_null_type(var_type):
85+
var_type_str = inspect(var_type)
86+
errors.append(
87+
GraphQLError(
88+
f"Variable '${var_name}' of non-null type '{var_type_str}'"
89+
" must not be null.",
90+
var_def_node,
91+
)
92+
)
93+
continue
94+
95+
coerced = coerce_value(value, var_type, var_def_node)
96+
coercion_errors = coerced.errors
97+
if coercion_errors:
98+
for error in coercion_errors:
99+
error.message = (
100+
f"Variable '${var_name}' got invalid"
101+
f" value {inspect(value)}; {error.message}"
102+
)
103+
errors.extend(coercion_errors)
104+
continue
105+
106+
coerced_values[var_name] = coerced.value
107+
99108
return (
100109
CoercedVariableValues(errors, None)
101110
if errors
@@ -114,62 +123,58 @@ def get_argument_values(
114123
of argument AST nodes.
115124
"""
116125
coerced_values: Dict[str, Any] = {}
117-
arg_nodes = node.arguments
118-
if arg_nodes is None:
119-
return coerced_values
120-
arg_defs = type_def.args
121-
arg_node_map = {arg.name.value: arg for arg in arg_nodes}
122-
for name, arg_def in arg_defs.items():
126+
arg_node_map = {arg.name.value: arg for arg in node.arguments or []}
127+
128+
for name, arg_def in type_def.args.items():
123129
arg_type = arg_def.type
124-
argument_node = cast(ArgumentNode, arg_node_map.get(name))
125-
variable_values = cast(Dict[str, Any], variable_values)
126-
if argument_node and isinstance(argument_node.value, VariableNode):
127-
variable_name = argument_node.value.name.value
128-
has_value = variable_values and variable_name in variable_values
129-
is_null = has_value and variable_values[variable_name] is None
130-
else:
131-
has_value = argument_node is not None
132-
is_null = has_value and isinstance(argument_node.value, NullValueNode)
133-
if not has_value and arg_def.default_value is not INVALID:
134-
# If no argument was provided where the definition has a default value,
135-
# use the default value.
136-
# If an out name exists, we use that as the name (extension of GraphQL.js).
137-
coerced_values[arg_def.out_name or name] = arg_def.default_value
138-
elif (not has_value or is_null) and is_non_null_type(arg_type):
139-
# If no argument or a null value was provided to an argument with a non-null
140-
# type (required), produce a field error.
141-
if is_null:
142-
raise GraphQLError(
143-
f"Argument '{name}' of non-null type"
144-
f" '{arg_type}' must not be null.",
145-
argument_node.value,
146-
)
147-
elif argument_node and isinstance(argument_node.value, VariableNode):
148-
raise GraphQLError(
149-
f"Argument '{name}' of required type"
150-
f" '{arg_type}' was provided the variable"
151-
f" '${variable_name}'"
152-
" which was not provided a runtime value.",
153-
argument_node.value,
154-
)
155-
else:
130+
argument_node = arg_node_map.get(name)
131+
132+
if argument_node is None:
133+
if arg_def.default_value is not INVALID:
134+
coerced_values[arg_def.out_name or name] = arg_def.default_value
135+
elif is_non_null_type(arg_type):
156136
raise GraphQLError(
157137
f"Argument '{name}' of required type '{arg_type}'"
158138
" was not provided.",
159139
node,
160140
)
161-
elif has_value:
162-
value_node = argument_node.value
163-
coerced_value = value_from_ast(value_node, arg_type, variable_values)
164-
if coerced_value is INVALID:
165-
# Note: `values_of_correct_type` validation should catch this before
166-
# execution. This is a runtime check to ensure execution does not
167-
# continue with an invalid argument value.
168-
raise GraphQLError(
169-
f"Argument '{name}'" f" has invalid value {print_ast(value_node)}.",
170-
argument_node.value,
171-
)
172-
coerced_values[arg_def.out_name or name] = coerced_value
141+
continue
142+
143+
value_node = argument_node.value
144+
is_null = isinstance(argument_node.value, NullValueNode)
145+
146+
if isinstance(value_node, VariableNode):
147+
variable_name = value_node.name.value
148+
if variable_values is None or variable_name not in variable_values:
149+
if arg_def.default_value is not INVALID:
150+
coerced_values[arg_def.out_name or name] = arg_def.default_value
151+
elif is_non_null_type(arg_type):
152+
raise GraphQLError(
153+
f"Argument '{name}' of required type '{arg_type}'"
154+
f" was provided the variable '${variable_name}'"
155+
" which was not provided a runtime value.",
156+
value_node,
157+
)
158+
continue
159+
is_null = variable_values[variable_name] is None
160+
161+
if is_null and is_non_null_type(arg_type):
162+
raise GraphQLError(
163+
f"Argument '{name}' of non-null type '{arg_type}' must not be null.",
164+
value_node,
165+
)
166+
167+
coerced_value = value_from_ast(value_node, arg_type, variable_values)
168+
if coerced_value is INVALID:
169+
# Note: `values_of_correct_type` validation should catch this before
170+
# execution. This is a runtime check to ensure execution does not
171+
# continue with an invalid argument value.
172+
raise GraphQLError(
173+
f"Argument '{name}' has invalid value {print_ast(value_node)}.",
174+
value_node,
175+
)
176+
coerced_values[arg_def.out_name or name] = coerced_value
177+
173178
return coerced_values
174179

175180

0 commit comments

Comments
 (0)