diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py index f87fd570..5266ef1c 100644 --- a/graphene/types/mutation.py +++ b/graphene/types/mutation.py @@ -5,6 +5,7 @@ from .objecttype import ObjectTypeMeta, ObjectType from .field import Field from ..utils.props import props +from ..utils.is_base_type import is_base_type class MutationMeta(ObjectTypeMeta): @@ -16,15 +17,22 @@ class MutationMeta(ObjectTypeMeta): assert resolver, 'All mutations must define a mutate method in it' return partial(Field, cls, args=field_args, resolver=resolver) - def construct(cls, bases, attrs): - super(MutationMeta, cls).construct(bases, attrs) - if not cls._meta.abstract and cls._construct_field: - Input = attrs.pop('Input', None) + def __new__(cls, name, bases, attrs): + super_new = super(MutationMeta, cls).__new__ + + # Also ensure initialization is only performed for subclasses of Model + # (excluding Model class itself). + if not is_base_type(bases, MutationMeta): + return type.__new__(cls, name, bases, attrs) + + Input = attrs.pop('Input', None) + + cls = super_new(cls, name, bases, attrs) + if cls._construct_field: field_args = props(Input) if Input else {} cls.Field = cls.construct_field(field_args) return cls class Mutation(six.with_metaclass(MutationMeta, ObjectType)): - class Meta: - abstract = True + pass diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py index 3ea63d52..37061822 100644 --- a/graphene/types/objecttype.py +++ b/graphene/types/objecttype.py @@ -124,6 +124,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)): # GraphQL ObjectType acting as container args_len = len(args) fields = self._meta.graphql_type.get_fields().values() + for f in fields: + setattr(self, getattr(f, 'attname', f.name), None) + if args_len > len(fields): # Daft, but matches old exception sans the err msg. raise IndexError("Number of args exceeds number of fields") diff --git a/graphene/types/tests/test_schema.py b/graphene/types/tests/test_schema.py index c3fd8ead..b42a9343 100644 --- a/graphene/types/tests/test_schema.py +++ b/graphene/types/tests/test_schema.py @@ -1,6 +1,6 @@ from ..scalars import String from ..field import Field -from ..objecttype import ObjectType, implements +from ..objecttype import ObjectType from ..interface import Interface from ..structures import List from ..schema import Schema diff --git a/graphene/utils/copy_fields.py b/graphene/utils/copy_fields.py index 59239a12..19c5ef38 100644 --- a/graphene/utils/copy_fields.py +++ b/graphene/utils/copy_fields.py @@ -5,7 +5,7 @@ from ..types.field import Field, InputField def copy_fields(like, fields, **extra): _fields = [] for attname, field in fields.items(): - field = like.copy_and_extend(field, attname=attname, **extra) + field = like.copy_and_extend(field, attname=getattr(field, 'attname', None) or attname, **extra) _fields.append(field) return OrderedDict((f.name, f) for f in _fields) diff --git a/graphene/utils/is_graphene_type.py b/graphene/utils/is_graphene_type.py index 963db8a8..d252fa44 100644 --- a/graphene/utils/is_graphene_type.py +++ b/graphene/utils/is_graphene_type.py @@ -3,17 +3,19 @@ import inspect def is_graphene_type(_type): from ..types.objecttype import ObjectType + from ..types.mutation import Mutation from ..types.inputobjecttype import InputObjectType from ..types.interface import Interface from ..types.scalars import Scalar from ..types.enum import Enum - if _type in [Interface, InputObjectType, ObjectType]: + if _type in [Interface, InputObjectType, ObjectType, Mutation]: return False return inspect.isclass(_type) and issubclass(_type, ( Interface, ObjectType, InputObjectType, Scalar, + Mutation, Enum ))