Add interfaces meta argument on Mutations (#1023)

This commit is contained in:
Ntale Shadik 2019-07-24 20:44:22 +03:00 committed by Jonathan Kim
parent 6e4058960d
commit c96bd680d7
3 changed files with 28 additions and 5 deletions

View File

@ -6,18 +6,20 @@ from ..utils.props import props
from .field import Field from .field import Field
from .objecttype import ObjectType, ObjectTypeOptions from .objecttype import ObjectType, ObjectTypeOptions
from .utils import yank_fields_from_attrs from .utils import yank_fields_from_attrs
from .interface import Interface
# For static type checking with Mypy # For static type checking with Mypy
MYPY = False MYPY = False
if MYPY: if MYPY:
from .argument import Argument # NOQA from .argument import Argument # NOQA
from typing import Dict, Type, Callable # NOQA from typing import Dict, Type, Callable, Iterable # NOQA
class MutationOptions(ObjectTypeOptions): class MutationOptions(ObjectTypeOptions):
arguments = None # type: Dict[str, Argument] arguments = None # type: Dict[str, Argument]
output = None # type: Type[ObjectType] output = None # type: Type[ObjectType]
resolver = None # type: Callable resolver = None # type: Callable
interfaces = () # type: Iterable[Type[Interface]]
class Mutation(ObjectType): class Mutation(ObjectType):
@ -58,8 +60,7 @@ class Mutation(ObjectType):
name. name.
description (str): Description of the GraphQL type in the schema. Defaults to class description (str): Description of the GraphQL type in the schema. Defaults to class
docstring. docstring.
interfaces (Iterable[graphene.Interface]): NOT IMPLEMENTED (use ``output`` to define a interfaces (Iterable[graphene.Interface]): GraphQL interfaces to extend with the payload
payload implementing interfaces). GraphQL interfaces to extend with the payload
object. All fields from interface will be included in this object's schema. object. All fields from interface will be included in this object's schema.
fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to
use (prefer class attributes or ``Meta.output``). use (prefer class attributes or ``Meta.output``).
@ -67,13 +68,26 @@ class Mutation(ObjectType):
@classmethod @classmethod
def __init_subclass_with_meta__( def __init_subclass_with_meta__(
cls, resolver=None, output=None, arguments=None, _meta=None, **options cls,
interfaces=(),
resolver=None,
output=None,
arguments=None,
_meta=None,
**options
): ):
if not _meta: if not _meta:
_meta = MutationOptions(cls) _meta = MutationOptions(cls)
output = output or getattr(cls, "Output", None) output = output or getattr(cls, "Output", None)
fields = {} fields = {}
for interface in interfaces:
assert issubclass(interface, Interface), (
'All interfaces of {} must be a subclass of Interface. Received "{}".'
).format(cls.__name__, interface)
fields.update(interface._meta.fields)
if not output: if not output:
# If output is defined, we don't need to get the fields # If output is defined, we don't need to get the fields
fields = OrderedDict() fields = OrderedDict()
@ -110,6 +124,7 @@ class Mutation(ObjectType):
else: else:
_meta.fields = fields _meta.fields = fields
_meta.interfaces = interfaces
_meta.output = output _meta.output = output
_meta.resolver = resolver _meta.resolver = resolver
_meta.arguments = arguments _meta.arguments = arguments

View File

@ -121,7 +121,8 @@ class ObjectType(BaseType):
else: else:
_meta.fields = fields _meta.fields = fields
_meta.interfaces = interfaces if not _meta.interfaces:
_meta.interfaces = interfaces
_meta.possible_types = possible_types _meta.possible_types = possible_types
_meta.default_resolver = default_resolver _meta.default_resolver = default_resolver

View File

@ -7,6 +7,11 @@ from ..objecttype import ObjectType
from ..scalars import String from ..scalars import String
from ..schema import Schema from ..schema import Schema
from ..structures import NonNull from ..structures import NonNull
from ..interface import Interface
class MyType(Interface):
pass
def test_generate_mutation_no_args(): def test_generate_mutation_no_args():
@ -28,12 +33,14 @@ def test_generate_mutation_with_meta():
class Meta: class Meta:
name = "MyOtherMutation" name = "MyOtherMutation"
description = "Documentation" description = "Documentation"
interfaces = (MyType,)
def mutate(self, info, **args): def mutate(self, info, **args):
return args return args
assert MyMutation._meta.name == "MyOtherMutation" assert MyMutation._meta.name == "MyOtherMutation"
assert MyMutation._meta.description == "Documentation" assert MyMutation._meta.description == "Documentation"
assert MyMutation._meta.interfaces == (MyType,)
resolved = MyMutation.Field().resolver(None, None, name="Peter") resolved = MyMutation.Field().resolver(None, None, name="Peter")
assert resolved == {"name": "Peter"} assert resolved == {"name": "Peter"}