mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-08 23:50:38 +03:00
Merge branch '1.0-django-interfaceobjecttype' of github.com:graphql-python/graphene into 1.0-django-interfaceobjecttype
# Conflicts: # graphene/types/objecttype.py
This commit is contained in:
commit
f2ed1e58d9
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
from ..schema import Droid
|
|
||||||
|
|
||||||
|
|
||||||
def test_query_types():
|
|
||||||
graphql_type = Droid._meta.graphql_type
|
|
||||||
fields = graphql_type.get_fields()
|
|
||||||
assert fields['friends'].parent == Droid
|
|
||||||
assert fields
|
|
|
@ -54,6 +54,10 @@ class ConnectionMeta(ObjectTypeMeta):
|
||||||
)
|
)
|
||||||
cls.Edge = type(edge.name, (ObjectType, ), {'Meta': type('Meta', (object,), {'graphql_type': edge})})
|
cls.Edge = type(edge.name, (ObjectType, ), {'Meta': type('Meta', (object,), {'graphql_type': edge})})
|
||||||
cls._meta.graphql_type = connection
|
cls._meta.graphql_type = connection
|
||||||
|
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
||||||
|
|
||||||
|
cls._meta.get_fields = lambda: fields
|
||||||
|
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ class ClientIDMutationMeta(MutationMeta):
|
||||||
mutate_and_get_payload=cls.mutate_and_get_payload,
|
mutate_and_get_payload=cls.mutate_and_get_payload,
|
||||||
)
|
)
|
||||||
options.graphql_type = field.type
|
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)
|
cls.Field = partial(Field.copy_and_extend, field, type=field.type, _creation_counter=None)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ from ..types.objecttype import ObjectType, ObjectTypeMeta, is_objecttype
|
||||||
from ..types.options import Options
|
from ..types.options import Options
|
||||||
from .connection import Connection
|
from .connection import Connection
|
||||||
|
|
||||||
|
from ..utils.copy_fields import copy_fields
|
||||||
|
|
||||||
|
|
||||||
# We inherit from ObjectTypeMeta as we want to allow
|
# We inherit from ObjectTypeMeta as we want to allow
|
||||||
# inheriting from Node, and also ObjectType.
|
# inheriting from Node, and also ObjectType.
|
||||||
|
@ -23,16 +25,17 @@ class NodeMeta(ObjectTypeMeta):
|
||||||
meta,
|
meta,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
@staticmethod
|
||||||
|
def _create_objecttype(cls, name, bases, attrs):
|
||||||
if is_objecttype(bases):
|
# The interface provided by node_definitions is not an instance
|
||||||
cls = super(NodeMeta, cls).__new__(cls, name, bases, attrs)
|
# of GrapheneInterfaceType, so it will have no graphql_type,
|
||||||
# The interface provided by node_definitions is not an instance
|
# so will not trigger Node.implements
|
||||||
# of GrapheneInterfaceType, so it will have no graphql_type,
|
cls = super(NodeMeta, cls)._create_objecttype(cls, name, bases, attrs)
|
||||||
# so will not trigger Node.implements
|
cls.implements(cls)
|
||||||
cls.implements(cls)
|
return cls
|
||||||
return cls
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_interface(cls, name, bases, attrs):
|
||||||
options = cls._get_interface_options(attrs.pop('Meta', None))
|
options = cls._get_interface_options(attrs.pop('Meta', None))
|
||||||
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
@ -45,6 +48,10 @@ class NodeMeta(ObjectTypeMeta):
|
||||||
type_resolver=cls.resolve_type,
|
type_resolver=cls.resolve_type,
|
||||||
)
|
)
|
||||||
options.graphql_type = node_interface
|
options.graphql_type = node_interface
|
||||||
|
|
||||||
|
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
||||||
|
options.get_fields = lambda: fields
|
||||||
|
|
||||||
cls.Field = partial(
|
cls.Field = partial(
|
||||||
Field.copy_and_extend,
|
Field.copy_and_extend,
|
||||||
node_field,
|
node_field,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import inspect
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from graphql import GraphQLArgument
|
from graphql.type.definition import GraphQLArgument, GraphQLArgumentDefinition
|
||||||
from graphql.utils.assert_valid_name import assert_valid_name
|
from graphql.utils.assert_valid_name import assert_valid_name
|
||||||
|
|
||||||
from ..utils.orderedtype import OrderedType
|
from ..utils.orderedtype import OrderedType
|
||||||
|
@ -40,11 +40,15 @@ class Argument(GraphQLArgument, OrderedType):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def copy_from(cls, argument):
|
def copy_from(cls, argument):
|
||||||
|
if isinstance (argument, (GraphQLArgumentDefinition, Argument)):
|
||||||
|
name = argument.name
|
||||||
|
else:
|
||||||
|
name = None
|
||||||
return cls(
|
return cls(
|
||||||
type=argument.type,
|
type=argument.type,
|
||||||
default_value=argument.default_value,
|
default_value=argument.default_value,
|
||||||
description=argument.description,
|
description=argument.description,
|
||||||
name=argument.name,
|
name=name,
|
||||||
_creation_counter=argument.creation_counter if isinstance(argument, Argument) else None,
|
_creation_counter=argument.creation_counter if isinstance(argument, Argument) else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,12 @@ class GrapheneEnumType(GrapheneGraphQLType, GraphQLEnumType):
|
||||||
def values_from_enum(enum):
|
def values_from_enum(enum):
|
||||||
_values = OrderedDict()
|
_values = OrderedDict()
|
||||||
for name, value in enum.__members__.items():
|
for name, value in enum.__members__.items():
|
||||||
_values[name] = GraphQLEnumValue(name=name, value=value.value)
|
_values[name] = GraphQLEnumValue(
|
||||||
|
name=name,
|
||||||
|
value=value.value,
|
||||||
|
description=getattr(value, 'description', None),
|
||||||
|
deprecation_reason=getattr(value, 'deprecation_reason', None)
|
||||||
|
)
|
||||||
return _values
|
return _values
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from collections import OrderedDict
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from graphql.type import GraphQLField, GraphQLInputObjectField
|
from graphql.type import GraphQLField, GraphQLInputObjectField, GraphQLFieldDefinition
|
||||||
from graphql.utils.assert_valid_name import assert_valid_name
|
from graphql.utils.assert_valid_name import assert_valid_name
|
||||||
|
|
||||||
from ..utils.orderedtype import OrderedType
|
from ..utils.orderedtype import OrderedType
|
||||||
|
@ -126,18 +127,23 @@ class Field(AbstractField, GraphQLField, OrderedType):
|
||||||
_creation_counter = field.creation_counter if _creation_counter is False else None
|
_creation_counter = field.creation_counter if _creation_counter is False else None
|
||||||
attname = attname or field.attname
|
attname = attname or field.attname
|
||||||
parent = parent or field.parent
|
parent = parent or field.parent
|
||||||
|
args = to_arguments(args, field.args)
|
||||||
else:
|
else:
|
||||||
# If is a GraphQLField
|
# If is a GraphQLField
|
||||||
type = type or field.type
|
type = type or field.type
|
||||||
resolver = resolver or field.resolver
|
resolver = resolver or field.resolver
|
||||||
name = field.name
|
field_args = field.args
|
||||||
|
if isinstance(field, GraphQLFieldDefinition):
|
||||||
|
name = name or field.name
|
||||||
|
field_args = OrderedDict((a.name, a) for a in field_args)
|
||||||
|
args = to_arguments(args, field_args)
|
||||||
_creation_counter = None
|
_creation_counter = None
|
||||||
attname = attname or name
|
attname = attname or name
|
||||||
parent = parent
|
parent = parent
|
||||||
|
|
||||||
new_field = cls(
|
new_field = cls(
|
||||||
type=type,
|
type=type,
|
||||||
args=to_arguments(args, field.args),
|
args=args,
|
||||||
resolver=resolver,
|
resolver=resolver,
|
||||||
source=source,
|
source=source,
|
||||||
deprecation_reason=field.deprecation_reason,
|
deprecation_reason=field.deprecation_reason,
|
||||||
|
|
|
@ -11,16 +11,14 @@ from .objecttype import ObjectType, ObjectTypeMeta
|
||||||
class MutationMeta(ObjectTypeMeta):
|
class MutationMeta(ObjectTypeMeta):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
super_new = super(MutationMeta, cls).__new__
|
# Also ensure initialization is only performed for subclasses of
|
||||||
|
# Mutation
|
||||||
# Also ensure initialization is only performed for subclasses of Model
|
|
||||||
# (excluding Model class itself).
|
|
||||||
if not is_base_type(bases, MutationMeta):
|
if not is_base_type(bases, MutationMeta):
|
||||||
return type.__new__(cls, name, bases, attrs)
|
return type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
Input = attrs.pop('Input', None)
|
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 {}
|
field_args = props(Input) if Input else {}
|
||||||
resolver = getattr(cls, 'mutate', None)
|
resolver = getattr(cls, 'mutate', None)
|
||||||
assert resolver, 'All mutations must define a mutate method in it'
|
assert resolver, 'All mutations must define a mutate method in it'
|
||||||
|
|
|
@ -55,48 +55,15 @@ class ObjectTypeMeta(type):
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
super_new = type.__new__
|
super_new = type.__new__
|
||||||
|
|
||||||
# Also ensure initialization is only performed for subclasses of Model
|
# Also ensure initialization is only performed for subclasses of
|
||||||
# (excluding Model class itself).
|
# ObjectType,or Interfaces
|
||||||
|
|
||||||
if not is_base_type(bases, ObjectTypeMeta):
|
if not is_base_type(bases, ObjectTypeMeta):
|
||||||
return super_new(cls, name, bases, attrs)
|
return type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
if not is_objecttype(bases):
|
if not is_objecttype(bases):
|
||||||
return cls._create_interface(cls, name, bases, attrs)
|
return cls._create_interface(cls, name, bases, attrs)
|
||||||
|
|
||||||
options = Options(
|
return cls._create_objecttype(cls, name, bases, attrs)
|
||||||
attrs.pop('Meta', None),
|
|
||||||
name=None,
|
|
||||||
description=None,
|
|
||||||
graphql_type=None,
|
|
||||||
interfaces=(),
|
|
||||||
abstract=False
|
|
||||||
)
|
|
||||||
|
|
||||||
interfaces = tuple(options.interfaces)
|
|
||||||
fields = get_fields(ObjectType, attrs, bases, interfaces)
|
|
||||||
attrs = attrs_without_fields(attrs, fields)
|
|
||||||
cls = super_new(cls, name, bases, dict(attrs, _meta=options))
|
|
||||||
|
|
||||||
if not options.graphql_type:
|
|
||||||
fields = copy_fields(Field, fields, parent=cls)
|
|
||||||
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
|
||||||
options.graphql_type = GrapheneObjectType(
|
|
||||||
graphene_type=cls,
|
|
||||||
name=options.name or cls.__name__,
|
|
||||||
description=options.description or cls.__doc__,
|
|
||||||
fields=fields,
|
|
||||||
is_type_of=cls.is_type_of,
|
|
||||||
interfaces=tuple(get_interfaces(interfaces + base_interfaces))
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
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)
|
|
||||||
|
|
||||||
for name, field in fields.items():
|
|
||||||
setattr(cls, field.attname or name, field)
|
|
||||||
|
|
||||||
return cls
|
|
||||||
|
|
||||||
def get_interfaces(cls, bases):
|
def get_interfaces(cls, bases):
|
||||||
return (b for b in bases if issubclass(b, Interface))
|
return (b for b in bases if issubclass(b, Interface))
|
||||||
|
@ -133,7 +100,47 @@ class ObjectTypeMeta(type):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
assert not fields, "Can't mount Fields in an Interface with a defined graphql_type"
|
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)
|
||||||
|
|
||||||
|
return cls
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_objecttype(cls, name, bases, attrs):
|
||||||
|
options = Options(
|
||||||
|
attrs.pop('Meta', None),
|
||||||
|
name=None,
|
||||||
|
description=None,
|
||||||
|
graphql_type=None,
|
||||||
|
interfaces=(),
|
||||||
|
abstract=False
|
||||||
|
)
|
||||||
|
|
||||||
|
interfaces = tuple(options.interfaces)
|
||||||
|
fields = get_fields(ObjectType, attrs, bases, interfaces)
|
||||||
|
attrs = attrs_without_fields(attrs, fields)
|
||||||
|
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
if not options.graphql_type:
|
||||||
|
fields = copy_fields(Field, fields, parent=cls)
|
||||||
|
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
||||||
|
options.graphql_type = GrapheneObjectType(
|
||||||
|
graphene_type=cls,
|
||||||
|
name=options.name or cls.__name__,
|
||||||
|
description=options.description or cls.__doc__,
|
||||||
|
fields=fields,
|
||||||
|
is_type_of=cls.is_type_of,
|
||||||
|
interfaces=tuple(get_interfaces(interfaces + base_interfaces))
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
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():
|
for name, field in fields.items():
|
||||||
setattr(cls, field.attname or name, field)
|
setattr(cls, field.attname or name, field)
|
||||||
|
@ -146,9 +153,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# GraphQL ObjectType acting as container
|
# GraphQL ObjectType acting as container
|
||||||
args_len = len(args)
|
args_len = len(args)
|
||||||
fields = self._meta.graphql_type.get_fields().values()
|
fields = self._meta.get_fields().items()
|
||||||
for f in fields:
|
for name, f in fields:
|
||||||
setattr(self, getattr(f, 'attname', f.name), None)
|
setattr(self, getattr(f, 'attname', name), None)
|
||||||
|
|
||||||
if args_len > len(fields):
|
if args_len > len(fields):
|
||||||
# Daft, but matches old exception sans the err msg.
|
# Daft, but matches old exception sans the err msg.
|
||||||
|
@ -156,18 +163,18 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||||
fields_iter = iter(fields)
|
fields_iter = iter(fields)
|
||||||
|
|
||||||
if not kwargs:
|
if not kwargs:
|
||||||
for val, field in zip(args, fields_iter):
|
for val, (name, field) in zip(args, fields_iter):
|
||||||
attname = getattr(field, 'attname', field.name)
|
attname = getattr(field, 'attname', name)
|
||||||
setattr(self, attname, val)
|
setattr(self, attname, val)
|
||||||
else:
|
else:
|
||||||
for val, field in zip(args, fields_iter):
|
for val, (name, field) in zip(args, fields_iter):
|
||||||
attname = getattr(field, 'attname', field.name)
|
attname = getattr(field, 'attname', name)
|
||||||
setattr(self, attname, val)
|
setattr(self, attname, val)
|
||||||
kwargs.pop(attname, None)
|
kwargs.pop(attname, None)
|
||||||
|
|
||||||
for field in fields_iter:
|
for name, field in fields_iter:
|
||||||
try:
|
try:
|
||||||
attname = getattr(field, 'attname', field.name)
|
attname = getattr(field, 'attname', name)
|
||||||
val = kwargs.pop(attname)
|
val = kwargs.pop(attname)
|
||||||
setattr(self, attname, val)
|
setattr(self, attname, val)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -11,6 +11,10 @@ def test_enum_construction():
|
||||||
GREEN = 2
|
GREEN = 2
|
||||||
BLUE = 3
|
BLUE = 3
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description(self):
|
||||||
|
return "Description {}".format(self.name)
|
||||||
|
|
||||||
assert isinstance(RGB._meta.graphql_type, GraphQLEnumType)
|
assert isinstance(RGB._meta.graphql_type, GraphQLEnumType)
|
||||||
values = RGB._meta.graphql_type.get_values()
|
values = RGB._meta.graphql_type.get_values()
|
||||||
assert sorted([v.name for v in values]) == [
|
assert sorted([v.name for v in values]) == [
|
||||||
|
@ -18,6 +22,11 @@ def test_enum_construction():
|
||||||
'GREEN',
|
'GREEN',
|
||||||
'RED'
|
'RED'
|
||||||
]
|
]
|
||||||
|
assert sorted([v.description for v in values]) == [
|
||||||
|
'Description BLUE',
|
||||||
|
'Description GREEN',
|
||||||
|
'Description RED'
|
||||||
|
]
|
||||||
assert isinstance(RGB(name='field_name').as_field(), Field)
|
assert isinstance(RGB(name='field_name').as_field(), Field)
|
||||||
assert isinstance(RGB(name='field_name').as_argument(), Argument)
|
assert isinstance(RGB(name='field_name').as_argument(), Argument)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
from graphql import GraphQLInputObjectType, GraphQLString
|
from graphql import GraphQLInputObjectType, GraphQLString
|
||||||
|
from graphql.type.definition import GraphQLInputFieldDefinition
|
||||||
|
|
||||||
from ..field import InputField
|
from ..field import InputField
|
||||||
from ..inputobjecttype import InputObjectType
|
from ..inputobjecttype import InputObjectType
|
||||||
|
@ -43,7 +44,7 @@ def test_generate_objecttype_with_fields():
|
||||||
graphql_type = MyObjectType._meta.graphql_type
|
graphql_type = MyObjectType._meta.graphql_type
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert 'field' in fields
|
assert 'field' in fields
|
||||||
assert isinstance(fields['field'], InputField)
|
assert isinstance(fields['field'], GraphQLInputFieldDefinition)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_objecttype_with_graphene_fields():
|
def test_generate_objecttype_with_graphene_fields():
|
||||||
|
@ -53,4 +54,4 @@ def test_generate_objecttype_with_graphene_fields():
|
||||||
graphql_type = MyObjectType._meta.graphql_type
|
graphql_type = MyObjectType._meta.graphql_type
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert 'field' in fields
|
assert 'field' in fields
|
||||||
assert isinstance(fields['field'], InputField)
|
assert isinstance(fields['field'], GraphQLInputFieldDefinition)
|
||||||
|
|
|
@ -56,7 +56,7 @@ def test_interface_inheritance():
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert 'field' in fields
|
assert 'field' in fields
|
||||||
assert 'inherited' in fields
|
assert 'inherited' in fields
|
||||||
assert fields['field'] > fields['inherited']
|
assert MyInterface.field > MyInheritedInterface.inherited
|
||||||
|
|
||||||
|
|
||||||
def test_interface_instance():
|
def test_interface_instance():
|
||||||
|
|
|
@ -74,11 +74,7 @@ def test_objecttype_inheritance():
|
||||||
|
|
||||||
graphql_type = MyObjectType._meta.graphql_type
|
graphql_type = MyObjectType._meta.graphql_type
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert 'field1' in fields
|
assert fields.keys() == ['inherited', 'field1', 'field2']
|
||||||
assert 'field2' in fields
|
|
||||||
assert 'inherited' in fields
|
|
||||||
assert fields['field1'] > fields['inherited']
|
|
||||||
assert fields['field2'] > fields['field1']
|
|
||||||
|
|
||||||
|
|
||||||
def test_objecttype_as_container_get_fields():
|
def test_objecttype_as_container_get_fields():
|
||||||
|
@ -195,11 +191,7 @@ def test_objecttype_graphene_interface():
|
||||||
graphql_type = GrapheneObjectType._meta.graphql_type
|
graphql_type = GrapheneObjectType._meta.graphql_type
|
||||||
assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
|
assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
|
||||||
assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
|
assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields().keys() == ['name', 'extended', 'field']
|
||||||
assert 'field' in fields
|
|
||||||
assert 'extended' in fields
|
|
||||||
assert 'name' in fields
|
|
||||||
assert fields['field'] > fields['extended'] > fields['name']
|
|
||||||
|
|
||||||
|
|
||||||
def test_objecttype_graphene_inherit_interface():
|
def test_objecttype_graphene_inherit_interface():
|
||||||
|
@ -214,11 +206,8 @@ def test_objecttype_graphene_inherit_interface():
|
||||||
assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
|
assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
|
||||||
assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
|
assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert 'field' in fields
|
fields = graphql_type.get_fields().keys() == ['name', 'extended', 'field']
|
||||||
assert 'extended' in fields
|
|
||||||
assert 'name' in fields
|
|
||||||
assert issubclass(GrapheneObjectType, GrapheneInterface)
|
assert issubclass(GrapheneObjectType, GrapheneInterface)
|
||||||
assert fields['field'] > fields['extended'] > fields['name']
|
|
||||||
|
|
||||||
|
|
||||||
# def test_objecttype_graphene_interface_extended():
|
# def test_objecttype_graphene_interface_extended():
|
||||||
|
|
|
@ -3,8 +3,9 @@ import datetime
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from graphene.utils.get_graphql_type import get_graphql_type
|
from graphene.utils.get_graphql_type import get_graphql_type
|
||||||
from graphql import (GraphQLBoolean, GraphQLFloat, GraphQLInt,
|
from graphql import graphql
|
||||||
GraphQLScalarType, GraphQLString, graphql)
|
from graphql.type import (GraphQLBoolean, GraphQLFloat, GraphQLInt,
|
||||||
|
GraphQLScalarType, GraphQLString, GraphQLFieldDefinition)
|
||||||
from graphql.language import ast
|
from graphql.language import ast
|
||||||
|
|
||||||
from ..field import Field
|
from ..field import Field
|
||||||
|
@ -94,7 +95,7 @@ def test_scalar_in_objecttype(scalar_class, graphql_type):
|
||||||
graphql_type = get_graphql_type(MyObjectType)
|
graphql_type = get_graphql_type(MyObjectType)
|
||||||
fields = graphql_type.get_fields()
|
fields = graphql_type.get_fields()
|
||||||
assert list(fields.keys()) == ['before', 'field', 'after']
|
assert list(fields.keys()) == ['before', 'field', 'after']
|
||||||
assert isinstance(fields['field'], Field)
|
assert isinstance(fields['field'], GraphQLFieldDefinition)
|
||||||
|
|
||||||
|
|
||||||
def test_custom_scalar_empty():
|
def test_custom_scalar_empty():
|
||||||
|
|
|
@ -11,6 +11,12 @@ class Character(Interface):
|
||||||
friends = List(lambda: Character)
|
friends = List(lambda: Character)
|
||||||
best_friend = Field(lambda: Character)
|
best_friend = Field(lambda: Character)
|
||||||
|
|
||||||
|
def resolve_friends(self, *args):
|
||||||
|
return [Human(name='Peter')]
|
||||||
|
|
||||||
|
def resolve_best_friend(self, *args):
|
||||||
|
return Human(name='Best')
|
||||||
|
|
||||||
|
|
||||||
class Pet(ObjectType):
|
class Pet(ObjectType):
|
||||||
type = String()
|
type = String()
|
||||||
|
@ -26,12 +32,6 @@ class Human(ObjectType):
|
||||||
def resolve_pet(self, *args):
|
def resolve_pet(self, *args):
|
||||||
return Pet(type='Dog')
|
return Pet(type='Dog')
|
||||||
|
|
||||||
def resolve_friends(self, *args):
|
|
||||||
return [Human(name='Peter')]
|
|
||||||
|
|
||||||
def resolve_best_friend(self, *args):
|
|
||||||
return Human(name='Best')
|
|
||||||
|
|
||||||
|
|
||||||
class RootQuery(ObjectType):
|
class RootQuery(ObjectType):
|
||||||
character = Field(Character)
|
character = Field(Character)
|
||||||
|
|
|
@ -16,10 +16,24 @@ def get_fields_from_attrs(in_type, attrs):
|
||||||
yield attname, field
|
yield attname, field
|
||||||
|
|
||||||
|
|
||||||
def get_fields_from_types(bases):
|
def get_fields_from_bases_and_types(bases, types):
|
||||||
fields = set()
|
fields = set()
|
||||||
for _class in bases:
|
for _class in bases:
|
||||||
for attname, field in get_graphql_type(_class).get_fields().items():
|
if not is_graphene_type(_class):
|
||||||
|
continue
|
||||||
|
_fields = _class._meta.get_fields()
|
||||||
|
if callable(_fields):
|
||||||
|
_fields = _fields()
|
||||||
|
|
||||||
|
for default_attname, field in _fields.items():
|
||||||
|
attname = getattr(field, 'attname', default_attname)
|
||||||
|
if attname in fields:
|
||||||
|
continue
|
||||||
|
fields.add(attname)
|
||||||
|
yield attname, field
|
||||||
|
|
||||||
|
for grapqhl_type in types:
|
||||||
|
for attname, field in get_graphql_type(grapqhl_type).get_fields().items():
|
||||||
if attname in fields:
|
if attname in fields:
|
||||||
continue
|
continue
|
||||||
fields.add(attname)
|
fields.add(attname)
|
||||||
|
@ -29,11 +43,7 @@ def get_fields_from_types(bases):
|
||||||
def get_fields(in_type, attrs, bases, graphql_types=()):
|
def get_fields(in_type, attrs, bases, graphql_types=()):
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
graphene_bases = tuple(
|
extended_fields = list(get_fields_from_bases_and_types(bases, graphql_types))
|
||||||
base._meta.graphql_type for base in bases if is_graphene_type(base)
|
|
||||||
) + graphql_types
|
|
||||||
|
|
||||||
extended_fields = list(get_fields_from_types(graphene_bases))
|
|
||||||
local_fields = list(get_fields_from_attrs(in_type, attrs))
|
local_fields = list(get_fields_from_attrs(in_type, attrs))
|
||||||
# We asume the extended fields are already sorted, so we only
|
# We asume the extended fields are already sorted, so we only
|
||||||
# have to sort the local fields, that are get from attrs
|
# have to sort the local fields, that are get from attrs
|
||||||
|
|
|
@ -4,7 +4,7 @@ from graphql import (GraphQLField, GraphQLFloat, GraphQLInt,
|
||||||
GraphQLInterfaceType, GraphQLString)
|
GraphQLInterfaceType, GraphQLString)
|
||||||
|
|
||||||
from ...types import Argument, Field, ObjectType, String
|
from ...types import Argument, Field, ObjectType, String
|
||||||
from ..get_fields import get_fields_from_attrs, get_fields_from_types
|
from ..get_fields import get_fields_from_attrs, get_fields_from_bases_and_types
|
||||||
|
|
||||||
|
|
||||||
def test_get_fields_from_attrs():
|
def test_get_fields_from_attrs():
|
||||||
|
@ -31,8 +31,8 @@ def test_get_fields_from_types():
|
||||||
('extra', GraphQLField(GraphQLFloat))
|
('extra', GraphQLField(GraphQLFloat))
|
||||||
]))
|
]))
|
||||||
|
|
||||||
bases = (int_base, float_base)
|
_types = (int_base, float_base)
|
||||||
base_fields = OrderedDict(get_fields_from_types(bases))
|
base_fields = OrderedDict(get_fields_from_bases_and_types((), _types))
|
||||||
assert [f for f in base_fields.keys()] == ['int', 'num', 'extra', 'float']
|
assert [f for f in base_fields.keys()] == ['int', 'num', 'extra', 'float']
|
||||||
assert [f.type for f in base_fields.values()] == [
|
assert [f.type for f in base_fields.values()] == [
|
||||||
GraphQLInt,
|
GraphQLInt,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user