From 18270993815ef0d9fca9dc682de507b0e052d6ef Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 21 Jun 2016 17:30:33 -0700 Subject: [PATCH] Added get_fields to options --- graphene/relay/connection.py | 4 ++++ graphene/relay/mutation.py | 2 ++ graphene/relay/node.py | 25 ++++++++++++++++--------- graphene/types/mutation.py | 8 +++----- graphene/types/objecttype.py | 14 +++++++------- graphene/utils/get_fields.py | 2 +- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index 02b3dbe5..e88d1b82 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -54,6 +54,10 @@ class ConnectionMeta(ObjectTypeMeta): ) cls.Edge = type(edge.name, (ObjectType, ), {'Meta': type('Meta', (object,), {'graphql_type': edge})}) cls._meta.graphql_type = connection + fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls) + + cls._meta.get_fields = lambda: fields + return cls diff --git a/graphene/relay/mutation.py b/graphene/relay/mutation.py index f5fbec83..24a828a0 100644 --- a/graphene/relay/mutation.py +++ b/graphene/relay/mutation.py @@ -52,6 +52,8 @@ class ClientIDMutationMeta(MutationMeta): mutate_and_get_payload=cls.mutate_and_get_payload, ) options.graphql_type = field.type + options.get_fields = lambda: output_fields + cls.Field = partial(Field.copy_and_extend, field, type=field.type, _creation_counter=None) return cls diff --git a/graphene/relay/node.py b/graphene/relay/node.py index 4467746d..e0d6f3d1 100644 --- a/graphene/relay/node.py +++ b/graphene/relay/node.py @@ -10,6 +10,8 @@ from ..types.objecttype import ObjectType, ObjectTypeMeta, is_objecttype from ..types.options import Options from .connection import Connection +from ..utils.copy_fields import copy_fields + # We inherit from ObjectTypeMeta as we want to allow # inheriting from Node, and also ObjectType. @@ -23,16 +25,17 @@ class NodeMeta(ObjectTypeMeta): meta, ) - def __new__(cls, name, bases, attrs): - - if is_objecttype(bases): - cls = super(NodeMeta, cls).__new__(cls, name, bases, attrs) - # The interface provided by node_definitions is not an instance - # of GrapheneInterfaceType, so it will have no graphql_type, - # so will not trigger Node.implements - cls.implements(cls) - return cls + @staticmethod + def _create_objecttype(cls, name, bases, attrs): + # The interface provided by node_definitions is not an instance + # of GrapheneInterfaceType, so it will have no graphql_type, + # so will not trigger Node.implements + cls = super(NodeMeta, cls)._create_objecttype(cls, name, bases, attrs) + cls.implements(cls) + return cls + @staticmethod + def _create_interface(cls, name, bases, attrs): options = cls._get_interface_options(attrs.pop('Meta', None)) cls = type.__new__(cls, name, bases, dict(attrs, _meta=options)) @@ -45,6 +48,10 @@ class NodeMeta(ObjectTypeMeta): type_resolver=cls.resolve_type, ) options.graphql_type = node_interface + + fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls) + options.get_fields = lambda: fields + cls.Field = partial( Field.copy_and_extend, node_field, diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py index ee015d76..6874ae3d 100644 --- a/graphene/types/mutation.py +++ b/graphene/types/mutation.py @@ -11,16 +11,14 @@ from .objecttype import ObjectType, ObjectTypeMeta class MutationMeta(ObjectTypeMeta): 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). + # 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 = attrs.pop('Input', None) - cls = super_new(cls, name, bases, attrs) + cls = cls._create_objecttype(cls, name, bases, attrs) field_args = props(Input) if Input else {} resolver = getattr(cls, 'mutate', None) assert resolver, 'All mutations must define a mutate method in it' diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py index 19a06dac..19f5e2c8 100644 --- a/graphene/types/objecttype.py +++ b/graphene/types/objecttype.py @@ -56,7 +56,7 @@ class ObjectTypeMeta(type): super_new = type.__new__ # Also ensure initialization is only performed for subclasses of - # ObjectType, Interfaces + # ObjectType,or Interfaces if not is_base_type(bases, ObjectTypeMeta): return type.__new__(cls, name, bases, attrs) @@ -100,7 +100,9 @@ class ObjectTypeMeta(type): ) else: assert not fields, "Can't mount Fields in an Interface with a defined graphql_type" - fields = copy_fields(options.graphql_type.get_fields(), parent=cls) + fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls) + + options.get_fields = lambda: fields for name, field in fields.items(): setattr(cls, field.attname or name, field) @@ -138,6 +140,8 @@ class ObjectTypeMeta(type): assert not fields, "Can't mount Fields in an ObjectType with a defined graphql_type" fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls) + options.get_fields = lambda: fields + for name, field in fields.items(): setattr(cls, field.attname or name, field) @@ -149,11 +153,7 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)): def __init__(self, *args, **kwargs): # GraphQL ObjectType acting as container args_len = len(args) - _fields = self._meta.graphql_type._fields - if callable(_fields): - _fields = _fields() - - fields = _fields.items() + fields = self._meta.get_fields().items() for name, f in fields: setattr(self, getattr(f, 'attname', name), None) diff --git a/graphene/utils/get_fields.py b/graphene/utils/get_fields.py index 13ba2dae..4e18de67 100644 --- a/graphene/utils/get_fields.py +++ b/graphene/utils/get_fields.py @@ -21,7 +21,7 @@ def get_fields_from_bases_and_types(bases, types): for _class in bases: if not is_graphene_type(_class): continue - _fields = get_graphql_type(_class)._fields + _fields = _class._meta.get_fields() if callable(_fields): _fields = _fields()