Improved Interface/ObjectType is_type_of abstraction

This commit is contained in:
Syrus Akbary 2016-06-19 14:29:41 -07:00
parent 907a093117
commit b772499b9b
2 changed files with 34 additions and 23 deletions

View File

@ -16,6 +16,16 @@ class GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):
class InterfaceTypeMeta(type):
@staticmethod
def _get_interface_options(meta):
return Options(
meta,
name=None,
description=None,
graphql_type=None,
abstract=False
)
def __new__(cls, name, bases, attrs):
super_new = super(InterfaceTypeMeta, cls).__new__
@ -24,13 +34,7 @@ class InterfaceTypeMeta(type):
if not is_base_type(bases, InterfaceTypeMeta):
return super_new(cls, name, bases, attrs)
options = Options(
attrs.pop('Meta', None),
name=None,
description=None,
graphql_type=None,
abstract=False
)
options = cls._get_interface_options(attrs.pop('Meta', None))
fields = get_fields(Interface, attrs, bases)
attrs = attrs_without_fields(attrs, fields)
@ -41,6 +45,7 @@ class InterfaceTypeMeta(type):
options.graphql_type = GrapheneInterfaceType(
graphene_type=cls,
name=options.name or cls.__name__,
resolve_type=cls.resolve_type,
description=options.description or cls.__doc__,
fields=fields,
)
@ -59,6 +64,7 @@ def attrs_without_fields(attrs, fields):
class Interface(six.with_metaclass(InterfaceTypeMeta)):
resolve_type = None
def __init__(self, *args, **kwargs):
from .objecttype import ObjectType

View File

@ -26,22 +26,6 @@ class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
if isinstance(interface, GrapheneInterfaceType):
interface.graphene_type.implements(self.graphene_type)
@property
def is_type_of(self):
return self._is_type_of or self.default_is_type_of
@is_type_of.setter
def is_type_of(self, is_type_of):
self._is_type_of = is_type_of
def default_is_type_of(self, interface, context, info):
from ..utils.get_graphql_type import get_graphql_type
try:
graphql_type = get_graphql_type(type(interface))
return graphql_type.name == self.name
except:
return False
def get_interfaces(interfaces):
from ..utils.get_graphql_type import get_graphql_type
@ -51,6 +35,13 @@ def get_interfaces(interfaces):
yield graphql_type
def is_objecttype(bases):
for base in bases:
if issubclass(base, ObjectType):
return True
return False
# We inherit from InterfaceTypeMeta instead of type for being able
# to have ObjectTypes extending Interfaces using Python syntax, like:
# class MyObjectType(ObjectType, MyInterface)
@ -61,9 +52,13 @@ class ObjectTypeMeta(InterfaceTypeMeta):
# Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself).
if not is_base_type(bases, ObjectTypeMeta):
return super_new(cls, name, bases, attrs)
if not is_objecttype(bases):
return super(ObjectTypeMeta, cls).__new__(cls, name, bases, attrs)
options = Options(
attrs.pop('Meta', None),
name=None,
@ -86,6 +81,7 @@ class ObjectTypeMeta(InterfaceTypeMeta):
name=options.name or cls.__name__,
description=options.description or cls.__doc__,
fields=fields,
is_type_of=cls.is_type_of,
interfaces=tuple(get_interfaces(interfaces + base_interfaces))
)
else:
@ -147,3 +143,12 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
raise TypeError(
"'%s' is an invalid keyword argument for this function" %
list(kwargs)[0])
@classmethod
def is_type_of(cls, interface, context, info):
from ..utils.get_graphql_type import get_graphql_type
try:
graphql_type = get_graphql_type(type(interface))
return graphql_type.name == cls._meta.graphql_type.name
except:
return False