Merge pull request #1304 from closeio/support-interface-implementations

Add support for interfaces on interfaces
This commit is contained in:
Erik Wrede 2022-08-13 14:28:17 +02:00 committed by GitHub
commit c77d87d205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 2 deletions

View File

@ -5,11 +5,12 @@ from .utils import yank_fields_from_attrs
# For static type checking with Mypy
MYPY = False
if MYPY:
from typing import Dict # NOQA
from typing import Dict, Iterable, Type # NOQA
class InterfaceOptions(BaseOptions):
fields = None # type: Dict[str, Field]
interfaces = () # type: Iterable[Type[Interface]]
class Interface(BaseType):
@ -45,7 +46,7 @@ class Interface(BaseType):
"""
@classmethod
def __init_subclass_with_meta__(cls, _meta=None, **options):
def __init_subclass_with_meta__(cls, _meta=None, interfaces=(), **options):
if not _meta:
_meta = InterfaceOptions(cls)
@ -58,6 +59,9 @@ class Interface(BaseType):
else:
_meta.fields = fields
if not _meta.interfaces:
_meta.interfaces = interfaces
super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options)
@classmethod

View File

@ -233,11 +233,20 @@ class TypeMap(dict):
else None
)
def interfaces():
interfaces = []
for graphene_interface in graphene_type._meta.interfaces:
interface = self.add_type(graphene_interface)
assert interface.graphene_type == graphene_interface
interfaces.append(interface)
return interfaces
return GrapheneInterfaceType(
graphene_type=graphene_type,
name=graphene_type._meta.name,
description=graphene_type._meta.description,
fields=partial(self.create_fields_for_type, graphene_type),
interfaces=interfaces,
resolve_type=resolve_type,
)

View File

@ -25,13 +25,18 @@ def test_generate_interface():
def test_generate_interface_with_meta():
class MyFirstInterface(Interface):
pass
class MyInterface(Interface):
class Meta:
name = "MyOtherInterface"
description = "Documentation"
interfaces = [MyFirstInterface]
assert MyInterface._meta.name == "MyOtherInterface"
assert MyInterface._meta.description == "Documentation"
assert MyInterface._meta.interfaces == [MyFirstInterface]
def test_generate_interface_with_fields():

View File

@ -289,3 +289,33 @@ def test_objecttype_with_possible_types():
assert graphql_type.is_type_of
assert graphql_type.is_type_of({}, None) is True
assert graphql_type.is_type_of(MyObjectType(), None) is False
def test_interface_with_interfaces():
class FooInterface(Interface):
foo = String()
class BarInterface(Interface):
class Meta:
interfaces = [FooInterface]
foo = String()
bar = String()
type_map = create_type_map([FooInterface, BarInterface])
assert "FooInterface" in type_map
foo_graphql_type = type_map["FooInterface"]
assert isinstance(foo_graphql_type, GraphQLInterfaceType)
assert foo_graphql_type.name == "FooInterface"
assert "BarInterface" in type_map
bar_graphql_type = type_map["BarInterface"]
assert isinstance(bar_graphql_type, GraphQLInterfaceType)
assert bar_graphql_type.name == "BarInterface"
fields = bar_graphql_type.fields
assert list(fields) == ["foo", "bar"]
assert isinstance(fields["foo"], GraphQLField)
assert isinstance(fields["bar"], GraphQLField)
assert bar_graphql_type.interfaces == [foo_graphql_type]