Skip to content

Commit 8030fea

Browse files
committed
Fixed flexible resolving in return type
1 parent cdd4afb commit 8030fea

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

graphene/types/interface.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ class Interface(six.with_metaclass(InterfaceMeta)):
4848
when the field is resolved.
4949
'''
5050

51-
resolve_type = None
51+
@classmethod
52+
def resolve_type(cls, instance, context, info):
53+
from .objecttype import ObjectType
54+
if isinstance(instance, ObjectType):
55+
return type(instance)
5256

5357
def __init__(self, *args, **kwargs):
5458
raise Exception("An Interface cannot be intitialized")

graphene/types/objecttype.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
6363
have a name, but most importantly describe their fields.
6464
'''
6565

66-
@classmethod
67-
def is_type_of(cls, root, context, info):
68-
if isinstance(root, cls):
69-
return True
66+
is_type_of = None
7067

7168
def __init__(self, *args, **kwargs):
7269
# ObjectType acting as container

graphene/types/tests/test_query.py

+28
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ def test_query_wrong_default_value():
4141
class MyType(ObjectType):
4242
field = String()
4343

44+
@classmethod
45+
def is_type_of(cls, root, context, info):
46+
return isinstance(root, MyType)
47+
4448
class Query(ObjectType):
4549
hello = Field(MyType, default_value='hello')
4650

@@ -153,6 +157,30 @@ def reversed_middleware(next, *args, **kwargs):
153157
assert executed.data == {'hello': 'dlroW', 'other': 'rehto'}
154158

155159

160+
def test_objecttype_on_instances():
161+
class Ship:
162+
def __init__(self, name):
163+
self.name = name
164+
165+
class ShipType(ObjectType):
166+
name = String(description="Ship name", required=True)
167+
168+
def resolve_name(self, context, args, info):
169+
# Here self will be the Ship instance returned in resolve_ship
170+
return self.name
171+
172+
class Query(ObjectType):
173+
ship = Field(ShipType)
174+
175+
def resolve_ship(self, context, args, info):
176+
return Ship(name='xwing')
177+
178+
schema = Schema(query=Query)
179+
executed = schema.execute('{ ship { name } }')
180+
assert not executed.errors
181+
assert executed.data == {'ship': {'name': 'xwing'}}
182+
183+
156184
def test_big_list_query_benchmark(benchmark):
157185
big_list = range(10000)
158186

graphene/types/typemap.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
GraphQLFloat, GraphQLID, GraphQLInputObjectField,
77
GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLString)
88
from graphql.type import GraphQLEnumValue
9+
from graphql.execution.executor import get_default_resolve_type_fn
910
from graphql.type.typemap import GraphQLTypeMap
1011

1112
from ..utils.str_converters import to_camel_case
@@ -26,11 +27,14 @@ def is_graphene_type(_type):
2627
return True
2728

2829

29-
def resolve_type(resolve_type_func, map, root, args, info):
30-
_type = resolve_type_func(root, args, info)
30+
def resolve_type(resolve_type_func, map, root, context, info):
31+
_type = resolve_type_func(root, context, info)
3132
# assert inspect.isclass(_type) and issubclass(_type, ObjectType), (
3233
# 'Received incompatible type "{}".'.format(_type)
3334
# )
35+
if not _type:
36+
return get_default_resolve_type_fn(root, context, info, info.return_type)
37+
3438
if inspect.isclass(_type) and issubclass(_type, ObjectType):
3539
graphql_type = map.get(_type._meta.name)
3640
assert graphql_type and graphql_type.graphene_type == _type

0 commit comments

Comments
 (0)