@@ -124,7 +124,7 @@ def execute_operation(exe_context, operation, root_value):
124124 )
125125
126126 if operation .operation == 'mutation' :
127- return execute_fields_serially (exe_context , type , root_value , fields )
127+ return execute_fields_serially (exe_context , type , root_value , [], fields )
128128
129129 if operation .operation == 'subscription' :
130130 if not exe_context .allow_subscriptions :
@@ -133,12 +133,12 @@ def execute_operation(exe_context, operation, root_value):
133133 "You will need to either use the subscribe function "
134134 "or pass allow_subscriptions=True"
135135 )
136- return subscribe_fields (exe_context , type , root_value , fields )
136+ return subscribe_fields (exe_context , type , root_value , fields , )
137137
138- return execute_fields (exe_context , type , root_value , fields , None )
138+ return execute_fields (exe_context , type , root_value , fields , [], None )
139139
140140
141- def execute_fields_serially (exe_context , parent_type , source_value , fields ):
141+ def execute_fields_serially (exe_context , parent_type , source_value , path , fields ):
142142 def execute_field_callback (results , response_name ):
143143 field_asts = fields [response_name ]
144144 result = resolve_field (
@@ -147,7 +147,7 @@ def execute_field_callback(results, response_name):
147147 source_value ,
148148 field_asts ,
149149 None ,
150- [response_name ]
150+ path + [response_name ]
151151 )
152152 if result is Undefined :
153153 return results
@@ -168,13 +168,13 @@ def execute_field(prev_promise, response_name):
168168 return functools .reduce (execute_field , fields .keys (), Promise .resolve (collections .OrderedDict ()))
169169
170170
171- def execute_fields (exe_context , parent_type , source_value , fields , info ):
171+ def execute_fields (exe_context , parent_type , source_value , fields , path , info ):
172172 contains_promise = False
173173
174174 final_results = OrderedDict ()
175175
176176 for response_name , field_asts in fields .items ():
177- result = resolve_field (exe_context , parent_type , source_value , field_asts , info , ( info . path if info else []) + [response_name ])
177+ result = resolve_field (exe_context , parent_type , source_value , field_asts , info , path + [response_name ])
178178 if result is Undefined :
179179 continue
180180
@@ -207,8 +207,7 @@ def map_result(data):
207207 # assert len(fields) == 1, "Can only subscribe one element at a time."
208208
209209 for response_name , field_asts in fields .items ():
210-
211- result = subscribe_field (exe_context , parent_type , source_value , field_asts )
210+ result = subscribe_field (exe_context , parent_type , source_value , field_asts , [response_name ])
212211 if result is Undefined :
213212 continue
214213
@@ -272,11 +271,12 @@ def resolve_field(exe_context, parent_type, source, field_asts, parent_info, fie
272271 return_type ,
273272 field_asts ,
274273 info ,
274+ field_path ,
275275 result
276276 )
277277
278278
279- def subscribe_field (exe_context , parent_type , source , field_asts ):
279+ def subscribe_field (exe_context , parent_type , source , field_asts , path ):
280280 field_ast = field_asts [0 ]
281281 field_name = field_ast .name .value
282282
@@ -312,7 +312,7 @@ def subscribe_field(exe_context, parent_type, source, field_asts):
312312 operation = exe_context .operation ,
313313 variable_values = exe_context .variable_values ,
314314 context = context ,
315- path = [ field_name ]
315+ path = path
316316 )
317317
318318 executor = exe_context .executor
@@ -332,6 +332,7 @@ def subscribe_field(exe_context, parent_type, source, field_asts):
332332 return_type ,
333333 field_asts ,
334334 info ,
335+ path ,
335336 ))
336337
337338
@@ -346,16 +347,16 @@ def resolve_or_error(resolve_fn, source, info, args, executor):
346347 return e
347348
348349
349- def complete_value_catching_error (exe_context , return_type , field_asts , info , result ):
350+ def complete_value_catching_error (exe_context , return_type , field_asts , info , path , result ):
350351 # If the field type is non-nullable, then it is resolved without any
351352 # protection from errors.
352353 if isinstance (return_type , GraphQLNonNull ):
353- return complete_value (exe_context , return_type , field_asts , info , result )
354+ return complete_value (exe_context , return_type , field_asts , info , path , result )
354355
355356 # Otherwise, error protection is applied, logging the error and
356357 # resolving a null value for this field if one is encountered.
357358 try :
358- completed = complete_value (exe_context , return_type , field_asts , info , result )
359+ completed = complete_value (exe_context , return_type , field_asts , info , path , result )
359360 if is_thenable (completed ):
360361 def handle_error (error ):
361362 traceback = completed ._traceback
@@ -371,7 +372,7 @@ def handle_error(error):
371372 return None
372373
373374
374- def complete_value (exe_context , return_type , field_asts , info , result ):
375+ def complete_value (exe_context , return_type , field_asts , info , path , result ):
375376 """
376377 Implements the instructions for completeValue as defined in the
377378 "Field entries" section of the spec.
@@ -399,6 +400,7 @@ def complete_value(exe_context, return_type, field_asts, info, result):
399400 return_type ,
400401 field_asts ,
401402 info ,
403+ path ,
402404 resolved
403405 ),
404406 lambda error : Promise .rejected (
@@ -407,35 +409,35 @@ def complete_value(exe_context, return_type, field_asts, info, result):
407409
408410 # print return_type, type(result)
409411 if isinstance (result , Exception ):
410- raise GraphQLLocatedError (field_asts , original_error = result )
412+ raise GraphQLLocatedError (field_asts , original_error = result , path = path )
411413
412414 if isinstance (return_type , GraphQLNonNull ):
413- return complete_nonnull_value (exe_context , return_type , field_asts , info , result )
415+ return complete_nonnull_value (exe_context , return_type , field_asts , info , path , result )
414416
415417 # If result is null-like, return null.
416418 if result is None :
417419 return None
418420
419421 # If field type is List, complete each item in the list with the inner type
420422 if isinstance (return_type , GraphQLList ):
421- return complete_list_value (exe_context , return_type , field_asts , info , result )
423+ return complete_list_value (exe_context , return_type , field_asts , info , path , result )
422424
423425 # If field type is Scalar or Enum, serialize to a valid value, returning
424426 # null if coercion is not possible.
425427 if isinstance (return_type , (GraphQLScalarType , GraphQLEnumType )):
426- return complete_leaf_value (return_type , result )
428+ return complete_leaf_value (return_type , path , result )
427429
428430 if isinstance (return_type , (GraphQLInterfaceType , GraphQLUnionType )):
429- return complete_abstract_value (exe_context , return_type , field_asts , info , result )
431+ return complete_abstract_value (exe_context , return_type , field_asts , info , path , result )
430432
431433 if isinstance (return_type , GraphQLObjectType ):
432- return complete_object_value (exe_context , return_type , field_asts , info , result )
434+ return complete_object_value (exe_context , return_type , field_asts , info , path , result )
433435
434436 assert False , u'Cannot complete value of unexpected type "{}".' .format (
435437 return_type )
436438
437439
438- def complete_list_value (exe_context , return_type , field_asts , info , result ):
440+ def complete_list_value (exe_context , return_type , field_asts , info , path , result ):
439441 """
440442 Complete a list value by completing each item in the list with the inner type
441443 """
@@ -448,10 +450,8 @@ def complete_list_value(exe_context, return_type, field_asts, info, result):
448450 contains_promise = False
449451
450452 index = 0
451- path = info .path [:]
452453 for item in result :
453- info .path = path + [index ]
454- completed_item = complete_value_catching_error (exe_context , item_type , field_asts , info , item )
454+ completed_item = complete_value_catching_error (exe_context , item_type , field_asts , info , path + [index ], item , )
455455 if not contains_promise and is_thenable (completed_item ):
456456 contains_promise = True
457457
@@ -461,7 +461,7 @@ def complete_list_value(exe_context, return_type, field_asts, info, result):
461461 return Promise .all (completed_results ) if contains_promise else completed_results
462462
463463
464- def complete_leaf_value (return_type , result ):
464+ def complete_leaf_value (return_type , path , result ):
465465 """
466466 Complete a Scalar or Enum by serializing to a valid value, returning null if serialization is not possible.
467467 """
@@ -471,12 +471,13 @@ def complete_leaf_value(return_type, result):
471471 if serialized_result is None :
472472 raise GraphQLError (
473473 ('Expected a value of type "{}" but ' +
474- 'received: {}' ).format (return_type , result )
474+ 'received: {}' ).format (return_type , result ),
475+ path = path
475476 )
476477 return serialized_result
477478
478479
479- def complete_abstract_value (exe_context , return_type , field_asts , info , result ):
480+ def complete_abstract_value (exe_context , return_type , field_asts , info , path , result ):
480481 """
481482 Complete an value of an abstract type by determining the runtime type of that value, then completing based
482483 on that type.
@@ -514,7 +515,7 @@ def complete_abstract_value(exe_context, return_type, field_asts, info, result):
514515 field_asts
515516 )
516517
517- return complete_object_value (exe_context , runtime_type , field_asts , info , result )
518+ return complete_object_value (exe_context , runtime_type , field_asts , info , path , result )
518519
519520
520521def get_default_resolve_type_fn (value , info , abstract_type ):
@@ -524,7 +525,7 @@ def get_default_resolve_type_fn(value, info, abstract_type):
524525 return type
525526
526527
527- def complete_object_value (exe_context , return_type , field_asts , info , result ):
528+ def complete_object_value (exe_context , return_type , field_asts , info , path , result ):
528529 """
529530 Complete an Object value by evaluating all sub-selections.
530531 """
@@ -537,15 +538,15 @@ def complete_object_value(exe_context, return_type, field_asts, info, result):
537538
538539 # Collect sub-fields to execute to complete this value.
539540 subfield_asts = exe_context .get_sub_fields (return_type , field_asts )
540- return execute_fields (exe_context , return_type , result , subfield_asts , info )
541+ return execute_fields (exe_context , return_type , result , subfield_asts , path , info )
541542
542543
543- def complete_nonnull_value (exe_context , return_type , field_asts , info , result ):
544+ def complete_nonnull_value (exe_context , return_type , field_asts , info , path , result ):
544545 """
545546 Complete a NonNull value by completing the inner type
546547 """
547548 completed = complete_value (
548- exe_context , return_type .of_type , field_asts , info , result
549+ exe_context , return_type .of_type , field_asts , info , path , result
549550 )
550551 if completed is None :
551552 raise GraphQLError (
0 commit comments