mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-10 19:56:45 +03:00
Merge pull request #1304 from closeio/support-interface-implementations
Add support for interfaces on interfaces
This commit is contained in:
commit
c77d87d205
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue
Block a user