44from six import string_types
55
66from ..error import GraphQLError
7+ from ..language import ast
78from ..language .printer import print_ast
8- from ..type import (GraphQLEnumType , GraphQLInputObjectType , GraphQLList ,
9+ from ..type import (Undefined , GraphQLEnumType , GraphQLInputObjectType , GraphQLList ,
910 GraphQLNonNull , GraphQLScalarType , is_input_type )
1011from ..utils .is_valid_value import is_valid_value
1112from ..utils .type_from_ast import type_from_ast
@@ -23,8 +24,43 @@ def get_variable_values(schema, definition_asts, inputs):
2324 values = {}
2425 for def_ast in definition_asts :
2526 var_name = def_ast .variable .name .value
26- value = get_variable_value (schema , def_ast , inputs .get (var_name ))
27- values [var_name ] = value
27+ var_type = type_from_ast (schema , def_ast .type )
28+ value = inputs .get (var_name , Undefined )
29+
30+ if not is_input_type (var_type ):
31+ raise GraphQLError (
32+ 'Variable "${var_name}" expected value of type "{var_type}" which cannot be used as an input type.' .format (
33+ var_name = var_name ,
34+ var_type = print_ast (def_ast .type ),
35+ ),
36+ [def_ast ]
37+ )
38+ elif value is Undefined or value is None :
39+ if def_ast .default_value is not None :
40+ values [var_name ] = value_from_ast (def_ast .default_value , var_type )
41+ if isinstance (var_type , GraphQLNonNull ):
42+ raise GraphQLError (
43+ 'Variable "${var_name}" of required type "{var_type}" was not provided.' .format (
44+ var_name = var_name , var_type = var_type
45+ ), [def_ast ]
46+ )
47+ else :
48+ errors = is_valid_value (value , var_type )
49+ if errors :
50+ message = u'\n ' + u'\n ' .join (errors )
51+ raise GraphQLError (
52+ 'Variable "${}" got invalid value {}.{}' .format (
53+ var_name ,
54+ json .dumps (value , sort_keys = True ),
55+ message
56+ ),
57+ [def_ast ]
58+ )
59+ coerced_value = coerce_value (var_type , value )
60+ if coerced_value is Undefined :
61+ raise Exception ('Should have reported error.' )
62+
63+ values [var_name ] = coerced_value
2864
2965 return values
3066
@@ -42,72 +78,51 @@ def get_argument_values(arg_defs, arg_asts, variables=None):
4278
4379 result = {}
4480 for name , arg_def in arg_defs .items ():
45- value_ast = arg_ast_map .get (name )
81+ arg_type = arg_def .type
82+ value_ast = arg_ast_map .get (name , Undefined )
83+ if not value_ast :
84+ if arg_def .default_value is not Undefined :
85+ result [arg_def .out_name or name ] = arg_def .default_value
86+ continue
87+ elif isinstance (arg_type , GraphQLNonNull ):
88+ raise GraphQLError ('Argument "{name}" of required type {arg_type}" was not provided.' .format (
89+ name = name ,
90+ arg_type = arg_type
91+ ), arg_asts )
92+ elif isinstance (value_ast .value , ast .Variable ):
93+ variable_name = value_ast .value .name .value
94+ variable_value = variables .get (variable_name , Undefined )
95+ if variables and variable_value is not Undefined :
96+ result [arg_def .out_name or name ] = variable_value
97+ elif arg_def .default_value is not Undefined :
98+ result [arg_def .out_name or name ] = arg_def .default_value
99+ elif isinstance (arg_type , GraphQLNonNull ):
100+ raise GraphQLError ('Argument "{name}" of required type {arg_type}" provided the variable "${variable_name}" which was not provided' .format (
101+ name = name ,
102+ arg_type = arg_type ,
103+ variable_name = variable_name
104+ ), arg_asts )
105+ continue
106+
46107 if value_ast :
47108 value_ast = value_ast .value
48109
49110 value = value_from_ast (
50111 value_ast ,
51- arg_def . type ,
112+ arg_type ,
52113 variables
53114 )
54-
55- if value is None :
115+ if value is Undefined :
56116 value = arg_def .default_value
57117
58- if value is not None :
118+ if value is not Undefined :
59119 # We use out_name as the output name for the
60120 # dict if exists
61121 result [arg_def .out_name or name ] = value
62122
63123 return result
64124
65125
66- def get_variable_value (schema , definition_ast , input ):
67- """Given a variable definition, and any value of input, return a value which adheres to the variable definition,
68- or throw an error."""
69- type = type_from_ast (schema , definition_ast .type )
70- variable = definition_ast .variable
71-
72- if not type or not is_input_type (type ):
73- raise GraphQLError (
74- 'Variable "${}" expected value of type "{}" which cannot be used as an input type.' .format (
75- variable .name .value ,
76- print_ast (definition_ast .type ),
77- ),
78- [definition_ast ]
79- )
80-
81- input_type = type
82- errors = is_valid_value (input , input_type )
83- if not errors :
84- if input is None :
85- default_value = definition_ast .default_value
86- if default_value :
87- return value_from_ast (default_value , input_type )
88-
89- return coerce_value (input_type , input )
90-
91- if input is None :
92- raise GraphQLError (
93- 'Variable "${}" of required type "{}" was not provided.' .format (
94- variable .name .value ,
95- print_ast (definition_ast .type )
96- ),
97- [definition_ast ]
98- )
99-
100- message = (u'\n ' + u'\n ' .join (errors )) if errors else u''
101- raise GraphQLError (
102- 'Variable "${}" got invalid value {}.{}' .format (
103- variable .name .value ,
104- json .dumps (input , sort_keys = True ),
105- message
106- ),
107- [definition_ast ]
108- )
109-
110-
111126def coerce_value (type , value ):
112127 """Given a type and any value, return a runtime value coerced to match the type."""
113128 if isinstance (type , GraphQLNonNull ):
@@ -116,6 +131,9 @@ def coerce_value(type, value):
116131 # We only call this function after calling isValidValue.
117132 return coerce_value (type .of_type , value )
118133
134+ if value is Undefined :
135+ return Undefined
136+
119137 if value is None :
120138 return None
121139
@@ -130,11 +148,11 @@ def coerce_value(type, value):
130148 fields = type .fields
131149 obj = {}
132150 for field_name , field in fields .items ():
133- field_value = coerce_value (field .type , value .get (field_name ))
134- if field_value is None :
151+ field_value = coerce_value (field .type , value .get (field_name , Undefined ))
152+ if field_value is Undefined :
135153 field_value = field .default_value
136154
137- if field_value is not None :
155+ if field_value is not Undefined :
138156 # We use out_name as the output name for the
139157 # dict if exists
140158 obj [field .out_name or field_name ] = field_value
@@ -144,4 +162,8 @@ def coerce_value(type, value):
144162 assert isinstance (type , (GraphQLScalarType , GraphQLEnumType )), \
145163 'Must be input type'
146164
147- return type .parse_value (value )
165+ parsed = type .parse_value (value )
166+ if parsed is None :
167+ return Undefined
168+
169+ return parsed
0 commit comments