Improved schema type resolvers

This commit is contained in:
Syrus Akbary 2015-10-29 22:20:53 -07:00
parent 88196103f6
commit 55e2027dbb
9 changed files with 40 additions and 22 deletions

View File

@ -62,7 +62,7 @@ class DjangoModelField(Field):
self.object_type self.object_type
) )
) )
return _type and _type.internal_type(schema) or Field.SKIP return schema.T(_type) or Field.SKIP
def get_object_type(self, schema): def get_object_type(self, schema):
return get_type_for_model(schema, self.model) return get_type_for_model(schema, self.model)

View File

@ -114,7 +114,7 @@ class Field(object):
else: else:
object_type = self.get_object_type(schema) object_type = self.get_object_type(schema)
if object_type: if object_type:
field_type = object_type.internal_type(schema) field_type = schema.T(object_type)
field_type = self.type_wrapper(field_type) field_type = self.type_wrapper(field_type)
return field_type return field_type

View File

@ -25,6 +25,7 @@ class Schema(object):
def __init__(self, query=None, mutation=None, name='Schema', executor=None): def __init__(self, query=None, mutation=None, name='Schema', executor=None):
self._internal_types = {} self._internal_types = {}
self._types = {}
self.mutation = mutation self.mutation = mutation
self.query = query self.query = query
self.name = name self.name = name
@ -34,6 +35,13 @@ class Schema(object):
def __repr__(self): def __repr__(self):
return '<Schema: %s (%s)>' % (str(self.name), hash(self)) return '<Schema: %s (%s)>' % (str(self.name), hash(self))
def T(self, object_type):
if not object_type:
return
if object_type not in self._types:
self._types[object_type] = object_type.internal_type(self)
return self._types[object_type]
@property @property
def query(self): def query(self):
return self._query return self._query
@ -41,7 +49,6 @@ class Schema(object):
@query.setter @query.setter
def query(self, query): def query(self, query):
self._query = query self._query = query
self._query_type = query and query.internal_type(self)
@property @property
def mutation(self): def mutation(self):
@ -50,7 +57,6 @@ class Schema(object):
@mutation.setter @mutation.setter
def mutation(self, mutation): def mutation(self, mutation):
self._mutation = mutation self._mutation = mutation
self._mutation_type = mutation and mutation.internal_type(self)
@property @property
def executor(self): def executor(self):
@ -62,11 +68,11 @@ class Schema(object):
def executor(self, value): def executor(self, value):
self._executor = value self._executor = value
@cached_property @property
def schema(self): def schema(self):
if not self._query_type: if not self._query:
raise Exception('You have to define a base query type') raise Exception('You have to define a base query type')
return GraphQLSchema(self, query=self._query_type, mutation=self._mutation_type) return GraphQLSchema(self, query=self.T(self._query), mutation=self.T(self._mutation))
def associate_internal_type(self, internal_type, object_type): def associate_internal_type(self, internal_type, object_type):
self._internal_types[internal_type.name] = object_type self._internal_types[internal_type.name] = object_type
@ -76,6 +82,7 @@ class Schema(object):
return object_type return object_type
def get_type(self, type_name): def get_type(self, type_name):
self.schema._build_type_map()
if type_name not in self._internal_types: if type_name not in self._internal_types:
raise Exception('Type %s not found in %r' % (type_name, self)) raise Exception('Type %s not found in %r' % (type_name, self))
return self._internal_types[type_name] return self._internal_types[type_name]

View File

