|
1 |
| -from functools import partial |
| 1 | +from collections import OrderedDict |
2 | 2 |
|
3 |
| -import six |
4 |
| - |
5 |
| -from ..utils.is_base_type import is_base_type |
6 | 3 | from ..utils.get_unbound_function import get_unbound_function
|
7 | 4 | from ..utils.props import props
|
8 | 5 | from .field import Field
|
9 |
| -from .objecttype import ObjectType, ObjectTypeMeta |
10 |
| - |
11 |
| - |
12 |
| -class MutationMeta(ObjectTypeMeta): |
13 |
| - def __new__(cls, name, bases, attrs): |
14 |
| - # Also ensure initialization is only performed for subclasses of |
15 |
| - # Mutation |
16 |
| - if not is_base_type(bases, MutationMeta): |
17 |
| - return type.__new__(cls, name, bases, attrs) |
18 |
| - |
19 |
| - input_class = attrs.pop('Input', None) |
20 |
| - |
21 |
| - cls = ObjectTypeMeta.__new__(cls, name, bases, attrs) |
22 |
| - field_args = props(input_class) if input_class else {} |
23 |
| - output_class = getattr(cls, 'Output', cls) |
24 |
| - resolver = getattr(cls, 'mutate', None) |
| 6 | +from .utils import yank_fields_from_attrs |
| 7 | +from .objecttype import ObjectType, ObjectTypeOptions |
| 8 | + |
| 9 | +from .base import BaseOptions, BaseType |
| 10 | + |
| 11 | + |
| 12 | +class MutationOptions(ObjectTypeOptions): |
| 13 | + arguments = None # type: Dict[str, Argument] |
| 14 | + output = None # type: Type[ObjectType] |
| 15 | + resolver = None # type: Function |
| 16 | + |
| 17 | + |
| 18 | +class Mutation(ObjectType): |
| 19 | + ''' |
| 20 | + Mutation Type Definition |
| 21 | + ''' |
| 22 | + @classmethod |
| 23 | + def __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, **options): |
| 24 | + _meta = MutationOptions(cls) |
| 25 | + |
| 26 | + output = output or getattr(cls, 'Output', None) |
| 27 | + fields = {} |
| 28 | + if not output: |
| 29 | + # If output is defined, we don't need to get the fields |
| 30 | + fields = OrderedDict() |
| 31 | + for base in reversed(cls.__mro__): |
| 32 | + fields.update( |
| 33 | + yank_fields_from_attrs(base.__dict__, _as=Field) |
| 34 | + ) |
| 35 | + output = cls |
| 36 | + |
| 37 | + if not arguments: |
| 38 | + input_class = getattr(cls, 'Input', None) |
| 39 | + if input_class: |
| 40 | + arguments = props(input_class) |
| 41 | + else: |
| 42 | + arguments = {} |
| 43 | + |
| 44 | + resolver = resolver or get_unbound_function(getattr(cls, 'mutate', None)) |
25 | 45 | assert resolver, 'All mutations must define a mutate method in it'
|
26 |
| - resolver = get_unbound_function(resolver) |
27 |
| - cls.Field = partial( |
28 |
| - Field, output_class, args=field_args, resolver=resolver) |
29 |
| - return cls |
30 |
| - |
31 | 46 |
|
32 |
| -class Mutation(six.with_metaclass(MutationMeta, ObjectType)): |
33 |
| - pass |
| 47 | + _meta.fields = fields |
| 48 | + _meta.output = output |
| 49 | + _meta.resolver = resolver |
| 50 | + _meta.arguments = arguments |
| 51 | + |
| 52 | + super(Mutation, cls).__init_subclass_with_meta__(_meta=_meta, **options) |
| 53 | + |
| 54 | + @classmethod |
| 55 | + def Field(cls, *args, **kwargs): |
| 56 | + return Field( |
| 57 | + cls._meta.output, args=cls._meta.arguments, resolver=cls._meta.resolver |
| 58 | + ) |
0 commit comments