mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +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
|
# For static type checking with Mypy
|
||||||
MYPY = False
|
MYPY = False
|
||||||
if MYPY:
|
if MYPY:
|
||||||
from typing import Dict # NOQA
|
from typing import Dict, Iterable, Type # NOQA
|
||||||
|
|
||||||
|
|
||||||
class InterfaceOptions(BaseOptions):
|
class InterfaceOptions(BaseOptions):
|
||||||
fields = None # type: Dict[str, Field]
|
fields = None # type: Dict[str, Field]
|
||||||
|
interfaces = () # type: Iterable[Type[Interface]]
|
||||||
|
|
||||||
|
|
||||||
class Interface(BaseType):
|
class Interface(BaseType):
|
||||||
|
@ -45,7 +46,7 @@ class Interface(BaseType):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __init_subclass_with_meta__(cls, _meta=None, **options):
|
def __init_subclass_with_meta__(cls, _meta=None, interfaces=(), **options):
|
||||||
if not _meta:
|
if not _meta:
|
||||||
_meta = InterfaceOptions(cls)
|
_meta = InterfaceOptions(cls)
|
||||||
|
|
||||||
|
@ -58,6 +59,9 @@ class Interface(BaseType):
|
||||||
else:
|
else:
|
||||||
_meta.fields = fields
|
_meta.fields = fields
|
||||||
|
|
||||||
|
if not _meta.interfaces:
|
||||||
|
_meta.interfaces = interfaces
|
||||||
|
|
||||||
super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options)
|
super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -233,11 +233,20 @@ class TypeMap(dict):
|
||||||
else None
|
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(
|
return GrapheneInterfaceType(
|
||||||
graphene_type=graphene_type,
|
graphene_type=graphene_type,
|
||||||
name=graphene_type._meta.name,
|
name=graphene_type._meta.name,
|
||||||
description=graphene_type._meta.description,
|
description=graphene_type._meta.description,
|
||||||
fields=partial(self.create_fields_for_type, graphene_type),
|
fields=partial(self.create_fields_for_type, graphene_type),
|
||||||
|
interfaces=interfaces,
|
||||||
resolve_type=resolve_type,
|
resolve_type=resolve_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,18 @@ def test_generate_interface():
|
||||||
|
|
||||||
|
|
||||||
def test_generate_interface_with_meta():
|
def test_generate_interface_with_meta():
|
||||||
|
class MyFirstInterface(Interface):
|
||||||
|
pass
|
||||||
|
|
||||||
class MyInterface(Interface):
|
class MyInterface(Interface):
|
||||||
class Meta:
|
class Meta:
|
||||||
name = "MyOtherInterface"
|
name = "MyOtherInterface"
|
||||||
description = "Documentation"
|
description = "Documentation"
|
||||||
|
interfaces = [MyFirstInterface]
|
||||||
|
|
||||||
assert MyInterface._meta.name == "MyOtherInterface"
|
assert MyInterface._meta.name == "MyOtherInterface"
|
||||||
assert MyInterface._meta.description == "Documentation"
|
assert MyInterface._meta.description == "Documentation"
|
||||||
|
assert MyInterface._meta.interfaces == [MyFirstInterface]
|
||||||
|
|
||||||
|
|
||||||
def test_generate_interface_with_fields():
|
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
|
||||||
assert graphql_type.is_type_of({}, None) is True
|
assert graphql_type.is_type_of({}, None) is True
|
||||||
assert graphql_type.is_type_of(MyObjectType(), None) is False
|
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