Let the interfaces be immutable

This commit is contained in:
Syrus Akbary 2016-06-06 00:18:23 -07:00
parent b17f081906
commit 77ec170dd5
2 changed files with 28 additions and 20 deletions

View File

@ -61,5 +61,5 @@ class Node(six.with_metaclass(NodeMeta, Interface)):
in it in it
''' '''
if cls.require_get_node(): if cls.require_get_node():
assert hasattr(object_type, 'get_node'), '{}.get_node method is required by the Node interface.'.format(object_type._meta.graphql_type.name) assert hasattr(object_type, 'get_node'), '{}.get_node method is required by the Node interface.'.format(object_type.__name__)
return super(Node, cls).implements(object_type) return super(Node, cls).implements(object_type)

View File

@ -1,3 +1,4 @@
import copy
import six import six
from graphql import GraphQLObjectType from graphql import GraphQLObjectType
@ -8,6 +9,15 @@ from .interface import GrapheneInterfaceType
class GrapheneObjectType(GrapheneFieldsType, GraphQLObjectType): class GrapheneObjectType(GrapheneFieldsType, GraphQLObjectType):
def __init__(self, *args, **kwargs):
super(GrapheneObjectType, self).__init__(*args, **kwargs)
self.check_interfaces()
def check_interfaces(self):
for interface in self._provided_interfaces:
if isinstance(interface, GrapheneInterfaceType):
interface.graphene_type.implements(self.graphene_type)
@property @property
def is_type_of(self): def is_type_of(self):
return self._is_type_of or self.default_is_type_of return self._is_type_of or self.default_is_type_of
@ -20,22 +30,17 @@ class GrapheneObjectType(GrapheneFieldsType, GraphQLObjectType):
from ..utils.get_graphql_type import get_graphql_type from ..utils.get_graphql_type import get_graphql_type
try: try:
graphql_type = get_graphql_type(type(interface)) graphql_type = get_graphql_type(type(interface))
return graphql_type == self return graphql_type.name == self.name
except: except:
return False return False
def add_interface(self, interface):
def get_interfaces(cls, interfaces):
from ..utils.get_graphql_type import get_graphql_type from ..utils.get_graphql_type import get_graphql_type
# We clear the cached interfaces
self._interfaces = None for interface in interfaces:
# We clear the cached fields as could be inherited from interfaces
self._field_map = None
graphql_type = get_graphql_type(interface) graphql_type = get_graphql_type(interface)
yield graphql_type
if isinstance(graphql_type, GrapheneInterfaceType):
graphql_type.graphene_type.implements(self.graphene_type)
self._provided_interfaces.append(graphql_type)
class ObjectTypeMeta(ClassTypeMeta): class ObjectTypeMeta(ClassTypeMeta):
@ -50,9 +55,11 @@ class ObjectTypeMeta(ClassTypeMeta):
abstract=False abstract=False
) )
def get_interfaces(cls):
return get_interfaces(cls, cls._meta.interfaces)
def construct_graphql_type(cls, bases): def construct_graphql_type(cls, bases):
if not cls._meta.graphql_type and not cls._meta.abstract: if not cls._meta.graphql_type and not cls._meta.abstract:
from ..utils.get_graphql_type import get_graphql_type
from ..utils.is_graphene_type import is_graphene_type from ..utils.is_graphene_type import is_graphene_type
inherited_types = [ inherited_types = [
base._meta.graphql_type for base in bases if is_graphene_type(base) base._meta.graphql_type for base in bases if is_graphene_type(base)
@ -63,19 +70,20 @@ class ObjectTypeMeta(ClassTypeMeta):
name=cls._meta.name or cls.__name__, name=cls._meta.name or cls.__name__,
description=cls._meta.description, description=cls._meta.description,
fields=FieldMap(cls, bases=filter(None, inherited_types)), fields=FieldMap(cls, bases=filter(None, inherited_types)),
interfaces=[], interfaces=list(cls.get_interfaces()),
) )
for interface in cls._meta.interfaces:
cls._meta.graphql_type.add_interface(interface)
def implements(*interfaces): def implements(*interfaces):
# This function let us decorate a ObjectType # This function let us decorate a ObjectType
# Adding a specified interfaces into the graphql_type # Adding a specified interfaces into the graphql_type
def wrap_class(cls): def wrap_class(cls):
interface_types = get_interfaces(cls, interfaces)
for i in interfaces: graphql_type = cls._meta.graphql_type
cls._meta.graphql_type.add_interface(i) new_type = copy.copy(graphql_type)
new_type._provided_interfaces.extend(interface_types)
cls._meta.graphql_type = new_type
cls._meta.graphql_type.check_interfaces()
return cls return cls
return wrap_class return wrap_class