mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 01:47:45 +03:00 
			
		
		
		
	Added List, NonNull types
This commit is contained in:
		
							parent
							
								
									58dbfefc15
								
							
						
					
					
						commit
						d58d1f8d89
					
				
							
								
								
									
										64
									
								
								graphene/types/argument.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								graphene/types/argument.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					import copy
 | 
				
			||||||
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					import inspect
 | 
				
			||||||
 | 
					from itertools import chain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql import GraphQLArgument
 | 
				
			||||||
 | 
					from graphql.utils.assert_valid_name import assert_valid_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..utils.orderedtype import OrderedType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Argument(GraphQLArgument, OrderedType):
 | 
				
			||||||
 | 
					    __slots__ = ('name', 'type', 'default_value', 'description', 'creation_counter')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, type, default_value=None, description=None, name=None, _creation_counter=None):
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        self.type = type
 | 
				
			||||||
 | 
					        self.default_value = default_value
 | 
				
			||||||
 | 
					        self.description = description
 | 
				
			||||||
 | 
					        OrderedType.__init__(self, _creation_counter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def name(self):
 | 
				
			||||||
 | 
					        return self._name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @name.setter
 | 
				
			||||||
 | 
					    def name(self, name):
 | 
				
			||||||
 | 
					        if name is not None:
 | 
				
			||||||
 | 
					            assert_valid_name(name)
 | 
				
			||||||
 | 
					        self._name = name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def type(self):
 | 
				
			||||||
 | 
					        from ..utils.get_graphql_type import get_graphql_type
 | 
				
			||||||
 | 
					        if inspect.isfunction(self._type):
 | 
				
			||||||
 | 
					            return get_graphql_type(self._type())
 | 
				
			||||||
 | 
					        return get_graphql_type(self._type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @type.setter
 | 
				
			||||||
 | 
					    def type(self, type):
 | 
				
			||||||
 | 
					        self._type = type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def to_arguments(*args, **extra):
 | 
				
			||||||
 | 
					    from .proxy import TypeProxy
 | 
				
			||||||
 | 
					    args = list(filter(None, args))+[extra]
 | 
				
			||||||
 | 
					    arguments = []
 | 
				
			||||||
 | 
					    iter_arguments = chain(*[arg.items() for arg in args])
 | 
				
			||||||
 | 
					    arguments_names = set()
 | 
				
			||||||
 | 
					    for default_name, arg in iter_arguments:
 | 
				
			||||||
 | 
					        if isinstance(arg, TypeProxy):
 | 
				
			||||||
 | 
					            arg = arg.as_argument()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not isinstance(arg, GraphQLArgument):
 | 
				
			||||||
 | 
					            raise ValueError('Unknown argument "{}".'.format(default_name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        arg = copy.copy(arg)
 | 
				
			||||||
 | 
					        arg.name = arg.name or default_name
 | 
				
			||||||
 | 
					        assert arg.name, 'All arguments must have a name.'
 | 
				
			||||||
 | 
					        assert arg.name not in arguments_names, 'More than one Argument have same name "{}".'.format(arg.name)
 | 
				
			||||||
 | 
					        arguments.append(arg)
 | 
				
			||||||
 | 
					        arguments_names.add(arg.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return OrderedDict([(a.name, a) for a in sorted(arguments)])
 | 
				
			||||||
| 
						 | 
					@ -6,17 +6,18 @@ from graphql.utils.assert_valid_name import assert_valid_name
 | 
				
			||||||
from .objecttype import ObjectType
 | 
					from .objecttype import ObjectType
 | 
				
			||||||
from .interface import Interface
 | 
					from .interface import Interface
 | 
				
			||||||
from ..utils.orderedtype import OrderedType
 | 
					from ..utils.orderedtype import OrderedType
 | 
				
			||||||
 | 
					from .argument import to_arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Field(GraphQLField, OrderedType):
 | 
					class Field(GraphQLField, OrderedType):
 | 
				
			||||||
    __slots__ = ('_name', '_type', '_args', '_resolver', 'deprecation_reason', 'description', 'source', '_extra_args', 'attname', 'parent', 'creation_counter')
 | 
					    __slots__ = ('_name', '_type', '_args', '_resolver', 'deprecation_reason', 'description', 'source', 'attname', 'parent', 'creation_counter')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, type, args=None, resolver=None, source=None, deprecation_reason=None, name=None, description=None, **extra_args):
 | 
					    def __init__(self, type, args=None, resolver=None, source=None, deprecation_reason=None, name=None, description=None, _creation_counter=None, **extra_args):
 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
        self.attname = None
 | 
					        self.attname = None
 | 
				
			||||||
        self.parent = None
 | 
					        self.parent = None
 | 
				
			||||||
        self.type = type
 | 
					        self.type = type
 | 
				
			||||||
        self.args = args
 | 
					        self.args = to_arguments(args, extra_args)
 | 
				
			||||||
        assert not (source and resolver), ('You cannot have a source '
 | 
					        assert not (source and resolver), ('You cannot have a source '
 | 
				
			||||||
                                           'and a resolver at the same time')
 | 
					                                           'and a resolver at the same time')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,8 +25,7 @@ class Field(GraphQLField, OrderedType):
 | 
				
			||||||
        self.source = source
 | 
					        self.source = source
 | 
				
			||||||
        self.deprecation_reason = deprecation_reason
 | 
					        self.deprecation_reason = deprecation_reason
 | 
				
			||||||
        self.description = description
 | 
					        self.description = description
 | 
				
			||||||
        self._extra_args = extra_args
 | 
					        OrderedType.__init__(self, _creation_counter=_creation_counter)
 | 
				
			||||||
        OrderedType.__init__(self)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def contribute_to_class(self, cls, attname):
 | 
					    def contribute_to_class(self, cls, attname):
 | 
				
			||||||
        assert issubclass(cls, (ObjectType, Interface)), 'Field {} cannot be mounted in {}'.format(
 | 
					        assert issubclass(cls, (ObjectType, Interface)), 'Field {} cannot be mounted in {}'.format(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								graphene/types/proxy.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								graphene/types/proxy.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					from .field import Field
 | 
				
			||||||
 | 
					from .argument import Argument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..utils.orderedtype import OrderedType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TypeProxy(OrderedType):
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        self.args = args
 | 
				
			||||||
 | 
					        self.kwargs = kwargs
 | 
				
			||||||
 | 
					        OrderedType.__init__(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_type(self):
 | 
				
			||||||
 | 
					        return self._meta.graphql_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def as_field(self):
 | 
				
			||||||
 | 
					        return Field(
 | 
				
			||||||
 | 
					            self.get_type(),
 | 
				
			||||||
 | 
					            *self.args,
 | 
				
			||||||
 | 
					            _creation_counter=self.creation_counter,
 | 
				
			||||||
 | 
					            **self.kwargs
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def as_argument(self):
 | 
				
			||||||
 | 
					        return Argument(
 | 
				
			||||||
 | 
					            self.get_type(),
 | 
				
			||||||
 | 
					            *self.args,
 | 
				
			||||||
 | 
					            _creation_counter=self.creation_counter,
 | 
				
			||||||
 | 
					            **self.kwargs
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def contribute_to_class(self, cls, attname):
 | 
				
			||||||
 | 
					        field = self.as_field()
 | 
				
			||||||
 | 
					        return field.contribute_to_class(cls, attname)
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
from graphql import GraphQLScalarType, GraphQLString, GraphQLInt, GraphQLFloat, GraphQLBoolean
 | 
					from graphql import GraphQLString, GraphQLInt, GraphQLFloat, GraphQLBoolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .definitions import ClassTypeMeta, GrapheneScalarType
 | 
					from .definitions import ClassTypeMeta, GrapheneScalarType
 | 
				
			||||||
from .field import Field
 | 
					from .proxy import TypeProxy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ScalarTypeMeta(ClassTypeMeta):
 | 
					class ScalarTypeMeta(ClassTypeMeta):
 | 
				
			||||||
| 
						 | 
					@ -34,25 +34,10 @@ class ScalarTypeMeta(ClassTypeMeta):
 | 
				
			||||||
        return constructed
 | 
					        return constructed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Scalar(six.with_metaclass(ScalarTypeMeta)):
 | 
					class Scalar(six.with_metaclass(ScalarTypeMeta, TypeProxy)):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        abstract = True
 | 
					        abstract = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					 | 
				
			||||||
        self.args = args
 | 
					 | 
				
			||||||
        self.kwargs = kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def as_field(self):
 | 
					 | 
				
			||||||
        return Field(
 | 
					 | 
				
			||||||
            lambda: self._meta.graphql_type,
 | 
					 | 
				
			||||||
            *self.args,
 | 
					 | 
				
			||||||
            **self.kwargs
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def contribute_to_class(self, cls, attname):
 | 
					 | 
				
			||||||
        field = self.as_field()
 | 
					 | 
				
			||||||
        return field.contribute_to_class(cls, attname)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def construct_scalar_class(graphql_type):
 | 
					def construct_scalar_class(graphql_type):
 | 
				
			||||||
    # This is equivalent to
 | 
					    # This is equivalent to
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										33
									
								
								graphene/types/structures.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								graphene/types/structures.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					import inspect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql import GraphQLList, GraphQLNonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .proxy import TypeProxy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Structure(TypeProxy):
 | 
				
			||||||
 | 
					    def __init__(self, of_type, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(Structure, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					        self.of_type = of_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_type(self):
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def of_type(self):
 | 
				
			||||||
 | 
					        from ..utils.get_graphql_type import get_graphql_type
 | 
				
			||||||
 | 
					        if inspect.isfunction(self._of_type):
 | 
				
			||||||
 | 
					            return get_graphql_type(self._of_type())
 | 
				
			||||||
 | 
					        return get_graphql_type(self._of_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @of_type.setter
 | 
				
			||||||
 | 
					    def of_type(self, value):
 | 
				
			||||||
 | 
					        self._of_type = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class List(Structure, GraphQLList):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NonNull(Structure, GraphQLNonNull):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
							
								
								
									
										63
									
								
								graphene/types/tests/test_argument.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								graphene/types/tests/test_argument.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					import copy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql import GraphQLString, GraphQLArgument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..argument import Argument, to_arguments
 | 
				
			||||||
 | 
					from ..scalars import String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_argument():
 | 
				
			||||||
 | 
					    argument = Argument(GraphQLString, name="name", description="description")
 | 
				
			||||||
 | 
					    assert isinstance(argument, GraphQLArgument)
 | 
				
			||||||
 | 
					    assert argument.name == "name"
 | 
				
			||||||
 | 
					    assert argument.description == "description"
 | 
				
			||||||
 | 
					    assert argument.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_wrong_name():
 | 
				
			||||||
 | 
					    with pytest.raises(AssertionError) as excinfo:
 | 
				
			||||||
 | 
					        Argument(GraphQLString, name="a field")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert """Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "a field" does not.""" == str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_argument_type():
 | 
				
			||||||
 | 
					    argument = Argument(lambda: GraphQLString)
 | 
				
			||||||
 | 
					    assert argument.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_argument_graphene_type():
 | 
				
			||||||
 | 
					    argument = Argument(String())
 | 
				
			||||||
 | 
					    assert argument.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_argument_proxy_graphene_type():
 | 
				
			||||||
 | 
					    proxy = String()
 | 
				
			||||||
 | 
					    argument = proxy.as_argument()
 | 
				
			||||||
 | 
					    assert argument.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_copy_argument_works():
 | 
				
			||||||
 | 
					    argument = Argument(GraphQLString)
 | 
				
			||||||
 | 
					    copy.copy(argument)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments():
 | 
				
			||||||
 | 
					    arguments = to_arguments(a=String(), b=Argument(GraphQLString), c=Argument(String()))
 | 
				
			||||||
 | 
					    assert list(arguments.keys()) == ['a', 'b', 'c']
 | 
				
			||||||
 | 
					    assert [a.type for a in arguments.values()] == [GraphQLString] * 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments_incorrect():
 | 
				
			||||||
 | 
					    with pytest.raises(ValueError) as excinfo:
 | 
				
			||||||
 | 
					        to_arguments(incorrect=object())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert """Unknown argument "incorrect".""" == str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments_no_name():
 | 
				
			||||||
 | 
					    with pytest.raises(AssertionError) as excinfo:
 | 
				
			||||||
 | 
					        to_arguments(dict(a=String()), dict(a=String()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert """More than one Argument have same name "a".""" == str(excinfo.value)
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,12 @@
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
import copy
 | 
					import copy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphql import GraphQLString, GraphQLField
 | 
					from graphql import GraphQLString, GraphQLField, GraphQLInt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..field import Field
 | 
					from ..field import Field
 | 
				
			||||||
 | 
					from ..argument import Argument
 | 
				
			||||||
from ..objecttype import ObjectType
 | 
					from ..objecttype import ObjectType
 | 
				
			||||||
 | 
					from ..scalars import String, Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_field():
 | 
					def test_field():
 | 
				
			||||||
| 
						 | 
					@ -55,3 +57,22 @@ def test_copy_field_works():
 | 
				
			||||||
def test_field_callable_type():
 | 
					def test_field_callable_type():
 | 
				
			||||||
    field = Field(lambda: GraphQLString)
 | 
					    field = Field(lambda: GraphQLString)
 | 
				
			||||||
    assert field.type == GraphQLString
 | 
					    assert field.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_with_arguments():
 | 
				
			||||||
 | 
					    field = Field(GraphQLString, name="name", description="description", input=Argument(GraphQLString))
 | 
				
			||||||
 | 
					    assert isinstance(field, GraphQLField)
 | 
				
			||||||
 | 
					    assert field.name == "name"
 | 
				
			||||||
 | 
					    assert field.description == "description"
 | 
				
			||||||
 | 
					    assert 'input' in field.args
 | 
				
			||||||
 | 
					    assert field.args['input'].type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_with_argument_proxies():
 | 
				
			||||||
 | 
					    field = Field(GraphQLString, name="name", description="description", int=Int(), string=String())
 | 
				
			||||||
 | 
					    assert isinstance(field, GraphQLField)
 | 
				
			||||||
 | 
					    assert field.name == "name"
 | 
				
			||||||
 | 
					    assert field.description == "description"
 | 
				
			||||||
 | 
					    assert list(field.args.keys()) == ['int', 'string']
 | 
				
			||||||
 | 
					    assert field.args['string'].type == GraphQLString
 | 
				
			||||||
 | 
					    assert field.args['int'].type == GraphQLInt
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,14 @@
 | 
				
			||||||
import pytest
 | 
					from ..scalars import String
 | 
				
			||||||
from ..scalars import Scalar, String, Int, Float, Boolean
 | 
					 | 
				
			||||||
from ..field import Field
 | 
					from ..field import Field
 | 
				
			||||||
from ..objecttype import ObjectType, implements
 | 
					from ..objecttype import ObjectType, implements
 | 
				
			||||||
from ..interface import Interface
 | 
					from ..interface import Interface
 | 
				
			||||||
 | 
					from ..structures import List
 | 
				
			||||||
from ..schema import Schema
 | 
					from ..schema import Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(Interface):
 | 
					class Character(Interface):
 | 
				
			||||||
    name = String()
 | 
					    name = String()
 | 
				
			||||||
 | 
					    friends = List(lambda: Character)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pet(ObjectType):
 | 
					class Pet(ObjectType):
 | 
				
			||||||
| 
						 | 
					@ -21,20 +22,23 @@ 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')]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RootQuery(ObjectType):
 | 
					class RootQuery(ObjectType):
 | 
				
			||||||
    character = Field(Character)
 | 
					    character = Field(Character)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_character(self, *_):
 | 
					    def resolve_character(self, *_):
 | 
				
			||||||
        return Human(name='Hey!')
 | 
					        return Human(name='Harry')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
schema = Schema(query=RootQuery, types=[Human])
 | 
					schema = Schema(query=RootQuery, types=[Human])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_schema():
 | 
					def test_schema():
 | 
				
			||||||
    executed = schema.execute('{ character {name, ...on Human {pet { type } } } }')
 | 
					    executed = schema.execute('{ character {name, friends { name}, ...on Human {pet { type } } } }')
 | 
				
			||||||
    assert executed.data == {'character': {'name': 'Hey!', 'pet': {'type': 'Dog'}}}
 | 
					    assert executed.data == {'character': {'name': 'Harry', 'friends': [{'name': 'Peter'}], 'pet': {'type': 'Dog'}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_schema_introspect():
 | 
					def test_schema_introspect():
 | 
				
			||||||
| 
						 | 
					@ -50,10 +54,12 @@ schema {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Character {
 | 
					interface Character {
 | 
				
			||||||
  name: String
 | 
					  name: String
 | 
				
			||||||
 | 
					  friends: [Character]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Human implements Character {
 | 
					type Human implements Character {
 | 
				
			||||||
  name: String
 | 
					  name: String
 | 
				
			||||||
 | 
					  friends: [Character]
 | 
				
			||||||
  pet: Pet
 | 
					  pet: Pet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										44
									
								
								graphene/types/tests/test_structures.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								graphene/types/tests/test_structures.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql import GraphQLString, GraphQLList, GraphQLNonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..structures import List, NonNull
 | 
				
			||||||
 | 
					from ..scalars import String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_list():
 | 
				
			||||||
 | 
					    list_instance = List(String())
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, GraphQLList)
 | 
				
			||||||
 | 
					    assert list_instance.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_list_lambda():
 | 
				
			||||||
 | 
					    list_instance = List(lambda: String())
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, GraphQLList)
 | 
				
			||||||
 | 
					    assert list_instance.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_list_list():
 | 
				
			||||||
 | 
					    list_instance = List(List(String()))
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, List)
 | 
				
			||||||
 | 
					    assert isinstance(list_instance.of_type, GraphQLList)
 | 
				
			||||||
 | 
					    assert list_instance.of_type.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nonnull():
 | 
				
			||||||
 | 
					    list_instance = NonNull(String())
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert list_instance.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nonnull_lambda():
 | 
				
			||||||
 | 
					    list_instance = NonNull(lambda: String())
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert list_instance.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nonnull_list():
 | 
				
			||||||
 | 
					    list_instance = NonNull(List(String()))
 | 
				
			||||||
 | 
					    assert isinstance(list_instance, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert isinstance(list_instance.of_type, GraphQLList)
 | 
				
			||||||
 | 
					    assert list_instance.of_type.of_type == GraphQLString
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,10 @@ from ..types.scalars import Scalar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_graphene_type(_type):
 | 
					def is_graphene_type(_type):
 | 
				
			||||||
    return inspect.isclass(_type) and issubclass(_type, (
 | 
					    if inspect.isclass(_type):
 | 
				
			||||||
        Interface,
 | 
					        return issubclass(_type, (
 | 
				
			||||||
        ObjectType,
 | 
					            Interface,
 | 
				
			||||||
        Scalar
 | 
					            ObjectType,
 | 
				
			||||||
    ))
 | 
					            Scalar
 | 
				
			||||||
 | 
					        ))
 | 
				
			||||||
 | 
					    return is_graphene_type(type(_type))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user