Skip to content

Commit 55e2027

Browse files
committed
Improved schema type resolvers
1 parent 8819610 commit 55e2027

File tree

9 files changed

+40
-22
lines changed

9 files changed

+40
-22
lines changed

graphene/contrib/django/fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def internal_type(self, schema):
6262
self.object_type
6363
)
6464
)
65-
return _type and _type.internal_type(schema) or Field.SKIP
65+
return schema.T(_type) or Field.SKIP
6666

6767
def get_object_type(self, schema):
6868
return get_type_for_model(schema, self.model)

graphene/core/fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def internal_type(self, schema):
114114
else:
115115
object_type = self.get_object_type(schema)
116116
if object_type:
117-
field_type = object_type.internal_type(schema)
117+
field_type = schema.T(object_type)
118118

119119
field_type = self.type_wrapper(field_type)
120120
return field_type

graphene/core/schema.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Schema(object):
2525

2626
def __init__(self, query=None, mutation=None, name='Schema', executor=None):
2727
self._internal_types = {}
28+
self._types = {}
2829
self.mutation = mutation
2930
self.query = query
3031
self.name = name
@@ -34,14 +35,20 @@ def __init__(self, query=None, mutation=None, name='Schema', executor=None):
3435
def __repr__(self):
3536
return '<Schema: %s (%s)>' % (str(self.name), hash(self))
3637

38+
def T(self, object_type):
39+
if not object_type:
40+
return
41+
if object_type not in self._types:
42+
self._types[object_type] = object_type.internal_type(self)
43+
return self._types[object_type]
44+
3745
@property
3846
def query(self):
3947
return self._query
4048

4149
@query.setter
4250
def query(self, query):
4351
self._query = query
44-
self._query_type = query and query.internal_type(self)
4552

4653
@property
4754
def mutation(self):
@@ -50,7 +57,6 @@ def mutation(self):
5057
@mutation.setter
5158
def mutation(self, mutation):
5259
self._mutation = mutation
53-
self._mutation_type = mutation and mutation.internal_type(self)
5460

5561
@property
5662
def executor(self):
@@ -62,11 +68,11 @@ def executor(self):
6268
def executor(self, value):
6369
self._executor = value
6470

65-
@cached_property
71+
@property
6672
def schema(self):
67-
if not self._query_type:
73+
if not self._query:
6874
raise Exception('You have to define a base query type')
69-
return GraphQLSchema(self, query=self._query_type, mutation=self._mutation_type)
75+
return GraphQLSchema(self, query=self.T(self._query), mutation=self.T(self._mutation))
7076

7177
def associate_internal_type(self, internal_type, object_type):
7278
self._internal_types[internal_type.name] = object_type
@@ -76,6 +82,7 @@ def register(self, object_type):
7682
return object_type
7783

7884
def get_type(self, type_name):
85+
self.schema._build_type_map()
7986
if type_name not in self._internal_types:
8087
raise Exception('Type %s not found in %r' % (type_name, self))
8188
return self._internal_types[type_name]

graphene/core/types.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,14 @@ def fields_as_arguments(cls, schema):
179179

180180
@classmethod
181181
def resolve_objecttype(cls, schema, instance, *_):
182-
return instance
182+
return instance.__class__
183183

184184
@classmethod
185185
def resolve_type(cls, schema, instance, *_):
186186
objecttype = cls.resolve_objecttype(schema, instance, *_)
187-
return objecttype.internal_type(schema)
187+
return schema.T(objecttype)
188188

