Skip to content

Commit 1e910db

Browse files
committed
[RFC] Add explicit context arg to graphql execution
Related GraphQL-js commit: graphql/graphql-js@d7cc6f9
1 parent a7d822c commit 1e910db

File tree

10 files changed

+39
-32
lines changed

10 files changed

+39
-32
lines changed

graphql/execution/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def __init__(self, field_name, field_asts, return_type, parent_type,
259259
self.variable_values = variable_values
260260

261261

262-
def default_resolve_fn(source, args, info):
262+
def default_resolve_fn(source, args, context, info):
263263
"""If a resolve function is not given, then a default resolve behavior is used which takes the property of the source object
264264
of the same name as the field and returns it as the result, or if it's a function, returns the result of calling that function."""
265265
name = info.field_name

graphql/execution/executor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def resolve_field(exe_context, parent_type, source, field_asts):
164164

165165
def resolve_or_error(resolve_fn, source, args, context, info, executor):
166166
try:
167-
return executor.execute(resolve_fn, source, args, info)
167+
return executor.execute(resolve_fn, source, args, context, info)
168168
except Exception as e:
169169
logger.exception("An error occurred while resolving field {}.{}".format(
170170
info.parent_type.name, info.field_name
@@ -310,7 +310,7 @@ def complete_abstract_value(exe_context, return_type, field_asts, info, result):
310310
# Field type must be Object, Interface or Union and expect sub-selections.
311311
if isinstance(return_type, (GraphQLInterfaceType, GraphQLUnionType)):
312312
if return_type.resolve_type:
313-
runtime_type = return_type.resolve_type(result, info)
313+
runtime_type = return_type.resolve_type(result, exe_context.context_value, info)
314314
else:
315315
runtime_type = get_default_resolve_type_fn(result, exe_context.context_value, info, return_type)
316316

@@ -342,15 +342,15 @@ def complete_abstract_value(exe_context, return_type, field_asts, info, result):
342342
def get_default_resolve_type_fn(value, context, info, abstract_type):
343343
possible_types = info.schema.get_possible_types(abstract_type)
344344
for type in possible_types:
345-
if callable(type.is_type_of) and type.is_type_of(value, info):
345+
if callable(type.is_type_of) and type.is_type_of(value, context, info):
346346
return type
347347

348348

349349
def complete_object_value(exe_context, return_type, field_asts, info, result):
350350
"""
351351
Complete an Object value by evaluating all sub-selections.
352352
"""
353-
if return_type.is_type_of and not return_type.is_type_of(result, info):
353+
if return_type.is_type_of and not return_type.is_type_of(result, exe_context.context_value, info):
354354
raise GraphQLError(
355355
u'Expected value of type "{}" but got: {}.'.format(return_type, type(result).__name__),
356356
field_asts

graphql/execution/tests/test_abstract.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ def __init__(self, name):
2525
self.name = name
2626

2727

28-
is_type_of = lambda type: lambda obj, info: isinstance(obj, type)
28+
is_type_of = lambda type: lambda obj, context, info: isinstance(obj, type)
2929

3030

3131
def make_type_resolver(types):
32-
def resolve_type(obj, info):
32+
def resolve_type(obj, context, info):
3333
if callable(types):
3434
t = types()
3535
else:

graphql/execution/tests/test_executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def __init__(self, value):
485485
fields={
486486
'value': GraphQLField(GraphQLString),
487487
},
488-
is_type_of=lambda obj, info: isinstance(obj, Special)
488+
is_type_of=lambda obj, context, info: isinstance(obj, Special)
489489
)
490490

491491
schema = GraphQLSchema(

graphql/execution/tests/test_union_interface.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def __init__(self, name, pets, friends):
3838
'name': GraphQLField(GraphQLString),
3939
'barks': GraphQLField(GraphQLBoolean),
4040
},
41-
is_type_of=lambda value, info: isinstance(value, Dog)
41+
is_type_of=lambda value, context, info: isinstance(value, Dog)
4242
)
4343

4444
CatType = GraphQLObjectType(
@@ -48,11 +48,11 @@ def __init__(self, name, pets, friends):
4848
'name': GraphQLField(GraphQLString),
4949
'meows': GraphQLField(GraphQLBoolean),
5050
},
51-
is_type_of=lambda value, info: isinstance(value, Cat)
51+
is_type_of=lambda value, context, info: isinstance(value, Cat)
5252
)
5353

5454

55-
def resolve_pet_type(value, info):
55+
def resolve_pet_type(value, context, info):
5656
if isinstance(value, Dog):
5757
return DogType
5858
if isinstance(value, Cat):
@@ -70,7 +70,7 @@ def resolve_pet_type(value, info):
7070
'pets': GraphQLField(GraphQLList(PetType)),
7171
'friends': GraphQLField(GraphQLList(NamedType)),
7272
},
73-
is_type_of=lambda value, info: isinstance(value, Person)
73+
is_type_of=lambda value, context, info: isinstance(value, Person)
7474
)
7575

