Skip to content

Commit 12dde37

Browse files
committed
Added info.path
1 parent 33d4f83 commit 12dde37

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

graphql/execution/base.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
import sys
3+
import copy
34

45
from ..error import GraphQLError
56
from ..language import ast
@@ -126,7 +127,7 @@ class ExecutionResult(object):
126127
query, `errors` is null if no errors occurred, and is a
127128
non-empty array if an error occurred."""
128129

129-
__slots__ = 'data', 'errors', 'invalid'
130+
__slots__ = 'data', 'errors', 'invalid', 'extensions'
130131

131132
def __init__(self, data=None, errors=None, extensions=None, invalid=False):
132133
self.data = data
@@ -295,10 +296,10 @@ def get_field_entry_key(node):
295296

296297
class ResolveInfo(object):
297298
__slots__ = ('field_name', 'field_asts', 'return_type', 'parent_type',
298-
'schema', 'fragments', 'root_value', 'operation', 'variable_values', 'context')
299+
'schema', 'fragments', 'root_value', 'operation', 'variable_values', 'context', 'path')
299300

300301
def __init__(self, field_name, field_asts, return_type, parent_type,
301-
schema, fragments, root_value, operation, variable_values, context):
302+
schema, fragments, root_value, operation, variable_values, context, path):
302303
self.field_name = field_name
303304
self.field_asts = field_asts
304305
self.return_type = return_type
@@ -309,6 +310,23 @@ def __init__(self, field_name, field_asts, return_type, parent_type,
309310
self.operation = operation
310311
self.variable_values = variable_values
311312
self.context = context
313+
self.path = path
314+
315+
def clone(self):
316+
return ResolveInfo(
317+
field_name=self.field_name,
318+
field_asts=self.field_asts,
319+
return_type=self.return_type,
320+
parent_type=self.parent_type,
321+
schema=self.schema,
322+
fragments=self.fragments,
323+
root_value=self.root_value,
324+
operation=self.operation,
325+
variable_values=self.variable_values,
326+
context=self.context,
327+
path=copy.copy(self.path)
328+
)
329+
312330

313331

314332
def default_resolve_fn(source, info, **args):

graphql/execution/executor.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def on_resolve(data):
8383
if isinstance(data, Observable):
8484
return data
8585

86+
tracing_middleware.end()
8687
extensions = dict(tracing=tracing_middleware.tracing_dict)
8788

8889
if not context.errors:
@@ -121,7 +122,7 @@ def execute_operation(exe_context, operation, root_value):
121122
)
122123
return subscribe_fields(exe_context, type, root_value, fields)
123124

124-
return execute_fields(exe_context, type, root_value, fields)
125+
return execute_fields(exe_context, type, root_value, fields, None)
125126

126127

127128
def execute_fields_serially(exe_context, parent_type, source_value, fields):
@@ -152,14 +153,13 @@ def execute_field(prev_promise, response_name):
152153
return functools.reduce(execute_field, fields.keys(), Promise.resolve(collections.OrderedDict()))
153154

154155

155-
def execute_fields(exe_context, parent_type, source_value, fields):
156+
def execute_fields(exe_context, parent_type, source_value, fields, info):
156157
contains_promise = False
157158

158159
final_results = OrderedDict()
159160

160161
for response_name, field_asts in fields.items():
161-
result = resolve_field(exe_context, parent_type,
162-
source_value, field_asts)
162+
result = resolve_field(exe_context, parent_type, source_value, field_asts, info)
163163
if result is Undefined:
164164
continue
165165

@@ -211,7 +211,7 @@ def catch_error(error):
211211
return Observable.merge(observables)
212212

213213

214-
def resolve_field(exe_context, parent_type, source, field_asts):
214+
def resolve_field(exe_context, parent_type, source, field_asts, parent_info):
215215
field_ast = field_asts[0]
216216
field_name = field_ast.name.value
217217

@@ -246,12 +246,12 @@ def resolve_field(exe_context, parent_type, source, field_asts):
246246
root_value=exe_context.root_value,
247247
operation=exe_context.operation,
248248
variable_values=exe_context.variable_values,
249-
context=context
249+
context=context,
250+
path=parent_info.path+[field_name] if parent_info else [field_name]
250251
)
251252

252253
executor = exe_context.executor
253-
result = resolve_or_error(resolve_fn_middleware,
254-
source, info, args, executor)
254+
result = resolve_or_error(resolve_fn_middleware, source, info, args, executor)
255255

256256
return complete_value_catching_error(
257257
exe_context,
@@ -377,7 +377,6 @@ def complete_value(exe_context, return_type, field_asts, info, result):
377377
"""
378378
# If field type is NonNull, complete for inner type, and throw field error
379379
# if result is null.
380-
381380
if is_thenable(result):
382381
return Promise.resolve(result).then(
383382
lambda resolved: complete_value(
@@ -432,13 +431,16 @@ def complete_list_value(exe_context, return_type, field_asts, info, result):
432431
item_type = return_type.of_type
433432
completed_results = []
434433
contains_promise = False
434+
index = 0
435435
for item in result:
436-
completed_item = complete_value_catching_error(
437-
exe_context, item_type, field_asts, info, item)
436+
new_info = info.clone()
437+
new_info.path += [index]
438+
completed_item = complete_value_catching_error(exe_context, item_type, field_asts, new_info, item)
438439
if not contains_promise and is_thenable(completed_item):
439440
contains_promise = True
440441

441442
completed_results.append(completed_item)
443+
index += 1
442444

443445
return Promise.all(completed_results) if contains_promise else completed_results
444446

@@ -514,7 +516,7 @@ def complete_object_value(exe_context, return_type, field_asts, info, result):
514516

515517
# Collect sub-fields to execute to complete this value.
516518
subfield_asts = exe_context.get_sub_fields(return_type, field_asts)
517-
return execute_fields(exe_context, return_type, result, subfield_asts)
519+
return execute_fields(exe_context, return_type, result, subfield_asts, info)
518520

519521

520522
def complete_nonnull_value(exe_context, return_type, field_asts, info, result):

graphql/execution/tracing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def resolve(self, _next, root, info, *args, **kwargs):
5151
elapsed_ms = (end - start) * 1000
5252

5353
stat = {
54-
# "path": [ <>, ...],
54+
"path": info.path,
5555
"parentType": str(info.parent_type),
5656
"fieldName": info.field_name,
5757
"returnType": str(info.return_type),

0 commit comments

Comments
 (0)