189189
@classmethod
190-
@memoize
191190
@register_internal_type
192191
def internal_type(cls, schema):
193192
fields = lambda: OrderedDict([(f.name, f.internal_field(schema))
@@ -203,7 +202,7 @@ def internal_type(cls, schema):
203202
return GraphQLObjectType(
204203
cls._meta.type_name,
205204
description=cls._meta.description,
206-
interfaces=[i.internal_type(schema) for i in cls._meta.interfaces],
205+
interfaces=[schema.T(i) for i in cls._meta.interfaces],
207206
fields=fields,
208207
is_type_of=getattr(cls, 'is_type_of', None)
209208
)
@@ -225,7 +224,6 @@ def get_input_type(cls):
225224

226225
class InputObjectType(ObjectType):
227226
@classmethod
228-
@memoize
229227
@register_internal_type
230228
def internal_type(cls, schema):
231229
fields = lambda: OrderedDict([(f.name, f.internal_field(schema))

graphene/relay/fields.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ def internal_type(self, schema):
6363
node = self.get_object_type(schema)
6464
assert is_node(node), 'Only nodes have connections.'
6565
schema.register(node)
66-
67-
return self.get_connection_type(node).internal_type(schema)
66+
connection_type = self.get_connection_type(node)
67+
return schema.T(connection_type)
6868

6969

7070
class NodeField(Field):

tests/contrib_django/test_types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_django_interface():
5050

5151

5252
def test_pseudo_interface():
53-
object_type = Character.internal_type(schema)
53+
object_type = schema.T(Character)
5454
assert Character._meta.is_interface is True
5555
assert isinstance(object_type, GraphQLInterfaceType)
5656
assert Character._meta.model == Reporter
@@ -81,7 +81,7 @@ def test_interface_resolve_type():
8181

8282

8383
def test_object_type():
84-
object_type = Human.internal_type(schema)
84+
object_type = schema.T(Human)
8585
fields_map = Human._meta.fields_map
8686
assert Human._meta.is_interface is False
8787
assert isinstance(object_type, GraphQLObjectType)
@@ -95,7 +95,7 @@ def test_object_type():
9595
# 'reporter': fields_map['reporter'].internal_field(schema),
9696
# 'pubDate': fields_map['pub_date'].internal_field(schema),
9797
# }
98-
assert DjangoNode.internal_type(schema) in object_type.get_interfaces()
98+
assert schema.T(DjangoNode) in object_type.get_interfaces()
9999

100100

101101
def test_node_notinterface():

tests/core/test_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def resolve_pet(self, *args):
4646

4747
schema = Schema()
4848

49-
Human_type = Human.internal_type(schema)
49+
Human_type = schema.T(Human)
5050

5151

5252
def test_type():

tests/core/test_schema.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,23 @@ def test_schema_register():
125125
class MyType(ObjectType):
126126
type = StringField(resolve=lambda *_: 'Dog')
127127

128+
schema.query = MyType
129+
128130
assert schema.get_type('MyType') == MyType
129131

130132

133+
def test_schema_register():
134+
schema = Schema(name='My own schema')
135+
136+
@schema.register
137+
class MyType(ObjectType):
138+
type = StringField(resolve=lambda *_: 'Dog')
139+
140+
with raises(Exception) as excinfo:
141+
schema.get_type('MyType')
142+
assert 'base query type' in str(excinfo.value)
143+
144+
131145
def test_schema_introspect():
132146
schema = Schema(name='My own schema')
133147

@@ -138,4 +152,3 @@ class MyType(ObjectType):
138152

139153
introspection = schema.introspect()
140154
assert '__schema' in introspection
141-

tests/core/test_types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Meta:
3838

3939

4040
def test_interface():
41-
object_type = Character.internal_type(schema)
41+
object_type = schema.T(Character)
4242
assert Character._meta.is_interface is True
4343
assert isinstance(object_type, GraphQLInterfaceType)
4444
assert Character._meta.type_name == 'core_Character'
@@ -54,15 +54,15 @@ def test_interface_resolve_type():
5454

5555

5656
def test_object_type():
57-
object_type = Human.internal_type(schema)
57+
object_type = schema.T(Human)
5858
assert Human._meta.is_interface is False
5959
assert Human._meta.type_name == 'core_Human'
6060
assert isinstance(object_type, GraphQLObjectType)
6161
assert object_type.description == 'Human description'
6262
assert list(object_type.get_fields().keys()) == ['name', 'friends']
6363
# assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
6464
# schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
65-
assert object_type.get_interfaces() == [Character.internal_type(schema)]
65+
assert object_type.get_interfaces() == [schema.T(Character)]
6666
assert Human._meta.fields_map['name'].object_type == Human
6767

6868

0 commit comments

Comments
 (0)