mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Improved Interface/ObjectType is_type_of abstraction
This commit is contained in:
		
							parent
							
								
									907a093117
								
							
						
					
					
						commit
						b772499b9b
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user