@ -179,15 +179,14 @@ class BaseObjectType(object):
@classmethod @classmethod
def resolve_objecttype(cls, schema, instance, *_): def resolve_objecttype(cls, schema, instance, *_):
return instance return instance.__class__
@classmethod @classmethod
def resolve_type(cls, schema, instance, *_): def resolve_type(cls, schema, instance, *_):
objecttype = cls.resolve_objecttype(schema, instance, *_) objecttype = cls.resolve_objecttype(schema, instance, *_)
return objecttype.internal_type(schema) return schema.T(objecttype)
@classmethod @classmethod
@memoize
@register_internal_type @register_internal_type
def internal_type(cls, schema): def internal_type(cls, schema):
fields = lambda: OrderedDict([(f.name, f.internal_field(schema)) fields = lambda: OrderedDict([(f.name, f.internal_field(schema))
@ -203,7 +202,7 @@ class BaseObjectType(object):
return GraphQLObjectType( return GraphQLObjectType(
cls._meta.type_name, cls._meta.type_name,
description=cls._meta.description, description=cls._meta.description,
interfaces=[i.internal_type(schema) for i in cls._meta.interfaces], interfaces=[schema.T(i) for i in cls._meta.interfaces],
fields=fields, fields=fields,
is_type_of=getattr(cls, 'is_type_of', None) is_type_of=getattr(cls, 'is_type_of', None)
) )
@ -225,7 +224,6 @@ class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
class InputObjectType(ObjectType): class InputObjectType(ObjectType):
@classmethod @classmethod
@memoize
@register_internal_type @register_internal_type
def internal_type(cls, schema): def internal_type(cls, schema):
fields = lambda: OrderedDict([(f.name, f.internal_field(schema)) fields = lambda: OrderedDict([(f.name, f.internal_field(schema))

View File

@ -63,8 +63,8 @@ class ConnectionField(Field):
node = self.get_object_type(schema) node = self.get_object_type(schema)
assert is_node(node), 'Only nodes have connections.' assert is_node(node), 'Only nodes have connections.'
schema.register(node) schema.register(node)
connection_type = self.get_connection_type(node)
return self.get_connection_type(node).internal_type(schema) return schema.T(connection_type)
class NodeField(Field): class NodeField(Field):

View File

@ -50,7 +50,7 @@ def test_django_interface():
def test_pseudo_interface(): def test_pseudo_interface():
object_type = Character.internal_type(schema) object_type = schema.T(Character)
assert Character._meta.is_interface is True assert Character._meta.is_interface is True
assert isinstance(object_type, GraphQLInterfaceType) assert isinstance(object_type, GraphQLInterfaceType)
assert Character._meta.model == Reporter assert Character._meta.model == Reporter
@ -81,7 +81,7 @@ def test_interface_resolve_type():
def test_object_type(): def test_object_type():
object_type = Human.internal_type(schema) object_type = schema.T(Human)
fields_map = Human._meta.fields_map fields_map = Human._meta.fields_map
assert Human._meta.is_interface is False assert Human._meta.is_interface is False
assert isinstance(object_type, GraphQLObjectType) assert isinstance(object_type, GraphQLObjectType)
@ -95,7 +95,7 @@ def test_object_type():
# 'reporter': fields_map['reporter'].internal_field(schema), # 'reporter': fields_map['reporter'].internal_field(schema),
# 'pubDate': fields_map['pub_date'].internal_field(schema), # 'pubDate': fields_map['pub_date'].internal_field(schema),
# } # }
assert DjangoNode.internal_type(schema) in object_type.get_interfaces() assert schema.T(DjangoNode) in object_type.get_interfaces()
def test_node_notinterface(): def test_node_notinterface():

View File

@ -46,7 +46,7 @@ class Human(Character):
schema = Schema() schema = Schema()
Human_type = Human.internal_type(schema) Human_type = schema.T(Human)
def test_type(): def test_type():

View File

@ -125,9 +125,23 @@ def test_schema_register():
class MyType(ObjectType): class MyType(ObjectType):
type = StringField(resolve=lambda *_: 'Dog') type = StringField(resolve=lambda *_: 'Dog')
schema.query = MyType
assert schema.get_type('MyType') == MyType assert schema.get_type('MyType') == MyType
def test_schema_register():
schema = Schema(name='My own schema')
@schema.register
class MyType(ObjectType):
type = StringField(resolve=lambda *_: 'Dog')
with raises(Exception) as excinfo:
schema.get_type('MyType')
assert 'base query type' in str(excinfo.value)
def test_schema_introspect(): def test_schema_introspect():
schema = Schema(name='My own schema') schema = Schema(name='My own schema')
@ -138,4 +152,3 @@ def test_schema_introspect():
introspection = schema.introspect() introspection = schema.introspect()
assert '__schema' in introspection assert '__schema' in introspection

View File

@ -38,7 +38,7 @@ schema = Schema()
def test_interface(): def test_interface():
object_type = Character.internal_type(schema) object_type = schema.T(Character)
assert Character._meta.is_interface is True assert Character._meta.is_interface is True
assert isinstance(object_type, GraphQLInterfaceType) assert isinstance(object_type, GraphQLInterfaceType)
assert Character._meta.type_name == 'core_Character' assert Character._meta.type_name == 'core_Character'
@ -54,7 +54,7 @@ def test_interface_resolve_type():
def test_object_type(): def test_object_type():
object_type = Human.internal_type(schema) object_type = schema.T(Human)
assert Human._meta.is_interface is False assert Human._meta.is_interface is False
assert Human._meta.type_name == 'core_Human' assert Human._meta.type_name == 'core_Human'
assert isinstance(object_type, GraphQLObjectType) assert isinstance(object_type, GraphQLObjectType)
@ -62,7 +62,7 @@ def test_object_type():
assert list(object_type.get_fields().keys()) == ['name', 'friends'] assert list(object_type.get_fields().keys()) == ['name', 'friends']
# assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field( # assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
# schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)} # schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
assert object_type.get_interfaces() == [Character.internal_type(schema)] assert object_type.get_interfaces() == [schema.T(Character)]
assert Human._meta.fields_map['name'].object_type == Human assert Human._meta.fields_map['name'].object_type == Human