Skip to content

Commit

Permalink
Merge pull request #1304 from closeio/support-interface-implementations
Browse files Browse the repository at this point in the history
Add support for interfaces on interfaces
  • Loading branch information
erikwrede committed Aug 13, 2022
2 parents 8bdcec5 + 7004515 commit c77d87d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
8 changes: 6 additions & 2 deletions graphene/types/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
# 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):
Expand Down Expand Up @@ -45,7 +46,7 @@ class Meta:
"""

@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)

Expand All @@ -58,6 +59,9 @@ def __init_subclass_with_meta__(cls, _meta=None, **options):
else:
_meta.fields = fields

if not _meta.interfaces:
_meta.interfaces = interfaces

super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options)

@classmethod
Expand Down
9 changes: 9 additions & 0 deletions graphene/types/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,20 @@ def create_interface(self, graphene_type):
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,
)

Expand Down
5 changes: 5 additions & 0 deletions graphene/types/tests/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ class MyInterface(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():
Expand Down
30 changes: 30 additions & 0 deletions graphene/types/tests/test_type_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,33 @@ class Meta:
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]

0 comments on commit c77d87d

Please sign in to comment.