From 2d557d6ed729063834dd3c6b39c6584e8a183ab2 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 11 Jul 2017 21:16:41 -0700 Subject: [PATCH] Simplified mutation --- graphene/types/mutation.py | 79 ++++++++++++++++++++++++------------ graphene/types/objecttype.py | 5 ++- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py index 2e8e120aa..4b662f0d6 100644 --- a/graphene/types/mutation.py +++ b/graphene/types/mutation.py @@ -1,33 +1,58 @@ -from functools import partial +from collections import OrderedDict -import six - -from ..utils.is_base_type import is_base_type from ..utils.get_unbound_function import get_unbound_function from ..utils.props import props from .field import Field -from .objecttype import ObjectType, ObjectTypeMeta - - -class MutationMeta(ObjectTypeMeta): - def __new__(cls, name, bases, attrs): - # Also ensure initialization is only performed for subclasses of - # Mutation - if not is_base_type(bases, MutationMeta): - return type.__new__(cls, name, bases, attrs) - - input_class = attrs.pop('Input', None) - - cls = ObjectTypeMeta.__new__(cls, name, bases, attrs) - field_args = props(input_class) if input_class else {} - output_class = getattr(cls, 'Output', cls) - resolver = getattr(cls, 'mutate', None) +from .utils import yank_fields_from_attrs +from .objecttype import ObjectType, ObjectTypeOptions + +from .base import BaseOptions, BaseType + + +class MutationOptions(ObjectTypeOptions): + arguments = None # type: Dict[str, Argument] + output = None # type: Type[ObjectType] + resolver = None # type: Function + + +class Mutation(ObjectType): + ''' + Mutation Type Definition + ''' + @classmethod + def __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, **options): + _meta = MutationOptions(cls) + + output = output or getattr(cls, 'Output', None) + fields = {} + if not output: + # If output is defined, we don't need to get the fields + fields = OrderedDict() + for base in reversed(cls.__mro__): + fields.update( + yank_fields_from_attrs(base.__dict__, _as=Field) + ) + output = cls + + if not arguments: + input_class = getattr(cls, 'Input', None) + if input_class: + arguments = props(input_class) + else: + arguments = {} + + resolver = resolver or get_unbound_function(getattr(cls, 'mutate', None)) assert resolver, 'All mutations must define a mutate method in it' - resolver = get_unbound_function(resolver) - cls.Field = partial( - Field, output_class, args=field_args, resolver=resolver) - return cls - -class Mutation(six.with_metaclass(MutationMeta, ObjectType)): - pass + _meta.fields = fields + _meta.output = output + _meta.resolver = resolver + _meta.arguments = arguments + + super(Mutation, cls).__init_subclass_with_meta__(_meta=_meta, **options) + + @classmethod + def Field(cls, *args, **kwargs): + return Field( + cls._meta.output, args=cls._meta.arguments, resolver=cls._meta.resolver + ) diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py index ac591e058..e641867a5 100644 --- a/graphene/types/objecttype.py +++ b/graphene/types/objecttype.py @@ -23,8 +23,9 @@ class ObjectType(BaseType): have a name, but most importantly describe their fields. ''' @classmethod - def __init_subclass_with_meta__(cls, interfaces=(), possible_types=(), default_resolver=None, **options): - _meta = ObjectTypeOptions(cls) + def __init_subclass_with_meta__(cls, interfaces=(), possible_types=(), default_resolver=None, _meta=None, **options): + if not _meta: + _meta = ObjectTypeOptions(cls) fields = OrderedDict()