Skip to content

Commit 6817761

Browse files
committed
Fixed Union and Interface resolve_type when the field is a List/NonNull
1 parent 3c99302 commit 6817761

File tree

2 files changed

+102
-7
lines changed

2 files changed

+102
-7
lines changed

graphene/types/tests/test_query.py

+95
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
from graphql import Source, execute, parse, GraphQLError
55

66
from ..field import Field
7+
from ..interface import Interface
78
from ..inputfield import InputField
89
from ..inputobjecttype import InputObjectType
910
from ..objecttype import ObjectType
1011
from ..scalars import Int, String
1112
from ..schema import Schema
1213
from ..structures import List
14+
from ..union import Union
1315
from ..dynamic import Dynamic
1416

1517

@@ -24,6 +26,99 @@ class Query(ObjectType):
2426
assert executed.data == {'hello': 'World'}
2527

2628

29+
def test_query_union():
30+
class one_object(object):
31+
pass
32+
33+
class two_object(object):
34+
pass
35+
36+
class One(ObjectType):
37+
one = String()
38+
39+
@classmethod
40+
def is_type_of(cls, root, context, info):
41+
return isinstance(root, one_object)
42+
43+
class Two(ObjectType):
44+
two = String()
45+
46+
@classmethod
47+
def is_type_of(cls, root, context, info):
48+
return isinstance(root, two_object)
49+
50+
class MyUnion(Union):
51+
class Meta:
52+
types = (One, Two)
53+
54+
class Query(ObjectType):
55+
unions = List(MyUnion)
56+
57+
def resolve_unions(self, args, context, info):
58+
return [one_object(), two_object()]
59+
60+
hello_schema = Schema(Query)
61+
62+
executed = hello_schema.execute('{ unions { __typename } }')
63+
assert not executed.errors
64+
assert executed.data == {
65+
'unions': [{
66+
'__typename': 'One'
67+
}, {
68+
'__typename': 'Two'
69+
}]
70+
}
71+
72+
73+
def test_query_interface():
74+
class one_object(object):
75+
pass
76+
77+
class two_object(object):
78+
pass
79+
80+
class MyInterface(Interface):
81+
base = String()
82+
83+
class One(ObjectType):
84+
class Meta:
85+
interfaces = (MyInterface, )
86+
87+
one = String()
88+
89+
@classmethod
90+
def is_type_of(cls, root, context, info):
91+
return isinstance(root, one_object)
92+
93+
class Two(ObjectType):
94+
class Meta:
95+
interfaces = (MyInterface, )
96+
97+
two = String()
98+
99+
@classmethod
100+
def is_type_of(cls, root, context, info):
101+
return isinstance(root, two_object)
102+
103+
class Query(ObjectType):
104+
interfaces = List(MyInterface)
105+
106+
def resolve_interfaces(self, args, context, info):
107+
return [one_object(), two_object()]
108+
109+
hello_schema = Schema(Query, types=[One, Two])
110+
111+
executed = hello_schema.execute('{ interfaces { __typename } }')
112+
assert not executed.errors
113+
assert executed.data == {
114+
'interfaces': [{
115+
'__typename': 'One'
116+
}, {
117+
'__typename': 'Two'
118+
}]
119+
}
120+
121+
27122
def test_query_dynamic():
28123
class Query(ObjectType):
29124
hello = Dynamic(lambda: String(resolver=lambda *_: 'World'))

graphene/types/typemap.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ def is_graphene_type(_type):
3030
return True
3131

3232

33-
def resolve_type(resolve_type_func, map, root, context, info):
33+
def resolve_type(resolve_type_func, map, type_name, root, context, info):
3434
_type = resolve_type_func(root, context, info)
35-
# assert inspect.isclass(_type) and issubclass(_type, ObjectType), (
36-
# 'Received incompatible type "{}".'.format(_type)
37-
# )
35+
3836
if not _type:
39-
return get_default_resolve_type_fn(root, context, info, info.return_type)
37+
return_type = map[type_name]
38+
return get_default_resolve_type_fn(root, context, info, return_type)
4039

4140
if inspect.isclass(_type) and issubclass(_type, ObjectType):
4241
graphql_type = map.get(_type._meta.name)
4342
assert graphql_type and graphql_type.graphene_type == _type
4443
return graphql_type
44+
4545
return _type
4646

4747

@@ -151,7 +151,7 @@ def construct_interface(self, map, type):
151151
from .definitions import GrapheneInterfaceType
152152
_resolve_type = None
153153
if type.resolve_type:
154-
_resolve_type = partial(resolve_type, type.resolve_type, map)
154+
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
155155
map[type._meta.name] = GrapheneInterfaceType(
156156
graphene_type=type,
157157
name=type._meta.name,
@@ -178,7 +178,7 @@ def construct_union(self, map, type):
178178
from .definitions import GrapheneUnionType
179179
_resolve_type = None
180180
if type.resolve_type:
181-
_resolve_type = partial(resolve_type, type.resolve_type, map)
181+
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
182182
types = []
183183
for i in type._meta.types:
184184
map = self.construct_objecttype(map, i)

0 commit comments

Comments
 (0)