diff --git a/graphene/relay/node.py b/graphene/relay/node.py index aa6e2dc0..b129adbf 100644 --- a/graphene/relay/node.py +++ b/graphene/relay/node.py @@ -6,7 +6,7 @@ from graphql_relay import from_global_id, to_global_id from ..types import ID, Field, Interface, ObjectType from ..types.utils import get_type -from ..types.interface import InterfaceMeta +from ..types.interface import InterfaceOptions def is_node(objecttype): @@ -22,18 +22,6 @@ def is_node(objecttype): return False -def get_default_connection(cls): - from .connection import Connection - assert issubclass(cls, ObjectType), ( - 'Can only get connection type on implemented Nodes.' - ) - - class Meta: - node = cls - - return type('{}Connection'.format(cls.__name__), (Connection,), {'Meta': Meta}) - - class GlobalID(Field): def __init__(self, node=None, parent_type=None, required=True, *args, **kwargs): @@ -51,14 +39,6 @@ class GlobalID(Field): return partial(self.id_resolver, parent_resolver, self.node, parent_type_name=self.parent_type_name) -class NodeMeta(InterfaceMeta): - - def __new__(cls, name, bases, attrs): - cls = InterfaceMeta.__new__(cls, name, bases, attrs) - cls._meta.fields['id'] = GlobalID(cls, description='The ID of the object.') - return cls - - class NodeField(Field): def __init__(self, node, type=False, deprecation_reason=None, @@ -78,9 +58,16 @@ class NodeField(Field): return partial(self.node_type.node_resolver, only_type=get_type(self.field_type)) -class Node(six.with_metaclass(NodeMeta, Interface)): +class Node(Interface): '''An object with an ID''' + def __init_subclass_with_meta__(cls, **options): + _meta = InterfaceOptions(cls) + _meta.fields = { + 'id': GlobalID(cls, description='The ID of the object.') + } + super(Node, cls).__init_subclass_with_meta__(cls, _meta=_meta, **options) + @classmethod def Field(cls, *args, **kwargs): # noqa: N802 return NodeField(cls, *args, **kwargs) @@ -117,11 +104,3 @@ class Node(six.with_metaclass(NodeMeta, Interface)): @classmethod def to_global_id(cls, type, id): return to_global_id(type, id) - - @classmethod - def implements(cls, objecttype): - get_connection = getattr(objecttype, 'get_connection', None) - if not get_connection: - get_connection = partial(get_default_connection, objecttype) - - objecttype.Connection = get_connection() diff --git a/graphene/types/interface.py b/graphene/types/interface.py index adbd7c5c..dc7c34cc 100644 --- a/graphene/types/interface.py +++ b/graphene/types/interface.py @@ -19,16 +19,21 @@ class Interface(BaseType): when the field is resolved. ''' @classmethod - def __init_subclass_with_meta__(cls, **options): - _meta = InterfaceOptions(cls) + def __init_subclass_with_meta__(cls, _meta=None, **options): + if not _meta: + _meta = InterfaceOptions(cls) fields = OrderedDict() for base in reversed(cls.__mro__): fields.update( yank_fields_from_attrs(base.__dict__, _as=Field) ) + + if _meta.fields: + _meta.fields.update(fields) + else: + _meta.fields = fields - _meta.fields = fields super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options) @classmethod diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py index 9ef75df7..e6ade33e 100644 --- a/graphene/types/mutation.py +++ b/graphene/types/mutation.py @@ -35,7 +35,12 @@ class Mutation(ObjectType): output = cls if not arguments: - input_class = getattr(cls, 'Input', None) + input_class = getattr(cls, 'Arguments', None) + if not input_class: + input_class = getattr(cls, 'Input', None) + if input_class: + print("WARNING: Please use Arguments for Mutation (Input is for ClientMutationID)") + if input_class: arguments = props(input_class) else: diff --git a/graphene/types/tests/test_options.py b/graphene/types/tests/test_options.py deleted file mode 100644 index fbcba2db..00000000 --- a/graphene/types/tests/test_options.py +++ /dev/null @@ -1,30 +0,0 @@ -import pytest - -from ..options import Options - - -def test_options(): - class BaseOptions: - option_1 = False - name = True - meta = Options(BaseOptions, name=False, option_1=False) - assert meta.name == True - assert meta.option_1 == False - - -def test_options_extra_attrs(): - class BaseOptions: - name = True - type = True - - with pytest.raises(Exception) as exc_info: - meta = Options(BaseOptions) - - assert str(exc_info.value) == 'Invalid attributes: name, type' - - -def test_options_repr(): - class BaseOptions: - name = True - meta = Options(BaseOptions, name=False) - assert repr(meta) == ''