33import logging
44import sys
55
6- from promise import Promise , is_thenable , promise_for_dict , promisify
6+ from promise import Promise , promise_for_dict , promisify
77
88from ..error import GraphQLError , GraphQLLocatedError
99from ..pyutils .default_ordered_dict import DefaultOrderedDict
10+ from ..pyutils .ordereddict import OrderedDict
1011from ..type import (GraphQLEnumType , GraphQLInterfaceType , GraphQLList ,
1112 GraphQLNonNull , GraphQLObjectType , GraphQLScalarType ,
1213 GraphQLSchema , GraphQLUnionType )
1314from .base import (ExecutionContext , ExecutionResult , ResolveInfo , Undefined ,
1415 collect_fields , default_resolve_fn , get_field_def ,
1516 get_operation_root_type )
1617from .executors .sync import SyncExecutor
18+ from .middleware import MiddlewareManager
1719
1820logger = logging .getLogger (__name__ )
1921
2022
23+ def is_promise (obj ):
24+ return type (obj ) == Promise
25+
26+
2127def execute (schema , document_ast , root_value = None , context_value = None ,
2228 variable_values = None , operation_name = None , executor = None ,
23- return_promise = False ):
29+ return_promise = False , middlewares = None ):
2430 assert schema , 'Must provide schema'
2531 assert isinstance (schema , GraphQLSchema ), (
2632 'Schema must be an instance of GraphQLSchema. Also ensure that there are ' +
2733 'not multiple versions of GraphQL installed in your node_modules directory.'
2834 )
35+ if middlewares :
36+ assert isinstance (middlewares , MiddlewareManager ), (
37+ 'middlewares have to be an instance'
38+ ' of MiddlewareManager. Received "{}".' .format (middlewares )
39+ )
2940
3041 if executor is None :
3142 executor = SyncExecutor ()
@@ -37,7 +48,8 @@ def execute(schema, document_ast, root_value=None, context_value=None,
3748 context_value ,
3849 variable_values ,
3950 operation_name ,
40- executor
51+ executor ,
52+ middlewares
4153 )
4254
4355 def executor (resolve , reject ):
@@ -85,7 +97,7 @@ def execute_field_callback(results, response_name):
8597 if result is Undefined :
8698 return results
8799
88- if is_thenable (result ):
100+ if is_promise (result ):
89101 def collect_result (resolved_result ):
90102 results [response_name ] = resolved_result
91103 return results
@@ -104,15 +116,15 @@ def execute_field(prev_promise, response_name):
104116def execute_fields (exe_context , parent_type , source_value , fields ):
105117 contains_promise = False
106118
107- final_results = collections . OrderedDict ()
119+ final_results = OrderedDict ()
108120
109121 for response_name , field_asts in fields .items ():
110122 result = resolve_field (exe_context , parent_type , source_value , field_asts )
111123 if result is Undefined :
112124 continue
113125
114126 final_results [response_name ] = result
115- if is_thenable (result ):
127+ if is_promise (result ):
116128 contains_promise = True
117129
118130 if not contains_promise :
@@ -132,6 +144,9 @@ def resolve_field(exe_context, parent_type, source, field_asts):
132144 return_type = field_def .type
133145 resolve_fn = field_def .resolver or default_resolve_fn
134146
147+ # We wrap the resolve_fn from the middleware
148+ resolve_fn_middleware = exe_context .get_field_resolver (resolve_fn )
149+
135150 # Build a dict of arguments from the field.arguments AST, using the variables scope to
136151 # fulfill any variable references.
137152 args = exe_context .get_argument_values (field_def , field_ast )
@@ -156,7 +171,7 @@ def resolve_field(exe_context, parent_type, source, field_asts):
156171 )
157172
158173 executor = exe_context .executor
159- result = resolve_or_error (resolve_fn , source , args , context , info , executor )
174+ result = resolve_or_error (resolve_fn_middleware , source , args , context , info , executor )
160175
161176 return complete_value_catching_error (
162177 exe_context ,
@@ -188,7 +203,7 @@ def complete_value_catching_error(exe_context, return_type, field_asts, info, re
188203 # resolving a null value for this field if one is encountered.
189204 try :
190205 completed = complete_value (exe_context , return_type , field_asts , info , result )
191- if is_thenable (completed ):
206+ if is_promise (completed ):
192207 def handle_error (error ):
193208 exe_context .errors .append (error )
194209 return Promise .fulfilled (None )
@@ -222,7 +237,7 @@ def complete_value(exe_context, return_type, field_asts, info, result):
222237 """
223238 # If field type is NonNull, complete for inner type, and throw field error if result is null.
224239
225- if is_thenable (result ):
240+ if is_promise (result ):
226241 return promisify (result ).then (
227242 lambda resolved : complete_value (
228243 exe_context ,
@@ -238,16 +253,7 @@ def complete_value(exe_context, return_type, field_asts, info, result):
238253 raise GraphQLLocatedError (field_asts , original_error = result )
239254
240255 if isinstance (return_type , GraphQLNonNull ):
241- completed = complete_value (
242- exe_context , return_type .of_type , field_asts , info , result
243- )
244- if completed is None :
245- raise GraphQLError (
246- 'Cannot return null for non-nullable field {}.{}.' .format (info .parent_type , info .field_name ),
247- field_asts
248- )
249-
250- return completed
256+ return complete_nonnull_value (exe_context , return_type , field_asts , info , result )
251257
252258 # If result is null-like, return null.
253259 if result is None :
@@ -283,7 +289,7 @@ def complete_list_value(exe_context, return_type, field_asts, info, result):
283289 contains_promise = False
284290 for item in result :
285291 completed_item = complete_value_catching_error (exe_context , item_type , field_asts , info , item )
286- if not contains_promise and is_thenable (completed_item ):
292+ if not contains_promise and is_promise (completed_item ):
287293 contains_promise = True
288294
289295 completed_results .append (completed_item )
@@ -295,15 +301,10 @@ def complete_leaf_value(return_type, result):
295301 """
296302 Complete a Scalar or Enum by serializing to a valid value, returning null if serialization is not possible.
297303 """
298- serialize = getattr (return_type , 'serialize' , None )
299- assert serialize , 'Missing serialize method on type'
300-
301- serialized_result = serialize (result )
302-
303- if serialized_result is None :
304- return None
304+ # serialize = getattr(return_type, 'serialize', None)
305+ # assert serialize, 'Missing serialize method on type'
305306
306- return serialized_result
307+ return return_type . serialize ( result )
307308
308309
309310def complete_abstract_value (exe_context , return_type , field_asts , info , result ):
@@ -360,14 +361,21 @@ def complete_object_value(exe_context, return_type, field_asts, info, result):
360361 )
361362
362363 # Collect sub-fields to execute to complete this value.
363- subfield_asts = DefaultOrderedDict (list )
364- visited_fragment_names = set ()
365- for field_ast in field_asts :
366- selection_set = field_ast .selection_set
367- if selection_set :
368- subfield_asts = collect_fields (
369- exe_context , return_type , selection_set ,
370- subfield_asts , visited_fragment_names
371- )
372-
364+ subfield_asts = exe_context .get_sub_fields (return_type , field_asts )
373365 return execute_fields (exe_context , return_type , result , subfield_asts )
366+
367+
368+ def complete_nonnull_value (exe_context , return_type , field_asts , info , result ):
369+ """
370+ Complete a NonNull value by completing the inner type
371+ """
372+ completed = complete_value (
373+ exe_context , return_type .of_type , field_asts , info , result
374+ )
375+ if completed is None :
376+ raise GraphQLError (
377+ 'Cannot return null for non-nullable field {}.{}.' .format (info .parent_type , info .field_name ),
378+ field_asts
379+ )
380+
381+ return completed
0 commit comments