7676
schema = GraphQLSchema(query=PersonType, types=[PetType])
@@ -107,6 +107,7 @@ def test_can_introspect_on_union_and_intersection_types():
107107
}''')
108108

109109
result = execute(schema, ast)
110+
assert not result.errors
110111
assert result.data == {
111112
'Named': {
112113
'enumValues': None,
@@ -311,12 +312,15 @@ def test_only_include_fields_from_matching_fragment_condition():
311312

312313

313314
def test_gets_execution_info_in_resolver():
314-
encountered_schema = [None]
315-
encountered_root_value = [None]
316-
317-
def resolve_type(obj, info):
318-
encountered_schema[0] = info.schema
319-
encountered_root_value[0] = info.root_value
315+
class encountered:
316+
schema = None
317+
root_value = None
318+
context = None
319+
320+
def resolve_type(obj, context, info):
321+
encountered.schema = info.schema
322+
encountered.root_value = info.root_value
323+
encountered.context = context
320324
return PersonType2
321325

322326
NamedType2 = GraphQLInterfaceType(
@@ -338,12 +342,15 @@ def resolve_type(obj, info):
338342

339343
schema2 = GraphQLSchema(query=PersonType2)
340344
john2 = Person('John', [], [liz])
345+
context = {'hey'}
341346
ast = parse('''{ name, friends { name } }''')
342347

343-
result = execute(schema2, ast, john2)
348+
result = execute(schema2, ast, john2, context_value=context)
349+
assert not result.errors
344350
assert result.data == {
345351
'name': 'John', 'friends': [{'name': 'Liz'}]
346352
}
347353

348-
assert encountered_schema[0] == schema2
349-
assert encountered_root_value[0] == john2
354+
assert encountered.schema == schema2
355+
assert encountered.root_value == john2
356+
assert encountered.context == context

graphql/execution/tests/test_variables.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
stringify = lambda obj: json.dumps(obj, sort_keys=True)
2828

2929

30-
def input_to_json(obj, args, info):
30+
def input_to_json(obj, args, context, info):
3131
input = args.get('input')
3232
if input:
3333
return stringify(input)

graphql/type/definition.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class GraphQLObjectType(GraphQLType):
157157
'street': GraphQLField(GraphQLString),
158158
'number': GraphQLField(GraphQLInt),
159159
'formatted': GraphQLField(GraphQLString,
160-
resolver=lambda obj, args, info: obj.number + ' ' + obj.street),
160+
resolver=lambda obj, args, context, info: obj.number + ' ' + obj.street),
161161
})
162162
163163
When two types need to refer to each other, or a type needs to refer to

graphql/type/introspection.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def interfaces(type, *_):
168168
return type.get_interfaces()
169169

170170
@staticmethod
171-
def possible_types(type, args, info):
171+
def possible_types(type, args, context, info):
172172
if isinstance(type, (GraphQLInterfaceType, GraphQLUnionType)):
173173
return info.schema.get_possible_types(type)
174174

@@ -350,7 +350,7 @@ def input_fields(type, *_):
350350
SchemaMetaFieldDef = GraphQLField(
351351
type=GraphQLNonNull(__Schema),
352352
description='Access the current type schema of this server.',
353-
resolver=lambda source, args, info: info.schema,
353+
resolver=lambda source, args, context, info: info.schema,
354354
args=[]
355355
)
356356
SchemaMetaFieldDef.name = '__schema'
@@ -361,15 +361,15 @@ def input_fields(type, *_):
361361
type=__Type,
362362
description='Request the type information of a single type.',
363363
args=[TypeMetaFieldDef_args_name],
364-
resolver=lambda source, args, info: info.schema.get_type(args['name'])
364+
resolver=lambda source, args, context, info: info.schema.get_type(args['name'])
365365
)
366366
TypeMetaFieldDef.name = '__type'
367367
del TypeMetaFieldDef_args_name
368368

369369
TypeNameMetaFieldDef = GraphQLField(
370370
type=GraphQLNonNull(GraphQLString),
371371
description='The name of the current Object type at runtime.',
372-
resolver=lambda source, args, info: info.parent_type.name,
372+
resolver=lambda source, args, context, info: info.parent_type.name,
373373
args=[]
374374
)
375375
TypeNameMetaFieldDef.name = '__typename'

graphql/type/tests/test_enum_type.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ def get_first(args, *keys):
3535
'fromInt': GraphQLArgument(GraphQLInt),
3636
'fromString': GraphQLArgument(GraphQLString)
3737
},
38-
resolver=lambda value, args, info: get_first(args, 'fromInt', 'fromString', 'fromEnum')
38+
resolver=lambda value, args, context, info: get_first(args, 'fromInt', 'fromString', 'fromEnum')
3939
),
4040
'colorInt': GraphQLField(
4141
type=GraphQLInt,
4242
args={
4343
'fromEnum': GraphQLArgument(ColorType),
4444
'fromInt': GraphQLArgument(GraphQLInt),
4545
},
46-
resolver=lambda value, args, info: get_first(args, 'fromInt', 'fromEnum')
46+
resolver=lambda value, args, context, info: get_first(args, 'fromInt', 'fromEnum')
4747
)
4848
}
4949
)
@@ -56,7 +56,7 @@ def get_first(args, *keys):
5656
args={
5757
'color': GraphQLArgument(ColorType)
5858
},
59-
resolver=lambda value, args, info: args.get('color')
59+
resolver=lambda value, args, context, info: args.get('color')
6060
)
6161
}
6262
)
@@ -69,7 +69,7 @@ def get_first(args, *keys):
6969
args={
7070
'color': GraphQLArgument(ColorType)
7171
},
72-
resolver=lambda value, args, info: args.get('color')
72+
resolver=lambda value, args, context, info: args.get('color')
7373
)
7474
}
7575
)

graphql/type/tests/test_introspection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ def test_introspects_on_input_object():
728728
'field': GraphQLField(
729729
type=GraphQLString,
730730
args={'complex': GraphQLArgument(TestInputObject)},
731-
resolver=lambda obj, args, info: json.dumps(args.get('complex'))
731+
resolver=lambda obj, args, context, info: json.dumps(args.get('complex'))
732732
)
733733
})
734734
schema = GraphQLSchema(TestType)

0 commit comments

Comments
 (0)