diff --git a/graphene/new_types/__init__.py b/graphene/new_types/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/graphene/new_types/argument.py b/graphene/new_types/argument.py
deleted file mode 100644
index b16aef47..00000000
--- a/graphene/new_types/argument.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from collections import OrderedDict
-from itertools import chain
-
-from ..utils.orderedtype import OrderedType
-
-
-class Argument(OrderedType):
-
- def __init__(self, type, default_value=None, description=None, name=None, _creation_counter=None):
- super(Argument, self).__init__(_creation_counter=_creation_counter)
- self.name = name
- self.type = type
- self.default_value = default_value
- self.description = description
-
-
-def to_arguments(args, extra_args):
- from .unmountedtype import UnmountedType
- extra_args = sorted(extra_args.items(), key=lambda f: f[1])
- iter_arguments = chain(args.items() + extra_args)
- arguments = OrderedDict()
- for default_name, arg in iter_arguments:
- if isinstance(arg, UnmountedType):
- arg = arg.as_argument()
-
- if not isinstance(arg, Argument):
- raise ValueError('Unknown argument "{}".'.format(default_name))
-
- arg_name = default_name or arg.name
- assert arg_name not in arguments, 'More than one Argument have same name "{}".'.format(arg.name)
- arguments[arg_name] = arg
-
- return arguments
diff --git a/graphene/new_types/datetime.py b/graphene/new_types/datetime.py
deleted file mode 100644
index 9baa731e..00000000
--- a/graphene/new_types/datetime.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from __future__ import absolute_import
-
-import datetime
-
-from graphql.language import ast
-
-from .scalars import Scalar
-
-try:
- import iso8601
-except:
- raise ImportError(
- "iso8601 package is required for DateTime Scalar.\n"
- "You can install it using: pip install iso8601."
- )
-
-
-class DateTime(Scalar):
- '''
- The `DateTime` scalar type represents a DateTime
- value as specified by
- [iso8601](https://en.wikipedia.org/wiki/ISO_8601).
- '''
-
- @staticmethod
- def serialize(dt):
- assert isinstance(dt, (datetime.datetime, datetime.date)), (
- 'Received not compatible datetime "{}"'.format(repr(dt))
- )
- return dt.isoformat()
-
- @staticmethod
- def parse_literal(node):
- if isinstance(node, ast.StringValue):
- return iso8601.parse_date(node.value)
-
- @staticmethod
- def parse_value(value):
- return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
diff --git a/graphene/new_types/enum.py b/graphene/new_types/enum.py
deleted file mode 100644
index 02493b30..00000000
--- a/graphene/new_types/enum.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from collections import OrderedDict
-
-import six
-
-from ..generators import generate_enum
-from ..utils.is_base_type import is_base_type
-from .options import Options
-from .unmountedtype import UnmountedType
-
-try:
- from enum import Enum as PyEnum
-except ImportError:
- from ..utils.enum import Enum as PyEnum
-
-
-class EnumTypeMeta(type):
-
- def __new__(cls, name, bases, attrs):
- # Also ensure initialization is only performed for subclasses of Model
- # (excluding Model class itself).
- if not is_base_type(bases, EnumTypeMeta):
- return type.__new__(cls, name, bases, attrs)
-
- options = Options(
- attrs.pop('Meta', None),
- name=name,
- description=attrs.get('__doc__'),
- enum=None,
- )
- if not options.enum:
- options.enum = PyEnum(cls.__name__, attrs)
-
- new_attrs = OrderedDict(attrs, _meta=options, **options.enum.__members__)
- return type.__new__(cls, name, bases, new_attrs)
-
- def __prepare__(name, bases, **kwargs): # noqa: N805
- return OrderedDict()
-
- def __call__(cls, *args, **kwargs): # noqa: N805
- if cls is Enum:
- description = kwargs.pop('description', None)
- return cls.from_enum(PyEnum(*args, **kwargs), description=description)
- return super(EnumTypeMeta, cls).__call__(*args, **kwargs)
-
- def from_enum(cls, enum, description=None):
- meta_class = type('Meta', (object,), {'enum': enum, 'description': description})
- return type(meta_class.enum.__name__, (Enum,), {'Meta': meta_class})
-
- def __str__(cls):
- return cls._meta.name
-
-
-class Enum(six.with_metaclass(EnumTypeMeta, UnmountedType)):
- pass
diff --git a/graphene/new_types/field.py b/graphene/new_types/field.py
deleted file mode 100644
index 883bbfdd..00000000
--- a/graphene/new_types/field.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import inspect
-from functools import partial
-from collections import OrderedDict, Mapping
-
-from ..utils.orderedtype import OrderedType
-from .structures import NonNull
-from .argument import to_arguments
-
-
-def source_resolver(source, root, args, context, info):
- resolved = getattr(root, source, None)
- if inspect.isfunction(resolved):
- return resolved()
- return resolved
-
-
-class Field(OrderedType):
-
- def __init__(self, type, args=None, resolver=None, source=None,
- deprecation_reason=None, name=None, description=None,
- required=False, _creation_counter=None, **extra_args):
- super(Field, self).__init__(_creation_counter=_creation_counter)
- assert not args or isinstance(args, Mapping), (
- 'Arguments in a field have to be a mapping, received "{}".'
- ).format(args)
- assert not (source and resolver), (
- 'A Field cannot have a source and a resolver in at the same time.'
- )
-
- if required:
- type = NonNull(type)
-
- self.name = name
- self._type = type
- self.args = to_arguments(args or OrderedDict(), extra_args)
- if source:
- resolver = partial(source_resolver, source)
- self.resolver = resolver
- self.deprecation_reason = deprecation_reason
- self.description = description
-
- @property
- def type(self):
- if inspect.isfunction(self._type):
- return self._type()
- return self._type
diff --git a/graphene/new_types/inputobjecttype.py b/graphene/new_types/inputobjecttype.py
deleted file mode 100644
index aa8f24cc..00000000
--- a/graphene/new_types/inputobjecttype.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import six
-
-from ..utils.is_base_type import is_base_type
-from .options import Options
-
-from .abstracttype import AbstractTypeMeta
-from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
-
-
-class InputObjectTypeMeta(AbstractTypeMeta):
-
- def __new__(cls, name, bases, attrs):
- # Also ensure initialization is only performed for subclasses of
- # InputObjectType
- if not is_base_type(bases, InputObjectTypeMeta):
- return type.__new__(cls, name, bases, attrs)
-
- options = Options(
- attrs.pop('Meta', None),
- name=name,
- description=attrs.get('__doc__'),
- )
-
- attrs = merge_fields_in_attrs(bases, attrs)
- options.fields = get_fields_in_type(InputObjectType, attrs)
- yank_fields_from_attrs(attrs, options.fields)
-
- return type.__new__(cls, name, bases, dict(attrs, _meta=options))
-
- def __str__(cls):
- return cls._meta.name
-
-
-class InputObjectType(six.with_metaclass(InputObjectTypeMeta)):
- def __init__(self, *args, **kwargs):
- raise Exception("An InputObjectType cannot be intitialized")
diff --git a/graphene/new_types/interface.py b/graphene/new_types/interface.py
deleted file mode 100644
index d6c1fe37..00000000
--- a/graphene/new_types/interface.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import six
-
-from ..utils.is_base_type import is_base_type
-from .options import Options
-
-from .abstracttype import AbstractTypeMeta
-from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
-
-
-class InterfaceMeta(AbstractTypeMeta):
-
- def __new__(cls, name, bases, attrs):
- # Also ensure initialization is only performed for subclasses of
- # Interface
- if not is_base_type(bases, InterfaceMeta):
- return type.__new__(cls, name, bases, attrs)
-
- options = Options(
- attrs.pop('Meta', None),
- name=name,
- description=attrs.get('__doc__'),
- )
-
- attrs = merge_fields_in_attrs(bases, attrs)
- options.fields = get_fields_in_type(Interface, attrs)
- yank_fields_from_attrs(attrs, options.fields)
-
- return type.__new__(cls, name, bases, dict(attrs, _meta=options))
-
- def __str__(cls):
- return cls._meta.name
-
-
-class Interface(six.with_metaclass(InterfaceMeta)):
- resolve_type = None
-
- def __init__(self, *args, **kwargs):
- raise Exception("An Interface cannot be intitialized")
-
- # @classmethod
- # def implements(cls, objecttype):
- # pass
diff --git a/graphene/new_types/mutation.py b/graphene/new_types/mutation.py
deleted file mode 100644
index d54740ec..00000000
--- a/graphene/new_types/mutation.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from functools import partial
-
-import six
-
-from ..utils.is_base_type import is_base_type
-from ..utils.props import props
-from .field import Field
-from .objecttype import ObjectType, ObjectTypeMeta
-
-
-class MutationMeta(ObjectTypeMeta):
-
- def __new__(cls, name, bases, attrs):
- # 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_class = attrs.pop('Input', None)
-
- cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
- field_args = props(input_class) if input_class else {}
- resolver = getattr(cls, 'mutate', None)
- assert resolver, 'All mutations must define a mutate method in it'
- cls.Field = partial(Field, cls, args=field_args, resolver=resolver)
- return cls
-
-
-class Mutation(six.with_metaclass(MutationMeta, ObjectType)):
- pass
diff --git a/graphene/new_types/objecttype.py b/graphene/new_types/objecttype.py
deleted file mode 100644
index 3c1c7791..00000000
--- a/graphene/new_types/objecttype.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import six
-
-from ..utils.is_base_type import is_base_type
-from .options import Options
-
-from .abstracttype import AbstractTypeMeta
-from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
-
-
-class ObjectTypeMeta(AbstractTypeMeta):
-
- def __new__(cls, name, bases, attrs):
- # Also ensure initialization is only performed for subclasses of
- # ObjectType
- if not is_base_type(bases, ObjectTypeMeta):
- return type.__new__(cls, name, bases, attrs)
-
- options = Options(
- attrs.pop('Meta', None),
- name=name,
- description=attrs.get('__doc__'),
- interfaces=(),
- )
-
- attrs = merge_fields_in_attrs(bases, attrs)
- options.fields = get_fields_in_type(ObjectType, attrs)
- yank_fields_from_attrs(attrs, options.fields)
-
- return type.__new__(cls, name, bases, dict(attrs, _meta=options))
-
- def __str__(cls):
- return cls._meta.name
-
-
-class ObjectType(six.with_metaclass(ObjectTypeMeta)):
-
- is_type_of = None
-
- def __init__(self, *args, **kwargs):
- # GraphQL ObjectType acting as container
- args_len = len(args)
- fields = self._meta.fields.items()
- if args_len > len(fields):
- # Daft, but matches old exception sans the err msg.
- raise IndexError("Number of args exceeds number of fields")
- fields_iter = iter(fields)
-
- if not kwargs:
- for val, (name, field) in zip(args, fields_iter):
- setattr(self, name, val)
- else:
- for val, (name, field) in zip(args, fields_iter):
- setattr(self, name, val)
- kwargs.pop(name, None)
-
- for name, field in fields_iter:
- try:
- val = kwargs.pop(name)
- setattr(self, name, val)
- except KeyError:
- pass
-
- if kwargs:
- for prop in list(kwargs):
- try:
- if isinstance(getattr(self.__class__, prop), property):
- setattr(self, prop, kwargs.pop(prop))
- except AttributeError:
- pass
- if kwargs:
- raise TypeError(
- "'{}' is an invalid keyword argument for {}".format(
- list(kwargs)[0],
- self.__class__.__name__
- )
- )
diff --git a/graphene/new_types/options.py b/graphene/new_types/options.py
deleted file mode 100644
index 89c1eb5a..00000000
--- a/graphene/new_types/options.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import inspect
-from ..utils.props import props
-
-
-class Options(object):
- '''
- This is the class wrapper around Meta.
- It helps to validate and cointain the attributes inside
- '''
-
- def __init__(self, meta=None, **defaults):
- if meta:
- assert inspect.isclass(meta), (
- 'Meta have to be a class, received "{}".'.format(repr(meta))
- )
-
- meta_attrs = props(meta) if meta else {}
- for attr_name, value in defaults.items():
- if attr_name in meta_attrs:
- value = meta_attrs.pop(attr_name)
- elif hasattr(meta, attr_name):
- value = getattr(meta, attr_name)
- setattr(self, attr_name, value)
-
- # If meta_attrs is not empty, it implicit means
- # it received invalid attributes
- if meta_attrs:
- raise TypeError(
- "Invalid attributes: {}".format(
- ','.join(meta_attrs.keys())
- )
- )
-
- def __repr__(self):
- return ''.format(props(self))
diff --git a/graphene/new_types/scalars.py b/graphene/new_types/scalars.py
deleted file mode 100644
index 838fbd2e..00000000
--- a/graphene/new_types/scalars.py
+++ /dev/null
@@ -1,155 +0,0 @@
-import six
-
-from graphql.language.ast import BooleanValue, FloatValue, IntValue, StringValue
-
-from ..utils.is_base_type import is_base_type
-from .options import Options
-from .unmountedtype import UnmountedType
-
-
-class ScalarTypeMeta(type):
-
- def __new__(cls, name, bases, attrs):
- super_new = super(ScalarTypeMeta, cls).__new__
-
- # Also ensure initialization is only performed for subclasses of Model
- # (excluding Model class itself).
- if not is_base_type(bases, ScalarTypeMeta):
- return super_new(cls, name, bases, attrs)
-
- options = Options(
- attrs.pop('Meta', None),
- name=name,
- description=attrs.get('__doc__'),
- )
-
- return super_new(cls, name, bases, dict(attrs, _meta=options))
-
- def __str__(cls):
- return cls._meta.name
-
-
-class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
- serialize = None
- parse_value = None
- parse_literal = None
-
- @classmethod
- def get_type(cls):
- return cls
-
-# As per the GraphQL Spec, Integers are only treated as valid when a valid
-# 32-bit signed integer, providing the broadest support across platforms.
-#
-# n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
-# they are internally represented as IEEE 754 doubles.
-MAX_INT = 2147483647
-MIN_INT = -2147483648
-
-
-class Int(Scalar):
- '''
- The `Int` scalar type represents non-fractional signed whole numeric
- values. Int can represent values between -(2^53 - 1) and 2^53 - 1 since
- represented in JSON as double-precision floating point numbers specified
- by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
- '''
-
- @staticmethod
- def coerce_int(value):
- try:
- num = int(value)
- except ValueError:
- try:
- num = int(float(value))
- except ValueError:
- return None
- if MIN_INT <= num <= MAX_INT:
- return num
-
- serialize = coerce_int
- parse_value = coerce_int
-
- @staticmethod
- def parse_literal(ast):
- if isinstance(ast, IntValue):
- num = int(ast.value)
- if MIN_INT <= num <= MAX_INT:
- return num
-
-
-class Float(Scalar):
- '''
- The `Float` scalar type represents signed double-precision fractional
- values as specified by
- [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
- '''
-
- @staticmethod
- def coerce_float(value):
- try:
- return float(value)
- except ValueError:
- return None
-
- serialize = coerce_float
- parse_value = coerce_float
-
- @staticmethod
- def parse_literal(ast):
- if isinstance(ast, (FloatValue, IntValue)):
- return float(ast.value)
-
-
-class String(Scalar):
- '''
- The `String` scalar type represents textual data, represented as UTF-8
- character sequences. The String type is most often used by GraphQL to
- represent free-form human-readable text.
- '''
-
- @staticmethod
- def coerce_string(value):
- if isinstance(value, bool):
- return u'true' if value else u'false'
- return six.text_type(value)
-
- serialize = coerce_string
- parse_value = coerce_string
-
- @staticmethod
- def parse_literal(ast):
- if isinstance(ast, StringValue):
- return ast.value
-
-
-class Boolean(Scalar):
- '''
- The `Boolean` scalar type represents `true` or `false`.
- '''
-
- serialize = bool
- parse_value = bool
-
- @staticmethod
- def parse_literal(ast):
- if isinstance(ast, BooleanValue):
- return ast.value
-
-
-class ID(Scalar):
- '''
- The `ID` scalar type represents a unique identifier, often used to
- refetch an object or as key for a cache. The ID type appears in a JSON
- response as a String; however, it is not intended to be human-readable.
- When expected as an input type, any string (such as `"4"`) or integer
- (such as `4`) input value will be accepted as an ID.
- '''
-
- serialize = str
- parse_value = str
-
- @staticmethod
- def parse_literal(ast):
- if isinstance(ast, (StringValue, IntValue)):
- return ast.value
diff --git a/graphene/new_types/schema.py b/graphene/new_types/schema.py
deleted file mode 100644
index 624ce9e1..00000000
--- a/graphene/new_types/schema.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import inspect
-
-from graphql import GraphQLSchema, graphql, is_type
-from graphql.utils.introspection_query import introspection_query
-from graphql.utils.schema_printer import print_schema
-
-
-from .objecttype import ObjectType
-from .structures import List, NonNull
-from .scalars import Scalar, String
-# from ..utils.get_graphql_type import get_graphql_type
-
-
-# from graphql.type.schema import assert_object_implements_interface
-
-# from collections import defaultdict
-
-
-from graphql.type.directives import (GraphQLDirective, GraphQLIncludeDirective,
- GraphQLSkipDirective)
-from graphql.type.introspection import IntrospectionSchema
-from .typemap import TypeMap, is_graphene_type
-
-
-class Schema(GraphQLSchema):
-
- def __init__(self, query=None, mutation=None, subscription=None, directives=None, types=None, executor=None):
- self._query = query
- self._mutation = mutation
- self._subscription = subscription
- self.types = types
- self._executor = executor
- if directives is None:
- directives = [
- GraphQLIncludeDirective,
- GraphQLSkipDirective
- ]
-
- assert all(isinstance(d, GraphQLDirective) for d in directives), \
- 'Schema directives must be List[GraphQLDirective] if provided but got: {}.'.format(
- directives
- )
-
- self._directives = directives
- initial_types = [
- query,
- mutation,
- subscription,
- IntrospectionSchema
- ]
- if types:
- initial_types += types
- self._type_map = TypeMap(initial_types)
-
- def get_query_type(self):
- return self.get_graphql_type(self._query)
-
- def get_mutation_type(self):
- return self.get_graphql_type(self._mutation)
-
- def get_subscription_type(self):
- return self.get_graphql_type(self._subscription)
-
- def get_graphql_type(self, _type):
- if is_type(_type):
- return _type
- if is_graphene_type(_type):
- graphql_type = self.get_type(_type._meta.name)
- assert graphql_type, "Type {} not found in this schema.".format(_type._meta.name)
- assert graphql_type.graphene_type == _type
- return graphql_type
- raise Exception("{} is not a valid GraphQL type.".format(_type))
-
- def execute(self, request_string='', root_value=None, variable_values=None,
- context_value=None, operation_name=None, executor=None):
- return graphql(
- schema=self,
- request_string=request_string,
- root_value=root_value,
- context_value=context_value,
- variable_values=variable_values,
- operation_name=operation_name,
- executor=executor or self._executor
- )
-
- def register(self, object_type):
- self.types.append(object_type)
-
- def introspect(self):
- return self.execute(introspection_query).data
-
- def __str__(self):
- return print_schema(self)
-
- def lazy(self, _type):
- return lambda: self.get_type(_type)
-
- # def rebuild(self):
- # self._possible_type_map = defaultdict(set)
- # self._type_map = self._build_type_map(self.types)
- # # Keep track of all implementations by interface name.
- # self._implementations = defaultdict(list)
- # for type in self._type_map.values():
- # if isinstance(type, GraphQLObjectType):
- # for interface in type.get_interfaces():
- # self._implementations[interface.name].append(type)
-
- # # Enforce correct interface implementations.
- # for type in self._type_map.values():
- # if isinstance(type, GraphQLObjectType):
- # for interface in type.get_interfaces():
- # assert_object_implements_interface(self, type, interface)
diff --git a/graphene/new_types/structures.py b/graphene/new_types/structures.py
deleted file mode 100644
index 41fcd5dd..00000000
--- a/graphene/new_types/structures.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from .unmountedtype import UnmountedType
-
-
-class Structure(UnmountedType):
- '''
- A structure is a GraphQL type instance that
- wraps a main type with certain structure.
- '''
-
- def __init__(self, of_type, *args, **kwargs):
- super(Structure, self).__init__(*args, **kwargs)
- self.of_type = of_type
-
- def get_type(self):
- return self
-
-
-class List(Structure):
- def __str__(self):
- return '[{}]'.format(self.of_type)
-
-
-class NonNull(Structure):
- def __str__(self):
- return '{}!'.format(self.of_type)
diff --git a/graphene/new_types/tests/__init__.py b/graphene/new_types/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/graphene/new_types/tests/test_enum.py b/graphene/new_types/tests/test_enum.py
deleted file mode 100644
index c16cbc99..00000000
--- a/graphene/new_types/tests/test_enum.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from ..enum import Enum, PyEnum
-
-
-def test_enum_construction():
- class RGB(Enum):
- '''Description'''
- RED = 1
- GREEN = 2
- BLUE = 3
-
- @property
- def description(self):
- return "Description {}".format(self.name)
-
- assert RGB._meta.name == 'RGB'
- assert RGB._meta.description == 'Description'
-
- values = RGB._meta.enum.__members__.values()
- assert sorted([v.name for v in values]) == [
- 'BLUE',
- 'GREEN',
- 'RED'
- ]
- assert sorted([v.description for v in values]) == [
- 'Description BLUE',
- 'Description GREEN',
- 'Description RED'
- ]
-
-
-def test_enum_construction_meta():
- class RGB(Enum):
- class Meta:
- name = 'RGBEnum'
- description = 'Description'
- RED = 1
- GREEN = 2
- BLUE = 3
-
- assert RGB._meta.name == 'RGBEnum'
- assert RGB._meta.description == 'Description'
-
-
-def test_enum_instance_construction():
- RGB = Enum('RGB', 'RED,GREEN,BLUE')
-
- values = RGB._meta.enum.__members__.values()
- assert sorted([v.name for v in values]) == [
- 'BLUE',
- 'GREEN',
- 'RED'
- ]
-
-
-def test_enum_from_builtin_enum():
- PyRGB = PyEnum('RGB', 'RED,GREEN,BLUE')
-
- RGB = Enum.from_enum(PyRGB)
- assert RGB._meta.enum == PyRGB
- assert RGB.RED
- assert RGB.GREEN
- assert RGB.BLUE
-
-
-def test_enum_value_from_class():
- class RGB(Enum):
- RED = 1
- GREEN = 2
- BLUE = 3
-
- assert RGB.RED.value == 1
- assert RGB.GREEN.value == 2
- assert RGB.BLUE.value == 3
diff --git a/graphene/new_types/tests/test_field.py b/graphene/new_types/tests/test_field.py
deleted file mode 100644
index 31fcf037..00000000
--- a/graphene/new_types/tests/test_field.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import pytest
-
-from ..field import Field
-from ..structures import NonNull
-from ..argument import Argument
-
-
-class MyInstance(object):
- value = 'value'
- value_func = staticmethod(lambda: 'value_func')
-
-
-def test_field_basic():
- MyType = object()
- args = {'my arg': Argument(True)}
- resolver = lambda: None
- deprecation_reason = 'Deprecated now'
- description = 'My Field'
- field = Field(
- MyType,
- name='name',
- args=args,
- resolver=resolver,
- description=description,
- deprecation_reason=deprecation_reason
- )
- assert field.name == 'name'
- assert field.args == args
- assert field.resolver == resolver
- assert field.deprecation_reason == deprecation_reason
- assert field.description == description
-
-
-def test_field_required():
- MyType = object()
- field = Field(MyType, required=True)
- assert isinstance(field.type, NonNull)
- assert field.type.of_type == MyType
-
-
-def test_field_source():
- MyType = object()
- field = Field(MyType, source='value')
- assert field.resolver(MyInstance, {}, None, None) == MyInstance.value
-
-
-def test_field_with_lazy_type():
- MyType = object()
- field = Field(lambda: MyType)
- assert field.type == MyType
-
-
-def test_field_not_source_and_resolver():
- MyType = object()
- with pytest.raises(Exception) as exc_info:
- Field(MyType, source='value', resolver=lambda: None)
- assert str(exc_info.value) == 'A Field cannot have a source and a resolver in at the same time.'
-
-
-def test_field_source_func():
- MyType = object()
- field = Field(MyType, source='value_func')
- assert field.resolver(MyInstance(), {}, None, None) == MyInstance.value_func()
-
-
-def test_field_source_argument_as_kw():
- MyType = object()
- field = Field(MyType, b=NonNull(True), c=Argument(None), a=NonNull(False))
- assert field.args.keys() == ['b', 'c', 'a']
- assert isinstance(field.args['b'], Argument)
- assert isinstance(field.args['b'].type, NonNull)
- assert field.args['b'].type.of_type is True
- assert isinstance(field.args['c'], Argument)
- assert field.args['c'].type is None
- assert isinstance(field.args['a'], Argument)
- assert isinstance(field.args['a'].type, NonNull)
- assert field.args['a'].type.of_type is False
diff --git a/graphene/new_types/tests/test_inputobjecttype.py b/graphene/new_types/tests/test_inputobjecttype.py
deleted file mode 100644
index 52796749..00000000
--- a/graphene/new_types/tests/test_inputobjecttype.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import pytest
-
-from ..field import Field
-from ..inputfield import InputField
-from ..inputobjecttype import InputObjectType
-from ..unmountedtype import UnmountedType
-from ..abstracttype import AbstractType
-
-
-class MyType(object):
- pass
-
-
-class MyScalar(UnmountedType):
- def get_type(self):
- return MyType
-
-
-def test_generate_inputobjecttype():
- class MyInputObjectType(InputObjectType):
- '''Documentation'''
-
- assert MyInputObjectType._meta.name == "MyInputObjectType"
- assert MyInputObjectType._meta.description == "Documentation"
- assert MyInputObjectType._meta.fields == {}
-
-
-def test_generate_inputobjecttype_with_meta():
- class MyInputObjectType(InputObjectType):
-
- class Meta:
- name = 'MyOtherInputObjectType'
- description = 'Documentation'
-
- assert MyInputObjectType._meta.name == "MyOtherInputObjectType"
- assert MyInputObjectType._meta.description == "Documentation"
-
-
-def test_generate_inputobjecttype_with_fields():
- class MyInputObjectType(InputObjectType):
- field = Field(MyType)
-
- assert 'field' in MyInputObjectType._meta.fields
-
-
-def test_ordered_fields_in_inputobjecttype():
- class MyInputObjectType(InputObjectType):
- b = InputField(MyType)
- a = InputField(MyType)
- field = MyScalar()
- asa = InputField(MyType)
-
- assert list(MyInputObjectType._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-
-
-def test_generate_inputobjecttype_unmountedtype():
- class MyInputObjectType(InputObjectType):
- field = MyScalar(MyType)
-
- assert 'field' in MyInputObjectType._meta.fields
- assert isinstance(MyInputObjectType._meta.fields['field'], InputField)
-
-
-def test_generate_inputobjecttype_inherit_abstracttype():
- class MyAbstractType(AbstractType):
- field1 = MyScalar(MyType)
-
- class MyInputObjectType(InputObjectType, MyAbstractType):
- field2 = MyScalar(MyType)
-
- assert MyInputObjectType._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [InputField, InputField]
-
-
-def test_generate_inputobjecttype_inherit_abstracttype_reversed():
- class MyAbstractType(AbstractType):
- field1 = MyScalar(MyType)
-
- class MyInputObjectType(MyAbstractType, InputObjectType):
- field2 = MyScalar(MyType)
-
- assert MyInputObjectType._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [InputField, InputField]
diff --git a/graphene/new_types/tests/test_interface.py b/graphene/new_types/tests/test_interface.py
deleted file mode 100644
index 97804c5c..00000000
--- a/graphene/new_types/tests/test_interface.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import pytest
-
-from ..field import Field
-from ..interface import Interface
-from ..unmountedtype import UnmountedType
-from ..abstracttype import AbstractType
-
-
-class MyType(object):
- pass
-
-
-class MyScalar(UnmountedType):
- def get_type(self):
- return MyType
-
-
-def test_generate_interface():
- class MyInterface(Interface):
- '''Documentation'''
-
- assert MyInterface._meta.name == "MyInterface"
- assert MyInterface._meta.description == "Documentation"
- assert MyInterface._meta.fields == {}
-
-
-def test_generate_interface_with_meta():
- class MyInterface(Interface):
-
- class Meta:
- name = 'MyOtherInterface'
- description = 'Documentation'
-
- assert MyInterface._meta.name == "MyOtherInterface"
- assert MyInterface._meta.description == "Documentation"
-
-
-def test_generate_interface_with_fields():
- class MyInterface(Interface):
- field = Field(MyType)
-
- assert 'field' in MyInterface._meta.fields
-
-
-def test_ordered_fields_in_interface():
- class MyInterface(Interface):
- b = Field(MyType)
- a = Field(MyType)
- field = MyScalar()
- asa = Field(MyType)
-
- assert list(MyInterface._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-
-
-def test_generate_interface_unmountedtype():
- class MyInterface(Interface):
- field = MyScalar()
-
- assert 'field' in MyInterface._meta.fields
- assert isinstance(MyInterface._meta.fields['field'], Field)
-
-
-def test_generate_interface_inherit_abstracttype():
- class MyAbstractType(AbstractType):
- field1 = MyScalar()
-
- class MyInterface(Interface, MyAbstractType):
- field2 = MyScalar()
-
- assert MyInterface._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
-
-
-def test_generate_interface_inherit_abstracttype_reversed():
- class MyAbstractType(AbstractType):
- field1 = MyScalar()
-
- class MyInterface(MyAbstractType, Interface):
- field2 = MyScalar()
-
- assert MyInterface._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
diff --git a/graphene/new_types/tests/test_mutation.py b/graphene/new_types/tests/test_mutation.py
deleted file mode 100644
index 2b4a8859..00000000
--- a/graphene/new_types/tests/test_mutation.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import pytest
-
-from ..field import Field
-from ..mutation import Mutation
-from ..objecttype import ObjectType
-from ..scalars import String
-
-
-def test_generate_mutation_no_args():
- class MyMutation(Mutation):
- '''Documentation'''
- @classmethod
- def mutate(cls, *args, **kwargs):
- pass
-
- assert issubclass(MyMutation, ObjectType)
- assert MyMutation._meta.name == "MyMutation"
- assert MyMutation._meta.description == "Documentation"
- assert MyMutation.Field().resolver == MyMutation.mutate
-
-
-# def test_generate_mutation_with_args():
-# class MyMutation(Mutation):
-# '''Documentation'''
-# class Input:
-# s = String()
-
-# @classmethod
-# def mutate(cls, *args, **kwargs):
-# pass
-
-# graphql_type = MyMutation._meta.graphql_type
-# field = MyMutation.Field()
-# assert graphql_type.name == "MyMutation"
-# assert graphql_type.description == "Documentation"
-# assert isinstance(field, Field)
-# assert field.type == MyMutation._meta.graphql_type
-# assert 's' in field.args
-# assert field.args['s'].type == String
-
-
-def test_generate_mutation_with_meta():
- class MyMutation(Mutation):
-
- class Meta:
- name = 'MyOtherMutation'
- description = 'Documentation'
-
- @classmethod
- def mutate(cls, *args, **kwargs):
- pass
-
- assert MyMutation._meta.name == "MyOtherMutation"
- assert MyMutation._meta.description == "Documentation"
- assert MyMutation.Field().resolver == MyMutation.mutate
-
-
-def test_mutation_raises_exception_if_no_mutate():
- with pytest.raises(AssertionError) as excinfo:
- class MyMutation(Mutation):
- pass
-
- assert "All mutations must define a mutate method in it" == str(excinfo.value)
diff --git a/graphene/new_types/tests/test_objecttype.py b/graphene/new_types/tests/test_objecttype.py
deleted file mode 100644
index 9b8b3913..00000000
--- a/graphene/new_types/tests/test_objecttype.py
+++ /dev/null
@@ -1,131 +0,0 @@
-import pytest
-
-from ..field import Field
-from ..objecttype import ObjectType
-from ..unmountedtype import UnmountedType
-from ..abstracttype import AbstractType
-
-
-class MyType(object):
- pass
-
-
-class Container(ObjectType):
- field1 = Field(MyType)
- field2 = Field(MyType)
-
-
-class MyScalar(UnmountedType):
- def get_type(self):
- return MyType
-
-
-def test_generate_objecttype():
- class MyObjectType(ObjectType):
- '''Documentation'''
-
- assert MyObjectType._meta.name == "MyObjectType"
- assert MyObjectType._meta.description == "Documentation"
- assert MyObjectType._meta.interfaces == tuple()
- assert MyObjectType._meta.fields == {}
-
-
-def test_generate_objecttype_with_meta():
- class MyObjectType(ObjectType):
-
- class Meta:
- name = 'MyOtherObjectType'
- description = 'Documentation'
- interfaces = (MyType, )
-
- assert MyObjectType._meta.name == "MyOtherObjectType"
- assert MyObjectType._meta.description == "Documentation"
- assert MyObjectType._meta.interfaces == (MyType, )
-
-
-def test_generate_objecttype_with_fields():
- class MyObjectType(ObjectType):
- field = Field(MyType)
-
- assert 'field' in MyObjectType._meta.fields
-
-
-def test_ordered_fields_in_objecttype():
- class MyObjectType(ObjectType):
- b = Field(MyType)
- a = Field(MyType)
- field = MyScalar()
- asa = Field(MyType)
-
- assert list(MyObjectType._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-
-
-def test_generate_objecttype_inherit_abstracttype():
- class MyAbstractType(AbstractType):
- field1 = MyScalar()
-
- class MyObjectType(ObjectType, MyAbstractType):
- field2 = MyScalar()
-
- assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
-
-
-def test_generate_objecttype_inherit_abstracttype_reversed():
- class MyAbstractType(AbstractType):
- field1 = MyScalar()
-
- class MyObjectType(MyAbstractType, ObjectType):
- field2 = MyScalar()
-
- assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
- assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
-
-
-def test_generate_objecttype_unmountedtype():
- class MyObjectType(ObjectType):
- field = MyScalar()
-
- assert 'field' in MyObjectType._meta.fields
- assert isinstance(MyObjectType._meta.fields['field'], Field)
-
-
-def test_parent_container_get_fields():
- assert list(Container._meta.fields.keys()) == ['field1', 'field2']
-
-
-def test_objecttype_as_container_only_args():
- container = Container("1", "2")
- assert container.field1 == "1"
- assert container.field2 == "2"
-
-
-def test_objecttype_as_container_args_kwargs():
- container = Container("1", field2="2")
- assert container.field1 == "1"
- assert container.field2 == "2"
-
-
-def test_objecttype_as_container_few_kwargs():
- container = Container(field2="2")
- assert container.field2 == "2"
-
-
-def test_objecttype_as_container_all_kwargs():
- container = Container(field1="1", field2="2")
- assert container.field1 == "1"
- assert container.field2 == "2"
-
-
-def test_objecttype_as_container_extra_args():
- with pytest.raises(IndexError) as excinfo:
- Container("1", "2", "3")
-
- assert "Number of args exceeds number of fields" == str(excinfo.value)
-
-
-def test_objecttype_as_container_invalid_kwargs():
- with pytest.raises(TypeError) as excinfo:
- Container(unexisting_field="3")
-
- assert "'unexisting_field' is an invalid keyword argument for Container" == str(excinfo.value)
diff --git a/graphene/new_types/unmountedtype.py b/graphene/new_types/unmountedtype.py
deleted file mode 100644
index ac813e8e..00000000
--- a/graphene/new_types/unmountedtype.py
+++ /dev/null
@@ -1,70 +0,0 @@
-from ..utils.orderedtype import OrderedType
-
-
-class UnmountedType(OrderedType):
- '''
- This class acts a proxy for a Graphene Type, so it can be mounted
- as Field, InputField or Argument.
-
- Instead of writing
- >>> class MyObjectType(ObjectType):
- >>> my_field = Field(String(), description='Description here')
-
- It let you write
- >>> class MyObjectType(ObjectType):
- >>> my_field = String(description='Description here')
- '''
-
- def __init__(self, *args, **kwargs):
- super(UnmountedType, self).__init__()
- self.args = args
- self.kwargs = kwargs
-
- def get_type(self):
- raise NotImplementedError("get_type not implemented in {}".format(self))
-
- def as_field(self):
- '''
- Mount the UnmountedType as Field
- '''
- from .field import Field
- return Field(
- self.get_type(),
- *self.args,
- _creation_counter=self.creation_counter,
- **self.kwargs
- )
-
- def as_inputfield(self):
- '''
- Mount the UnmountedType as InputField
- '''
- from .inputfield import InputField
- return InputField(
- self.get_type(),
- *self.args,
- _creation_counter=self.creation_counter,
- **self.kwargs
- )
-
- def as_argument(self):
- '''
- Mount the UnmountedType as Argument
- '''
- from .argument import Argument
- return Argument(
- self.get_type(),
- *self.args,
- _creation_counter=self.creation_counter,
- **self.kwargs
- )
-
- def __eq__(self, other):
- return (
- self is other or (
- isinstance(other, UnmountedType) and
- self.get_type() == other.get_type() and
- self.args == other.args and
- self.kwargs == other.kwargs
- )
- )
diff --git a/graphene/types/__init__.py b/graphene/types/__init__.py
index e43ad73a..9523d7fd 100644
--- a/graphene/types/__init__.py
+++ b/graphene/types/__init__.py
@@ -1,13 +1,17 @@
-from .objecttype import ObjectType, Interface
+from .objecttype import ObjectType
+from .abstracttype import AbstractType
+from .interface import Interface
from .scalars import Scalar, String, ID, Int, Float, Boolean
from .schema import Schema
from .structures import List, NonNull
from .enum import Enum
-from .field import Field, InputField
+from .field import Field
+from .inputfield import InputField
from .argument import Argument
from .inputobjecttype import InputObjectType
__all__ = [
+ 'AbstractType',
'ObjectType',
'InputObjectType',
'Interface',
diff --git a/graphene/new_types/abstracttype.py b/graphene/types/abstracttype.py
similarity index 100%
rename from graphene/new_types/abstracttype.py
rename to graphene/types/abstracttype.py
diff --git a/graphene/types/argument.py b/graphene/types/argument.py
index fa816a5f..b16aef47 100644
--- a/graphene/types/argument.py
+++ b/graphene/types/argument.py
@@ -1,77 +1,33 @@
-import inspect
from collections import OrderedDict
from itertools import chain
-from graphql.type.definition import GraphQLArgument, GraphQLArgumentDefinition
-from graphql.utils.assert_valid_name import assert_valid_name
-
from ..utils.orderedtype import OrderedType
-from ..utils.str_converters import to_camel_case
-class Argument(GraphQLArgument, OrderedType):
+class Argument(OrderedType):
def __init__(self, type, default_value=None, description=None, name=None, _creation_counter=None):
+ super(Argument, self).__init__(_creation_counter=_creation_counter)
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
-
- @classmethod
- def copy_from(cls, argument):
- if isinstance(argument, (GraphQLArgumentDefinition, Argument)):
- name = argument.name
- else:
- name = None
- return cls(
- type=argument.type,
- default_value=argument.default_value,
- description=argument.description,
- name=name,
- _creation_counter=argument.creation_counter if isinstance(argument, Argument) else None,
- )
-def to_arguments(*args, **extra):
+def to_arguments(args, extra_args):
from .unmountedtype import UnmountedType
- args = list(filter(None, args)) + [extra]
- arguments = []
- iter_arguments = chain(*[arg.items() for arg in args])
- arguments_names = set()
+ extra_args = sorted(extra_args.items(), key=lambda f: f[1])
+ iter_arguments = chain(args.items() + extra_args)
+ arguments = OrderedDict()
for default_name, arg in iter_arguments:
if isinstance(arg, UnmountedType):
arg = arg.as_argument()
- if not isinstance(arg, GraphQLArgument):
+ if not isinstance(arg, Argument):
raise ValueError('Unknown argument "{}".'.format(default_name))
- arg = Argument.copy_from(arg)
- arg.name = arg.name or default_name and to_camel_case(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)
+ arg_name = default_name or arg.name
+ assert arg_name not in arguments, 'More than one Argument have same name "{}".'.format(arg.name)
+ arguments[arg_name] = arg
- return OrderedDict([(a.name, a) for a in sorted(arguments)])
+ return arguments
diff --git a/graphene/types/datetime.py b/graphene/types/datetime.py
index bdf5870e..9baa731e 100644
--- a/graphene/types/datetime.py
+++ b/graphene/types/datetime.py
@@ -16,6 +16,11 @@ except:
class DateTime(Scalar):
+ '''
+ The `DateTime` scalar type represents a DateTime
+ value as specified by
+ [iso8601](https://en.wikipedia.org/wiki/ISO_8601).
+ '''
@staticmethod
def serialize(dt):
diff --git a/graphene/types/enum.py b/graphene/types/enum.py
index 0f8ba122..02493b30 100644
--- a/graphene/types/enum.py
+++ b/graphene/types/enum.py
@@ -16,31 +16,22 @@ except ImportError:
class EnumTypeMeta(type):
def __new__(cls, name, bases, attrs):
- super_new = type.__new__
-
# Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself).
if not is_base_type(bases, EnumTypeMeta):
- return super_new(cls, name, bases, attrs)
+ return type.__new__(cls, name, bases, attrs)
options = Options(
attrs.pop('Meta', None),
- name=None,
- description=None,
+ name=name,
+ description=attrs.get('__doc__'),
enum=None,
- graphql_type=None
)
if not options.enum:
options.enum = PyEnum(cls.__name__, attrs)
new_attrs = OrderedDict(attrs, _meta=options, **options.enum.__members__)
-
- cls = super_new(cls, name, bases, new_attrs)
-
- if not options.graphql_type:
- options.graphql_type = generate_enum(cls)
-
- return cls
+ return type.__new__(cls, name, bases, new_attrs)
def __prepare__(name, bases, **kwargs): # noqa: N805
return OrderedDict()
@@ -51,10 +42,13 @@ class EnumTypeMeta(type):
return cls.from_enum(PyEnum(*args, **kwargs), description=description)
return super(EnumTypeMeta, cls).__call__(*args, **kwargs)
-
-class Enum(six.with_metaclass(EnumTypeMeta, UnmountedType)):
-
- @classmethod
def from_enum(cls, enum, description=None):
meta_class = type('Meta', (object,), {'enum': enum, 'description': description})
return type(meta_class.enum.__name__, (Enum,), {'Meta': meta_class})
+
+ def __str__(cls):
+ return cls._meta.name
+
+
+class Enum(six.with_metaclass(EnumTypeMeta, UnmountedType)):
+ pass
diff --git a/graphene/types/field.py b/graphene/types/field.py
index 2f687381..883bbfdd 100644
--- a/graphene/types/field.py
+++ b/graphene/types/field.py
@@ -1,221 +1,46 @@
import inspect
-from collections import OrderedDict
-
-from graphql.type import (GraphQLField, GraphQLFieldDefinition,
- GraphQLInputObjectField)
-from graphql.utils.assert_valid_name import assert_valid_name
+from functools import partial
+from collections import OrderedDict, Mapping
from ..utils.orderedtype import OrderedType
-from ..utils.str_converters import to_camel_case
+from .structures import NonNull
from .argument import to_arguments
-class AbstractField(object):
+def source_resolver(source, root, args, context, info):
+ resolved = getattr(root, source, None)
+ if inspect.isfunction(resolved):
+ return resolved()
+ return resolved
- @property
- def name(self):
- return self._name or self.attname and to_camel_case(self.attname)
- @name.setter
- def name(self, name):
- if name is not None:
- assert_valid_name(name)
- self._name = name
+class Field(OrderedType):
+
+ def __init__(self, type, args=None, resolver=None, source=None,
+ deprecation_reason=None, name=None, description=None,
+ required=False, _creation_counter=None, **extra_args):
+ super(Field, self).__init__(_creation_counter=_creation_counter)
+ assert not args or isinstance(args, Mapping), (
+ 'Arguments in a field have to be a mapping, received "{}".'
+ ).format(args)
+ assert not (source and resolver), (
+ 'A Field cannot have a source and a resolver in at the same time.'
+ )
+
+ if required:
+ type = NonNull(type)
+
+ self.name = name
+ self._type = type
+ self.args = to_arguments(args or OrderedDict(), extra_args)
+ if source:
+ resolver = partial(source_resolver, source)
+ self.resolver = resolver
+ self.deprecation_reason = deprecation_reason
+ self.description = description
@property
def type(self):
- from ..utils.get_graphql_type import get_graphql_type
- from .structures import NonNull
if inspect.isfunction(self._type):
- _type = self._type()
- else:
- _type = self._type
-
- if self.required:
- return NonNull(_type)
- return get_graphql_type(_type)
-
- @type.setter
- def type(self, type):
- self._type = type
-
-
-class Field(AbstractField, GraphQLField, OrderedType):
-
- def __init__(self, type, args=None, resolver=None, source=None, deprecation_reason=None,
- name=None, description=None, required=False, _creation_counter=None, **extra_args):
- self.name = name
- self.attname = None
- self.parent = None
- self.type = type
- self.args = to_arguments(args, extra_args)
- assert not (source and resolver), ('You cannot have a source '
- 'and a resolver at the same time')
-
- self.resolver = resolver
- self.source = source
- self.required = required
- self.deprecation_reason = deprecation_reason
- self.description = description
- OrderedType.__init__(self, _creation_counter=_creation_counter)
-
- def mount_error_message(self, where):
- return 'Field "{}" can only be mounted in ObjectType or Interface, received {}.'.format(
- self,
- where.__name__
- )
-
- def mount(self, parent, attname=None):
- from .objecttype import ObjectType
- from .interface import Interface
- assert issubclass(parent, (ObjectType, Interface)), self.mount_error_message(parent)
-
- self.attname = attname
- self.parent = parent
-
- def default_resolver(self, root, args, context, info):
- return getattr(root, self.source or self.attname, None)
-
- @property
- def resolver(self):
- resolver = getattr(self.parent, 'resolve_{}'.format(self.attname), None)
-
- # We try to get the resolver from the interfaces
- # This is not needed anymore as Interfaces could be extended now with Python syntax
- # if not resolver and issubclass(self.parent, ObjectType):
- # graphql_type = self.parent._meta.graphql_type
- # interfaces = graphql_type._provided_interfaces or []
- # for interface in interfaces:
- # if not isinstance(interface, GrapheneInterfaceType):
- # continue
- # fields = interface.get_fields()
- # if self.attname in fields:
- # resolver = getattr(interface.graphene_type, 'resolve_{}'.format(self.attname), None)
- # if resolver:
- # # We remove the bounding to the method
- # resolver = resolver #.__func__
- # break
-
- if resolver:
- resolver = getattr(resolver, '__func__', resolver)
- else:
- resolver = self.default_resolver
-
- # def resolver_wrapper(root, *args, **kwargs):
- # if not isinstance(root, self.parent):
- # root = self.parent()
- # return resolver(root, *args, **kwargs)
-
- return self._resolver or resolver # resolver_wrapper
-
- @resolver.setter
- def resolver(self, resolver):
- self._resolver = resolver
-
- def __copy__(self):
- return self.copy_and_extend(self)
-
- @classmethod
- def copy_and_extend(
- cls, field, type=None, args=None, resolver=None, source=None, deprecation_reason=None, name=None,
- description=None, required=False, _creation_counter=False, parent=None, attname=None, **extra_args):
- if isinstance(field, Field):
- type = type or field._type
- resolver = resolver or field._resolver
- source = source or field.source
- name = name or field._name
- required = required or field.required
- _creation_counter = field.creation_counter if _creation_counter is False else None
- attname = attname or field.attname
- parent = parent or field.parent
- args = to_arguments(args, field.args)
- else:
- # If is a GraphQLField
- type = type or field.type
- resolver = resolver or field.resolver
- 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
- attname = attname or name
- parent = parent
-
- new_field = cls(
- type=type,
- args=args,
- resolver=resolver,
- source=source,
- deprecation_reason=field.deprecation_reason,
- name=name,
- required=required,
- description=field.description,
- _creation_counter=_creation_counter,
- **extra_args
- )
- new_field.attname = attname
- new_field.parent = parent
- return new_field
-
- def __str__(self):
- if not self.parent:
- return 'Not bounded field'
- return "{}.{}".format(self.parent._meta.graphql_type, self.attname)
-
-
-class InputField(AbstractField, GraphQLInputObjectField, OrderedType):
-
- def __init__(self, type, default_value=None, description=None, name=None, required=False, _creation_counter=None):
- self.name = name
- self.type = type
- self.default_value = default_value
- self.description = description
- self.required = required
- self.attname = None
- self.parent = None
- OrderedType.__init__(self, _creation_counter=_creation_counter)
-
- def mount_error_message(self, where):
- return 'InputField {} can only be mounted in InputObjectType classes, received {}.'.format(
- self,
- where.__name__
- )
-
- def mount(self, parent, attname):
- from .inputobjecttype import InputObjectType
-
- assert issubclass(parent, (InputObjectType)), self.mount_error_message(parent)
- self.attname = attname
- self.parent = parent
-
- def __copy__(self):
- return self.copy_and_extend(self)
-
- @classmethod
- def copy_and_extend(cls, field, type=None, default_value=None, description=None, name=None,
- required=False, parent=None, attname=None, _creation_counter=False):
- if isinstance(field, Field):
- type = type or field._type
- name = name or field._name
- required = required or field.required
- _creation_counter = field.creation_counter if _creation_counter is False else None
- attname = attname or field.attname
- parent = parent or field.parent
- else:
- # If is a GraphQLField
- type = type or field.type
- name = field.name
- _creation_counter = None
-
- new_field = cls(
- type=type,
- name=name,
- required=required,
- default_value=default_value or field.default_value,
- description=description or field.description,
- _creation_counter=_creation_counter,
- )
- new_field.attname = attname
- new_field.parent = parent
- return new_field
+ return self._type()
+ return self._type
diff --git a/graphene/new_types/inputfield.py b/graphene/types/inputfield.py
similarity index 100%
rename from graphene/new_types/inputfield.py
rename to graphene/types/inputfield.py
diff --git a/graphene/types/inputobjecttype.py b/graphene/types/inputobjecttype.py
index 46a1ffdd..aa8f24cc 100644
--- a/graphene/types/inputobjecttype.py
+++ b/graphene/types/inputobjecttype.py
@@ -1,49 +1,36 @@
import six
-from ..generators import generate_inputobjecttype
-from ..utils.copy_fields import copy_fields
-from ..utils.get_fields import get_fields
from ..utils.is_base_type import is_base_type
-from .field import InputField
-from .objecttype import attrs_without_fields
from .options import Options
-from .unmountedtype import UnmountedType
+
+from .abstracttype import AbstractTypeMeta
+from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
-class InputObjectTypeMeta(type):
+class InputObjectTypeMeta(AbstractTypeMeta):
def __new__(cls, name, bases, attrs):
- super_new = super(InputObjectTypeMeta, 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
+ # InputObjectType
if not is_base_type(bases, InputObjectTypeMeta):
- return super_new(cls, name, bases, attrs)
+ return type.__new__(cls, name, bases, attrs)
options = Options(
attrs.pop('Meta', None),
- name=None,
- description=None,
- graphql_type=None,
+ name=name,
+ description=attrs.get('__doc__'),
)
- fields = get_fields(InputObjectType, attrs, bases)
- attrs = attrs_without_fields(attrs, fields)
- cls = super_new(cls, name, bases, dict(attrs, _meta=options))
+ attrs = merge_fields_in_attrs(bases, attrs)
+ options.fields = get_fields_in_type(InputObjectType, attrs)
+ yank_fields_from_attrs(attrs, options.fields)
- if not options.graphql_type:
- fields = copy_fields(InputField, fields, parent=cls)
- options.get_fields = lambda: fields
- options.graphql_type = generate_inputobjecttype(cls)
- else:
- assert not fields, "Can't mount InputFields in an InputObjectType with a defined graphql_type"
- fields = copy_fields(InputField, options.graphql_type.get_fields(), parent=cls)
+ return type.__new__(cls, name, bases, dict(attrs, _meta=options))
- for name, field in fields.items():
- setattr(cls, field.attname or name, field)
-
- return cls
+ def __str__(cls):
+ return cls._meta.name
-class InputObjectType(six.with_metaclass(InputObjectTypeMeta, UnmountedType)):
- pass
+class InputObjectType(six.with_metaclass(InputObjectTypeMeta)):
+ def __init__(self, *args, **kwargs):
+ raise Exception("An InputObjectType cannot be intitialized")
diff --git a/graphene/types/interface.py b/graphene/types/interface.py
index 56fc0ebb..d6c1fe37 100644
--- a/graphene/types/interface.py
+++ b/graphene/types/interface.py
@@ -1,3 +1,42 @@
-from .objecttype import Interface
+import six
-__all__ = ['Interface']
+from ..utils.is_base_type import is_base_type
+from .options import Options
+
+from .abstracttype import AbstractTypeMeta
+from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
+
+
+class InterfaceMeta(AbstractTypeMeta):
+
+ def __new__(cls, name, bases, attrs):
+ # Also ensure initialization is only performed for subclasses of
+ # Interface
+ if not is_base_type(bases, InterfaceMeta):
+ return type.__new__(cls, name, bases, attrs)
+
+ options = Options(
+ attrs.pop('Meta', None),
+ name=name,
+ description=attrs.get('__doc__'),
+ )
+
+ attrs = merge_fields_in_attrs(bases, attrs)
+ options.fields = get_fields_in_type(Interface, attrs)
+ yank_fields_from_attrs(attrs, options.fields)
+
+ return type.__new__(cls, name, bases, dict(attrs, _meta=options))
+
+ def __str__(cls):
+ return cls._meta.name
+
+
+class Interface(six.with_metaclass(InterfaceMeta)):
+ resolve_type = None
+
+ def __init__(self, *args, **kwargs):
+ raise Exception("An Interface cannot be intitialized")
+
+ # @classmethod
+ # def implements(cls, objecttype):
+ # pass
diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py
index 018f8ef9..d54740ec 100644
--- a/graphene/types/mutation.py
+++ b/graphene/types/mutation.py
@@ -18,7 +18,7 @@ class MutationMeta(ObjectTypeMeta):
input_class = attrs.pop('Input', None)
- cls = cls._create_objecttype(cls, name, bases, attrs)
+ cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
field_args = props(input_class) if input_class 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 acee8265..3c1c7791 100644
--- a/graphene/types/objecttype.py
+++ b/graphene/types/objecttype.py
@@ -1,132 +1,45 @@
-import inspect
import six
-from ..utils.copy_fields import copy_fields
-from ..utils.get_fields import get_fields
from ..utils.is_base_type import is_base_type
-from .field import Field
from .options import Options
-
-from ..generators import generate_interface, generate_objecttype
+from .abstracttype import AbstractTypeMeta
+from .utils import get_fields_in_type, yank_fields_from_attrs, merge_fields_in_attrs
-def get_interfaces(interfaces):
- from ..utils.get_graphql_type import get_graphql_type
-
- for interface in interfaces:
- graphql_type = get_graphql_type(interface)
- yield graphql_type
-
-
-def is_objecttype(bases):
- for base in bases:
- if issubclass(base, ObjectType):
- return True
- return False
-
-
-def attrs_without_fields(attrs, fields):
- return {k: v for k, v in attrs.items() if k not in fields}
-
-
-# We inherit from InterfaceTypeMeta instead of type for being able
-# to have ObjectTypes extending Interfaces using Python syntax, like:
-# class MyObjectType(ObjectType, MyInterface)
-class ObjectTypeMeta(type):
+class ObjectTypeMeta(AbstractTypeMeta):
def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of
- # ObjectType,or Interfaces
+ # ObjectType
if not is_base_type(bases, ObjectTypeMeta):
return type.__new__(cls, name, bases, attrs)
- if not is_objecttype(bases):
- return cls._create_interface(cls, name, bases, attrs)
-
- return cls._create_objecttype(cls, name, bases, attrs)
-
- def is_object_type(cls): # noqa: N805
- return issubclass(cls, ObjectType)
-
- @staticmethod
- def _get_interface_options(meta):
- return Options(
- meta,
- name=None,
- description=None,
- graphql_type=None,
- )
-
- @staticmethod
- def _create_interface(cls, name, bases, attrs):
- options = cls._get_interface_options(attrs.pop('Meta', None))
-
- fields = get_fields(Interface, attrs, bases)
- 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)
- options.get_fields = lambda: fields
- options.graphql_type = generate_interface(cls)
- else:
- assert not fields, "Can't mount Fields in an Interface 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)
-
- return cls
-
- @staticmethod
- def _create_objecttype(cls, name, bases, attrs):
options = Options(
attrs.pop('Meta', None),
- name=None,
- description=None,
- graphql_type=None,
+ name=name,
+ description=attrs.get('__doc__'),
interfaces=(),
)
- 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))
+ attrs = merge_fields_in_attrs(bases, attrs)
+ options.fields = get_fields_in_type(ObjectType, attrs)
+ yank_fields_from_attrs(attrs, options.fields)
- if not options.graphql_type:
- fields = copy_fields(Field, fields, parent=cls)
- inherited_interfaces = tuple(b for b in bases if issubclass(b, Interface))
- options.get_fields = lambda: fields
- options.interfaces = interfaces + inherited_interfaces
- options.get_interfaces = tuple(get_interfaces(options.interfaces))
- options.graphql_type = generate_objecttype(cls)
- for i in options.interfaces:
- if inspect.isclass(i) and issubclass(i, Interface):
- i.implements(cls)
- else:
- assert not fields, "Can't mount Fields in an ObjectType with a defined graphql_type"
- assert not interfaces, "Can't have extra interfaces with a defined graphql_type"
- fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
+ return type.__new__(cls, name, bases, dict(attrs, _meta=options))
- options.get_fields = lambda: fields
-
- for name, field in fields.items():
- setattr(cls, field.attname or name, field)
-
- return cls
+ def __str__(cls):
+ return cls._meta.name
class ObjectType(six.with_metaclass(ObjectTypeMeta)):
+ is_type_of = None
+
def __init__(self, *args, **kwargs):
# GraphQL ObjectType acting as container
args_len = len(args)
- fields = self._meta.get_fields().items()
- for name, f in fields:
- setattr(self, getattr(f, 'attname', name), None)
-
+ fields = self._meta.fields.items()
if args_len > len(fields):
# Daft, but matches old exception sans the err msg.
raise IndexError("Number of args exceeds number of fields")
@@ -134,19 +47,16 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
if not kwargs:
for val, (name, field) in zip(args, fields_iter):
- attname = getattr(field, 'attname', name)
- setattr(self, attname, val)
+ setattr(self, name, val)
else:
for val, (name, field) in zip(args, fields_iter):
- attname = getattr(field, 'attname', name)
- setattr(self, attname, val)
- kwargs.pop(attname, None)
+ setattr(self, name, val)
+ kwargs.pop(name, None)
for name, field in fields_iter:
try:
- attname = getattr(field, 'attname', name)
- val = kwargs.pop(attname)
- setattr(self, attname, val)
+ val = kwargs.pop(name)
+ setattr(self, name, val)
except KeyError:
pass
@@ -159,28 +69,8 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
pass
if kwargs:
raise TypeError(
- "'%s' is an invalid keyword argument for this function" %
- list(kwargs)[0])
-
- @classmethod
- def is_type_of(cls, interface, context, info):
- from ..utils.get_graphql_type import get_graphql_type
- try:
- graphql_type = get_graphql_type(type(interface))
- return graphql_type.name == cls._meta.graphql_type.name
- except:
- return False
-
-
-class Interface(six.with_metaclass(ObjectTypeMeta)):
- resolve_type = None
-
- def __init__(self, *args, **kwargs):
- from .objecttype import ObjectType
- if not isinstance(self, ObjectType):
- raise Exception("An interface cannot be intitialized")
- super(Interface, self).__init__(*args, **kwargs)
-
- @classmethod
- def implements(cls, objecttype):
- pass
+ "'{}' is an invalid keyword argument for {}".format(
+ list(kwargs)[0],
+ self.__class__.__name__
+ )
+ )
diff --git a/graphene/types/options.py b/graphene/types/options.py
index 0b810b5e..89c1eb5a 100644
--- a/graphene/types/options.py
+++ b/graphene/types/options.py
@@ -1,3 +1,4 @@
+import inspect
from ..utils.props import props
@@ -8,9 +9,11 @@ class Options(object):
'''
def __init__(self, meta=None, **defaults):
- self.add_attrs_from_meta(meta, defaults)
+ if meta:
+ assert inspect.isclass(meta), (
+ 'Meta have to be a class, received "{}".'.format(repr(meta))
+ )
- def add_attrs_from_meta(self, meta, defaults):
meta_attrs = props(meta) if meta else {}
for attr_name, value in defaults.items():
if attr_name in meta_attrs:
@@ -27,3 +30,6 @@ class Options(object):
','.join(meta_attrs.keys())
)
)
+
+ def __repr__(self):
+ return ''.format(props(self))
diff --git a/graphene/types/scalars.py b/graphene/types/scalars.py
index d6966e19..838fbd2e 100644
--- a/graphene/types/scalars.py
+++ b/graphene/types/scalars.py
@@ -1,9 +1,7 @@
import six
-from graphql import (GraphQLBoolean, GraphQLFloat, GraphQLID, GraphQLInt,
- GraphQLString)
+from graphql.language.ast import BooleanValue, FloatValue, IntValue, StringValue
-from ..generators import generate_scalar
from ..utils.is_base_type import is_base_type
from .options import Options
from .unmountedtype import UnmountedType
@@ -21,34 +19,137 @@ class ScalarTypeMeta(type):
options = Options(
attrs.pop('Meta', None),
- name=None,
- description=None,
- graphql_type=None
+ name=name,
+ description=attrs.get('__doc__'),
)
- cls = super_new(cls, name, bases, dict(attrs, _meta=options))
+ return super_new(cls, name, bases, dict(attrs, _meta=options))
- if not options.graphql_type:
- options.graphql_type = generate_scalar(cls)
-
- return cls
+ def __str__(cls):
+ return cls._meta.name
class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
- pass
+ serialize = None
+ parse_value = None
+ parse_literal = None
+
+ @classmethod
+ def get_type(cls):
+ return cls
+
+# As per the GraphQL Spec, Integers are only treated as valid when a valid
+# 32-bit signed integer, providing the broadest support across platforms.
+#
+# n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
+# they are internally represented as IEEE 754 doubles.
+MAX_INT = 2147483647
+MIN_INT = -2147483648
-def construct_scalar_class(graphql_type):
- # This is equivalent to
- # class String(Scalar):
- # class Meta:
- # graphql_type = graphql_type
- meta_class = type('Meta', (object,), {'graphql_type': graphql_type})
- return type(graphql_type.name, (Scalar, ), {'Meta': meta_class})
+class Int(Scalar):
+ '''
+ The `Int` scalar type represents non-fractional signed whole numeric
+ values. Int can represent values between -(2^53 - 1) and 2^53 - 1 since
+ represented in JSON as double-precision floating point numbers specified
+ by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
+ '''
+
+ @staticmethod
+ def coerce_int(value):
+ try:
+ num = int(value)
+ except ValueError:
+ try:
+ num = int(float(value))
+ except ValueError:
+ return None
+ if MIN_INT <= num <= MAX_INT:
+ return num
+
+ serialize = coerce_int
+ parse_value = coerce_int
+
+ @staticmethod
+ def parse_literal(ast):
+ if isinstance(ast, IntValue):
+ num = int(ast.value)
+ if MIN_INT <= num <= MAX_INT:
+ return num
-String = construct_scalar_class(GraphQLString)
-Int = construct_scalar_class(GraphQLInt)
-Float = construct_scalar_class(GraphQLFloat)
-Boolean = construct_scalar_class(GraphQLBoolean)
-ID = construct_scalar_class(GraphQLID)
+class Float(Scalar):
+ '''
+ The `Float` scalar type represents signed double-precision fractional
+ values as specified by
+ [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
+ '''
+
+ @staticmethod
+ def coerce_float(value):
+ try:
+ return float(value)
+ except ValueError:
+ return None
+
+ serialize = coerce_float
+ parse_value = coerce_float
+
+ @staticmethod
+ def parse_literal(ast):
+ if isinstance(ast, (FloatValue, IntValue)):
+ return float(ast.value)
+
+
+class String(Scalar):
+ '''
+ The `String` scalar type represents textual data, represented as UTF-8
+ character sequences. The String type is most often used by GraphQL to
+ represent free-form human-readable text.
+ '''
+
+ @staticmethod
+ def coerce_string(value):
+ if isinstance(value, bool):
+ return u'true' if value else u'false'
+ return six.text_type(value)
+
+ serialize = coerce_string
+ parse_value = coerce_string
+
+ @staticmethod
+ def parse_literal(ast):
+ if isinstance(ast, StringValue):
+ return ast.value
+
+
+class Boolean(Scalar):
+ '''
+ The `Boolean` scalar type represents `true` or `false`.
+ '''
+
+ serialize = bool
+ parse_value = bool
+
+ @staticmethod
+ def parse_literal(ast):
+ if isinstance(ast, BooleanValue):
+ return ast.value
+
+
+class ID(Scalar):
+ '''
+ The `ID` scalar type represents a unique identifier, often used to
+ refetch an object or as key for a cache. The ID type appears in a JSON
+ response as a String; however, it is not intended to be human-readable.
+ When expected as an input type, any string (such as `"4"`) or integer
+ (such as `4`) input value will be accepted as an ID.
+ '''
+
+ serialize = str
+ parse_value = str
+
+ @staticmethod
+ def parse_literal(ast):
+ if isinstance(ast, (StringValue, IntValue)):
+ return ast.value
diff --git a/graphene/types/schema.py b/graphene/types/schema.py
index 24b68702..624ce9e1 100644
--- a/graphene/types/schema.py
+++ b/graphene/types/schema.py
@@ -1,8 +1,14 @@
-from graphql import GraphQLSchema, graphql
+import inspect
+
+from graphql import GraphQLSchema, graphql, is_type
from graphql.utils.introspection_query import introspection_query
from graphql.utils.schema_printer import print_schema
-from ..utils.get_graphql_type import get_graphql_type
+
+from .objecttype import ObjectType
+from .structures import List, NonNull
+from .scalars import Scalar, String
+# from ..utils.get_graphql_type import get_graphql_type
# from graphql.type.schema import assert_object_implements_interface
@@ -10,32 +16,60 @@ from ..utils.get_graphql_type import get_graphql_type
# from collections import defaultdict
+from graphql.type.directives import (GraphQLDirective, GraphQLIncludeDirective,
+ GraphQLSkipDirective)
+from graphql.type.introspection import IntrospectionSchema
+from .typemap import TypeMap, is_graphene_type
+
+
class Schema(GraphQLSchema):
def __init__(self, query=None, mutation=None, subscription=None, directives=None, types=None, executor=None):
- if query:
- query = get_graphql_type(query)
- if mutation:
- mutation = get_graphql_type(mutation)
- if subscription:
- subscription = get_graphql_type(subscription)
+ self._query = query
+ self._mutation = mutation
+ self._subscription = subscription
self.types = types
self._executor = executor
- super(Schema, self).__init__(
- query=query,
- mutation=mutation,
- subscription=subscription,
- directives=directives,
- types=self.types
+ if directives is None:
+ directives = [
+ GraphQLIncludeDirective,
+ GraphQLSkipDirective
+ ]
+
+ assert all(isinstance(d, GraphQLDirective) for d in directives), \
+ 'Schema directives must be List[GraphQLDirective] if provided but got: {}.'.format(
+ directives
)
- @property
- def types(self):
- return map(get_graphql_type, self._types or [])
+ self._directives = directives
+ initial_types = [
+ query,
+ mutation,
+ subscription,
+ IntrospectionSchema
+ ]
+ if types:
+ initial_types += types
+ self._type_map = TypeMap(initial_types)
- @types.setter
- def types(self, value):
- self._types = value
+ def get_query_type(self):
+ return self.get_graphql_type(self._query)
+
+ def get_mutation_type(self):
+ return self.get_graphql_type(self._mutation)
+
+ def get_subscription_type(self):
+ return self.get_graphql_type(self._subscription)
+
+ def get_graphql_type(self, _type):
+ if is_type(_type):
+ return _type
+ if is_graphene_type(_type):
+ graphql_type = self.get_type(_type._meta.name)
+ assert graphql_type, "Type {} not found in this schema.".format(_type._meta.name)
+ assert graphql_type.graphene_type == _type
+ return graphql_type
+ raise Exception("{} is not a valid GraphQL type.".format(_type))
def execute(self, request_string='', root_value=None, variable_values=None,
context_value=None, operation_name=None, executor=None):
@@ -50,7 +84,7 @@ class Schema(GraphQLSchema):
)
def register(self, object_type):
- self._types.append(object_type)
+ self.types.append(object_type)
def introspect(self):
return self.execute(introspection_query).data
@@ -58,9 +92,6 @@ class Schema(GraphQLSchema):
def __str__(self):
return print_schema(self)
- def get_type(self, _type):
- return self._type_map[_type]
-
def lazy(self, _type):
return lambda: self.get_type(_type)
diff --git a/graphene/types/structures.py b/graphene/types/structures.py
index d577098f..41fcd5dd 100644
--- a/graphene/types/structures.py
+++ b/graphene/types/structures.py
@@ -1,7 +1,3 @@
-import inspect
-
-from graphql import GraphQLList, GraphQLNonNull
-
from .unmountedtype import UnmountedType
@@ -18,21 +14,12 @@ class Structure(UnmountedType):
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):
+ def __str__(self):
+ return '[{}]'.format(self.of_type)
-class List(Structure, GraphQLList):
- pass
-
-
-class NonNull(Structure, GraphQLNonNull):
- pass
+class NonNull(Structure):
+ def __str__(self):
+ return '{}!'.format(self.of_type)
diff --git a/graphene/new_types/tests/test_abstracttype.py b/graphene/types/tests/test_abstracttype.py
similarity index 100%
rename from graphene/new_types/tests/test_abstracttype.py
rename to graphene/types/tests/test_abstracttype.py
diff --git a/graphene/types/tests/test_argument.py b/graphene/types/tests/test_argument.py
deleted file mode 100644
index 6969130f..00000000
--- a/graphene/types/tests/test_argument.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import copy
-
-import pytest
-
-from graphql import GraphQLArgument, GraphQLString
-
-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)
diff --git a/graphene/new_types/tests/test_definition.py b/graphene/types/tests/test_definition.py
similarity index 100%
rename from graphene/new_types/tests/test_definition.py
rename to graphene/types/tests/test_definition.py
diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py
index 4abd185e..c16cbc99 100644
--- a/graphene/types/tests/test_enum.py
+++ b/graphene/types/tests/test_enum.py
@@ -1,12 +1,9 @@
-from graphql.type import GraphQLEnumType
-
-from ..argument import Argument
from ..enum import Enum, PyEnum
-from ..field import Field
def test_enum_construction():
class RGB(Enum):
+ '''Description'''
RED = 1
GREEN = 2
BLUE = 3
@@ -15,8 +12,10 @@ def test_enum_construction():
def description(self):
return "Description {}".format(self.name)
- assert isinstance(RGB._meta.graphql_type, GraphQLEnumType)
- values = RGB._meta.graphql_type.get_values()
+ assert RGB._meta.name == 'RGB'
+ assert RGB._meta.description == 'Description'
+
+ values = RGB._meta.enum.__members__.values()
assert sorted([v.name for v in values]) == [
'BLUE',
'GREEN',
@@ -27,37 +26,40 @@ def test_enum_construction():
'Description GREEN',
'Description RED'
]
- assert isinstance(RGB(name='field_name').as_field(), Field)
- assert isinstance(RGB(name='field_name').as_argument(), Argument)
+
+
+def test_enum_construction_meta():
+ class RGB(Enum):
+ class Meta:
+ name = 'RGBEnum'
+ description = 'Description'
+ RED = 1
+ GREEN = 2
+ BLUE = 3
+
+ assert RGB._meta.name == 'RGBEnum'
+ assert RGB._meta.description == 'Description'
def test_enum_instance_construction():
RGB = Enum('RGB', 'RED,GREEN,BLUE')
- assert isinstance(RGB._meta.graphql_type, GraphQLEnumType)
- values = RGB._meta.graphql_type.get_values()
+ values = RGB._meta.enum.__members__.values()
assert sorted([v.name for v in values]) == [
'BLUE',
'GREEN',
'RED'
]
- assert isinstance(RGB(name='field_name').as_field(), Field)
- assert isinstance(RGB(name='field_name').as_argument(), Argument)
def test_enum_from_builtin_enum():
PyRGB = PyEnum('RGB', 'RED,GREEN,BLUE')
RGB = Enum.from_enum(PyRGB)
- assert isinstance(RGB._meta.graphql_type, GraphQLEnumType)
- values = RGB._meta.graphql_type.get_values()
- assert sorted([v.name for v in values]) == [
- 'BLUE',
- 'GREEN',
- 'RED'
- ]
- assert isinstance(RGB(name='field_name').as_field(), Field)
- assert isinstance(RGB(name='field_name').as_argument(), Argument)
+ assert RGB._meta.enum == PyRGB
+ assert RGB.RED
+ assert RGB.GREEN
+ assert RGB.BLUE
def test_enum_value_from_class():
@@ -67,3 +69,5 @@ def test_enum_value_from_class():
BLUE = 3
assert RGB.RED.value == 1
+ assert RGB.GREEN.value == 2
+ assert RGB.BLUE.value == 3
diff --git a/graphene/types/tests/test_field.py b/graphene/types/tests/test_field.py
index 521f9b7d..31fcf037 100644
--- a/graphene/types/tests/test_field.py
+++ b/graphene/types/tests/test_field.py
@@ -1,67 +1,77 @@
-import copy
-
import pytest
-from graphql import GraphQLField, GraphQLInt, GraphQLNonNull, GraphQLString
-
-from ..argument import Argument
from ..field import Field
-from ..scalars import Int, String
+from ..structures import NonNull
+from ..argument import Argument
-def test_field():
- field = Field(GraphQLString, name="name", description="description")
- assert isinstance(field, GraphQLField)
- assert field.name == "name"
- assert field.description == "description"
- assert field.type == GraphQLString
+class MyInstance(object):
+ value = 'value'
+ value_func = staticmethod(lambda: 'value_func')
+
+
+def test_field_basic():
+ MyType = object()
+ args = {'my arg': Argument(True)}
+ resolver = lambda: None
+ deprecation_reason = 'Deprecated now'
+ description = 'My Field'
+ field = Field(
+ MyType,
+ name='name',
+ args=args,
+ resolver=resolver,
+ description=description,
+ deprecation_reason=deprecation_reason
+ )
+ assert field.name == 'name'
+ assert field.args == args
+ assert field.resolver == resolver
+ assert field.deprecation_reason == deprecation_reason
+ assert field.description == description
def test_field_required():
- field = Field(GraphQLString, required=True)
- assert isinstance(field, GraphQLField)
- assert isinstance(field.type, GraphQLNonNull)
- assert field.type.of_type == GraphQLString
+ MyType = object()
+ field = Field(MyType, required=True)
+ assert isinstance(field.type, NonNull)
+ assert field.type.of_type == MyType
-def test_field_wrong_name():
- with pytest.raises(AssertionError) as excinfo:
- Field(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_field_source():
+ MyType = object()
+ field = Field(MyType, source='value')
+ assert field.resolver(MyInstance, {}, None, None) == MyInstance.value
-def test_not_source_and_resolver():
- with pytest.raises(AssertionError) as excinfo:
- Field(GraphQLString, source="a", resolver=lambda *_: None)
-
- assert "You cannot have a source and a resolver at the same time" == str(excinfo.value)
+def test_field_with_lazy_type():
+ MyType = object()
+ field = Field(lambda: MyType)
+ assert field.type == MyType
-def test_copy_field_works():
- field = Field(GraphQLString)
- copy.copy(field)
+def test_field_not_source_and_resolver():
+ MyType = object()
+ with pytest.raises(Exception) as exc_info:
+ Field(MyType, source='value', resolver=lambda: None)
+ assert str(exc_info.value) == 'A Field cannot have a source and a resolver in at the same time.'
-def test_field_callable_type():
- field = Field(lambda: GraphQLString)
- assert field.type == GraphQLString
+def test_field_source_func():
+ MyType = object()
+ field = Field(MyType, source='value_func')
+ assert field.resolver(MyInstance(), {}, None, None) == MyInstance.value_func()
-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
+def test_field_source_argument_as_kw():
+ MyType = object()
+ field = Field(MyType, b=NonNull(True), c=Argument(None), a=NonNull(False))
+ assert field.args.keys() == ['b', 'c', 'a']
+ assert isinstance(field.args['b'], Argument)
+ assert isinstance(field.args['b'].type, NonNull)
+ assert field.args['b'].type.of_type is True
+ assert isinstance(field.args['c'], Argument)
+ assert field.args['c'].type is None
+ assert isinstance(field.args['a'], Argument)
+ assert isinstance(field.args['a'].type, NonNull)
+ assert field.args['a'].type.of_type is False
diff --git a/graphene/types/tests/test_inputobjecttype.py b/graphene/types/tests/test_inputobjecttype.py
index 8036b96a..52796749 100644
--- a/graphene/types/tests/test_inputobjecttype.py
+++ b/graphene/types/tests/test_inputobjecttype.py
@@ -1,57 +1,83 @@
+import pytest
-from graphql import GraphQLInputObjectType, GraphQLString
-from graphql.type.definition import GraphQLInputFieldDefinition
-
-from ..field import InputField
+from ..field import Field
+from ..inputfield import InputField
from ..inputobjecttype import InputObjectType
-from ..scalars import String
+from ..unmountedtype import UnmountedType
+from ..abstracttype import AbstractType
+
+
+class MyType(object):
+ pass
+
+
+class MyScalar(UnmountedType):
+ def get_type(self):
+ return MyType
def test_generate_inputobjecttype():
- class MyObjectType(InputObjectType):
+ class MyInputObjectType(InputObjectType):
'''Documentation'''
- graphql_type = MyObjectType._meta.graphql_type
- assert isinstance(graphql_type, GraphQLInputObjectType)
- assert graphql_type.name == "MyObjectType"
- assert graphql_type.description == "Documentation"
+ assert MyInputObjectType._meta.name == "MyInputObjectType"
+ assert MyInputObjectType._meta.description == "Documentation"
+ assert MyInputObjectType._meta.fields == {}
def test_generate_inputobjecttype_with_meta():
- class MyObjectType(InputObjectType):
+ class MyInputObjectType(InputObjectType):
class Meta:
- name = 'MyOtherObjectType'
+ name = 'MyOtherInputObjectType'
description = 'Documentation'
- graphql_type = MyObjectType._meta.graphql_type
- assert isinstance(graphql_type, GraphQLInputObjectType)
- assert graphql_type.name == "MyOtherObjectType"
- assert graphql_type.description == "Documentation"
+ assert MyInputObjectType._meta.name == "MyOtherInputObjectType"
+ assert MyInputObjectType._meta.description == "Documentation"
-def test_empty_inputobjecttype_has_meta():
- class MyObjectType(InputObjectType):
- pass
+def test_generate_inputobjecttype_with_fields():
+ class MyInputObjectType(InputObjectType):
+ field = Field(MyType)
- assert MyObjectType._meta
+ assert 'field' in MyInputObjectType._meta.fields
-def test_generate_objecttype_with_fields():
- class MyObjectType(InputObjectType):
- field = InputField(GraphQLString)
+def test_ordered_fields_in_inputobjecttype():
+ class MyInputObjectType(InputObjectType):
+ b = InputField(MyType)
+ a = InputField(MyType)
+ field = MyScalar()
+ asa = InputField(MyType)
- graphql_type = MyObjectType._meta.graphql_type
- fields = graphql_type.get_fields()
- assert 'field' in fields
- assert isinstance(fields['field'], GraphQLInputFieldDefinition)
+ assert list(MyInputObjectType._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-def test_generate_objecttype_with_graphene_fields():
- class MyObjectType(InputObjectType):
- field = String()
+def test_generate_inputobjecttype_unmountedtype():
+ class MyInputObjectType(InputObjectType):
+ field = MyScalar(MyType)
- graphql_type = MyObjectType._meta.graphql_type
- fields = graphql_type.get_fields()
- assert 'field' in fields
- assert isinstance(fields['field'], GraphQLInputFieldDefinition)
+ assert 'field' in MyInputObjectType._meta.fields
+ assert isinstance(MyInputObjectType._meta.fields['field'], InputField)
+
+
+def test_generate_inputobjecttype_inherit_abstracttype():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar(MyType)
+
+ class MyInputObjectType(InputObjectType, MyAbstractType):
+ field2 = MyScalar(MyType)
+
+ assert MyInputObjectType._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [InputField, InputField]
+
+
+def test_generate_inputobjecttype_inherit_abstracttype_reversed():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar(MyType)
+
+ class MyInputObjectType(MyAbstractType, InputObjectType):
+ field2 = MyScalar(MyType)
+
+ assert MyInputObjectType._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [InputField, InputField]
diff --git a/graphene/types/tests/test_interface.py b/graphene/types/tests/test_interface.py
index 09136e04..97804c5c 100644
--- a/graphene/types/tests/test_interface.py
+++ b/graphene/types/tests/test_interface.py
@@ -1,19 +1,27 @@
import pytest
-from graphql import GraphQLField, GraphQLInterfaceType, GraphQLString
-
from ..field import Field
from ..interface import Interface
+from ..unmountedtype import UnmountedType
+from ..abstracttype import AbstractType
+
+
+class MyType(object):
+ pass
+
+
+class MyScalar(UnmountedType):
+ def get_type(self):
+ return MyType
def test_generate_interface():
class MyInterface(Interface):
'''Documentation'''
- graphql_type = MyInterface._meta.graphql_type
- assert isinstance(graphql_type, GraphQLInterfaceType)
- assert graphql_type.name == "MyInterface"
- assert graphql_type.description == "Documentation"
+ assert MyInterface._meta.name == "MyInterface"
+ assert MyInterface._meta.description == "Documentation"
+ assert MyInterface._meta.fields == {}
def test_generate_interface_with_meta():
@@ -23,62 +31,52 @@ def test_generate_interface_with_meta():
name = 'MyOtherInterface'
description = 'Documentation'
- graphql_type = MyInterface._meta.graphql_type
- assert isinstance(graphql_type, GraphQLInterfaceType)
- assert graphql_type.name == "MyOtherInterface"
- assert graphql_type.description == "Documentation"
-
-
-def test_empty_interface_has_meta():
- class MyInterface(Interface):
- pass
-
- assert MyInterface._meta
+ assert MyInterface._meta.name == "MyOtherInterface"
+ assert MyInterface._meta.description == "Documentation"
def test_generate_interface_with_fields():
class MyInterface(Interface):
- field = Field(GraphQLString)
+ field = Field(MyType)
- graphql_type = MyInterface._meta.graphql_type
- fields = graphql_type.get_fields()
- assert 'field' in fields
+ assert 'field' in MyInterface._meta.fields
-def test_interface_inheritance():
- class MyInheritedInterface(Interface):
- inherited = Field(GraphQLString)
-
- class MyInterface(MyInheritedInterface):
- field = Field(GraphQLString)
-
- graphql_type = MyInterface._meta.graphql_type
- fields = graphql_type.get_fields()
- assert 'field' in fields
- assert 'inherited' in fields
- assert MyInterface.field > MyInheritedInterface.inherited
-
-
-def test_interface_instance():
+def test_ordered_fields_in_interface():
class MyInterface(Interface):
- inherited = Field(GraphQLString)
+ b = Field(MyType)
+ a = Field(MyType)
+ field = MyScalar()
+ asa = Field(MyType)
- with pytest.raises(Exception) as excinfo:
- MyInterface()
-
- assert "An interface cannot be intitialized" in str(excinfo.value)
+ assert list(MyInterface._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-def test_interface_add_fields_in_reused_graphql_type():
- MyGraphQLType = GraphQLInterfaceType('MyGraphQLType', fields={
- 'field': GraphQLField(GraphQLString)
- })
+def test_generate_interface_unmountedtype():
+ class MyInterface(Interface):
+ field = MyScalar()
- with pytest.raises(AssertionError) as excinfo:
- class GrapheneInterface(Interface):
- field = Field(GraphQLString)
+ assert 'field' in MyInterface._meta.fields
+ assert isinstance(MyInterface._meta.fields['field'], Field)
- class Meta:
- graphql_type = MyGraphQLType
- assert """Can't mount Fields in an Interface with a defined graphql_type""" == str(excinfo.value)
+def test_generate_interface_inherit_abstracttype():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar()
+
+ class MyInterface(Interface, MyAbstractType):
+ field2 = MyScalar()
+
+ assert MyInterface._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
+
+
+def test_generate_interface_inherit_abstracttype_reversed():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar()
+
+ class MyInterface(MyAbstractType, Interface):
+ field2 = MyScalar()
+
+ assert MyInterface._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
diff --git a/graphene/types/tests/test_mutation.py b/graphene/types/tests/test_mutation.py
index 49855746..2b4a8859 100644
--- a/graphene/types/tests/test_mutation.py
+++ b/graphene/types/tests/test_mutation.py
@@ -1,7 +1,5 @@
import pytest
-from graphql import GraphQLObjectType, GraphQLString
-
from ..field import Field
from ..mutation import Mutation
from ..objecttype import ObjectType
@@ -16,31 +14,29 @@ def test_generate_mutation_no_args():
pass
assert issubclass(MyMutation, ObjectType)
- graphql_type = MyMutation._meta.graphql_type
- assert isinstance(graphql_type, GraphQLObjectType)
- assert graphql_type.name == "MyMutation"
- assert graphql_type.description == "Documentation"
+ assert MyMutation._meta.name == "MyMutation"
+ assert MyMutation._meta.description == "Documentation"
+ assert MyMutation.Field().resolver == MyMutation.mutate
-def test_generate_mutation_with_args():
- class MyMutation(Mutation):
- '''Documentation'''
- class Input:
- s = String()
+# def test_generate_mutation_with_args():
+# class MyMutation(Mutation):
+# '''Documentation'''
+# class Input:
+# s = String()
- @classmethod
- def mutate(cls, *args, **kwargs):
- pass
+# @classmethod
+# def mutate(cls, *args, **kwargs):
+# pass
- graphql_type = MyMutation._meta.graphql_type
- field = MyMutation.Field()
- assert isinstance(graphql_type, GraphQLObjectType)
- assert graphql_type.name == "MyMutation"
- assert graphql_type.description == "Documentation"
- assert isinstance(field, Field)
- assert field.type == MyMutation._meta.graphql_type
- assert 's' in field.args
- assert field.args['s'].type == GraphQLString
+# graphql_type = MyMutation._meta.graphql_type
+# field = MyMutation.Field()
+# assert graphql_type.name == "MyMutation"
+# assert graphql_type.description == "Documentation"
+# assert isinstance(field, Field)
+# assert field.type == MyMutation._meta.graphql_type
+# assert 's' in field.args
+# assert field.args['s'].type == String
def test_generate_mutation_with_meta():
@@ -54,20 +50,9 @@ def test_generate_mutation_with_meta():
def mutate(cls, *args, **kwargs):
pass
- graphql_type = MyMutation._meta.graphql_type
- assert isinstance(graphql_type, GraphQLObjectType)
- assert graphql_type.name == "MyOtherMutation"
- assert graphql_type.description == "Documentation"
-
-
-def test_empty_mutation_has_meta():
- class MyMutation(Mutation):
-
- @classmethod
- def mutate(cls, *args, **kwargs):
- pass
-
- assert MyMutation._meta
+ assert MyMutation._meta.name == "MyOtherMutation"
+ assert MyMutation._meta.description == "Documentation"
+ assert MyMutation.Field().resolver == MyMutation.mutate
def test_mutation_raises_exception_if_no_mutate():
diff --git a/graphene/types/tests/test_objecttype.py b/graphene/types/tests/test_objecttype.py
index 3a2f124e..9b8b3913 100644
--- a/graphene/types/tests/test_objecttype.py
+++ b/graphene/types/tests/test_objecttype.py
@@ -1,26 +1,33 @@
import pytest
-from graphql import (GraphQLField, GraphQLInterfaceType, GraphQLObjectType,
- GraphQLString)
-
from ..field import Field
-from ..interface import Interface
from ..objecttype import ObjectType
+from ..unmountedtype import UnmountedType
+from ..abstracttype import AbstractType
+
+
+class MyType(object):
+ pass
class Container(ObjectType):
- field1 = Field(GraphQLString, name='field1')
- field2 = Field(GraphQLString, name='field2')
+ field1 = Field(MyType)
+ field2 = Field(MyType)
+
+
+class MyScalar(UnmountedType):
+ def get_type(self):
+ return MyType
def test_generate_objecttype():
class MyObjectType(ObjectType):
'''Documentation'''
- graphql_type = MyObjectType._meta.graphql_type
- assert isinstance(graphql_type, GraphQLObjectType)
- assert graphql_type.name == "MyObjectType"
- assert graphql_type.description == "Documentation"
+ assert MyObjectType._meta.name == "MyObjectType"
+ assert MyObjectType._meta.description == "Documentation"
+ assert MyObjectType._meta.interfaces == tuple()
+ assert MyObjectType._meta.fields == {}
def test_generate_objecttype_with_meta():
@@ -29,66 +36,62 @@ def test_generate_objecttype_with_meta():
class Meta:
name = 'MyOtherObjectType'
description = 'Documentation'
+ interfaces = (MyType, )
- graphql_type = MyObjectType._meta.graphql_type
- assert isinstance(graphql_type, GraphQLObjectType)
- assert graphql_type.name == "MyOtherObjectType"
- assert graphql_type.description == "Documentation"
-
-
-def test_empty_objecttype_has_meta():
- class MyObjectType(ObjectType):
- pass
-
- assert MyObjectType._meta
+ assert MyObjectType._meta.name == "MyOtherObjectType"
+ assert MyObjectType._meta.description == "Documentation"
+ assert MyObjectType._meta.interfaces == (MyType, )
def test_generate_objecttype_with_fields():
class MyObjectType(ObjectType):
- field = Field(GraphQLString)
+ field = Field(MyType)
- graphql_type = MyObjectType._meta.graphql_type
- fields = graphql_type.get_fields()
- assert 'field' in fields
+ assert 'field' in MyObjectType._meta.fields
def test_ordered_fields_in_objecttype():
class MyObjectType(ObjectType):
- b = Field(GraphQLString)
- a = Field(GraphQLString)
- field = Field(GraphQLString)
- asa = Field(GraphQLString)
+ b = Field(MyType)
+ a = Field(MyType)
+ field = MyScalar()
+ asa = Field(MyType)
- graphql_type = MyObjectType._meta.graphql_type
- fields = graphql_type.get_fields()
- assert list(fields.keys()) == ['b', 'a', 'field', 'asa']
+ assert list(MyObjectType._meta.fields.keys()) == ['b', 'a', 'field', 'asa']
-def test_objecttype_inheritance():
- class MyInheritedObjectType(ObjectType):
- inherited = Field(GraphQLString)
+def test_generate_objecttype_inherit_abstracttype():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar()
- class MyObjectType(MyInheritedObjectType):
- field1 = Field(GraphQLString)
- field2 = Field(GraphQLString)
+ class MyObjectType(ObjectType, MyAbstractType):
+ field2 = MyScalar()
- graphql_type = MyObjectType._meta.graphql_type
- fields = graphql_type.get_fields()
- assert list(fields.keys()) == ['inherited', 'field1', 'field2']
+ assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
-def test_objecttype_as_container_get_fields():
+def test_generate_objecttype_inherit_abstracttype_reversed():
+ class MyAbstractType(AbstractType):
+ field1 = MyScalar()
- class Container(ObjectType):
- field1 = Field(GraphQLString)
- field2 = Field(GraphQLString)
+ class MyObjectType(MyAbstractType, ObjectType):
+ field2 = MyScalar()
- assert list(Container._meta.graphql_type.get_fields().keys()) == ['field1', 'field2']
+ assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
+ assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
+
+
+def test_generate_objecttype_unmountedtype():
+ class MyObjectType(ObjectType):
+ field = MyScalar()
+
+ assert 'field' in MyObjectType._meta.fields
+ assert isinstance(MyObjectType._meta.fields['field'], Field)
def test_parent_container_get_fields():
- fields = Container._meta.graphql_type.get_fields()
- assert list(fields.keys()) == ['field1', 'field2']
+ assert list(Container._meta.fields.keys()) == ['field1', 'field2']
def test_objecttype_as_container_only_args():
@@ -125,130 +128,4 @@ def test_objecttype_as_container_invalid_kwargs():
with pytest.raises(TypeError) as excinfo:
Container(unexisting_field="3")
- assert "'unexisting_field' is an invalid keyword argument for this function" == str(excinfo.value)
-
-
-def test_objecttype_reuse_graphql_type():
- MyGraphQLType = GraphQLObjectType('MyGraphQLType', fields={
- 'field': GraphQLField(GraphQLString)
- })
-
- class GrapheneObjectType(ObjectType):
-
- class Meta:
- graphql_type = MyGraphQLType
-
- graphql_type = GrapheneObjectType._meta.graphql_type
- assert graphql_type == MyGraphQLType
- instance = GrapheneObjectType(field="A")
- assert instance.field == "A"
-
-
-def test_objecttype_add_fields_in_reused_graphql_type():
- MyGraphQLType = GraphQLObjectType('MyGraphQLType', fields={
- 'field': GraphQLField(GraphQLString)
- })
-
- with pytest.raises(AssertionError) as excinfo:
- class GrapheneObjectType(ObjectType):
- field = Field(GraphQLString)
-
- class Meta:
- graphql_type = MyGraphQLType
-
- assert """Can't mount Fields in an ObjectType with a defined graphql_type""" == str(excinfo.value)
-
-
-def test_objecttype_graphql_interface():
- MyInterface = GraphQLInterfaceType('MyInterface', fields={
- 'field': GraphQLField(GraphQLString)
- })
-
- class GrapheneObjectType(ObjectType):
-
- class Meta:
- interfaces = [MyInterface]
-
- graphql_type = GrapheneObjectType._meta.graphql_type
- assert graphql_type.get_interfaces() == (MyInterface, )
- # assert graphql_type.is_type_of(MyInterface, None, None)
- fields = graphql_type.get_fields()
- assert 'field' in fields
-
-
-def test_objecttype_graphene_interface():
- class GrapheneInterface(Interface):
- name = Field(GraphQLString)
- extended = Field(GraphQLString)
-
- class GrapheneObjectType(ObjectType):
-
- class Meta:
- interfaces = [GrapheneInterface]
-
- field = Field(GraphQLString)
-
- graphql_type = GrapheneObjectType._meta.graphql_type
- assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
- assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
- fields = graphql_type.get_fields().keys() == ['name', 'extended', 'field']
-
-
-def test_objecttype_graphene_inherit_interface():
- class GrapheneInterface(Interface):
- name = Field(GraphQLString)
- extended = Field(GraphQLString)
-
- class GrapheneObjectType(ObjectType, GrapheneInterface):
- field = Field(GraphQLString)
-
- graphql_type = GrapheneObjectType._meta.graphql_type
- assert graphql_type.get_interfaces() == (GrapheneInterface._meta.graphql_type, )
- assert graphql_type.is_type_of(GrapheneObjectType(), None, None)
- fields = graphql_type.get_fields()
- fields = graphql_type.get_fields().keys() == ['name', 'extended', 'field']
- assert issubclass(GrapheneObjectType, GrapheneInterface)
-
-
-# def test_objecttype_graphene_interface_extended():
-# class GrapheneInterface(Interface):
-# field = Field(GraphQLString)
-
-# class GrapheneObjectType(ObjectType):
-# class Meta:
-# interfaces = [GrapheneInterface]
-
-# schema = Schema(query=GrapheneObjectType)
-# assert str(schema) == """
-# schema {
-# query: GrapheneObjectType
-# }
-
-# interface GrapheneInterface {
-# field: String
-# }
-
-# type GrapheneObjectType implements GrapheneInterface {
-# field: String
-# }
-# """.lstrip()
-# GrapheneInterface._meta.graphql_type.add_field(Field(String, name='dynamic'))
-# # GrapheneObjectType._meta.graphql_type._field_map = None
-# assert GrapheneInterface._meta.graphql_type.get_fields().keys() == ['field', 'dynamic']
-# assert GrapheneObjectType._meta.graphql_type.get_fields().keys() == ['field', 'dynamic']
-# schema.rebuild()
-# assert str(schema) == """
-# schema {
-# query: GrapheneObjectType
-# }
-
-# interface GrapheneInterface {
-# field: String
-# dynamic: String
-# }
-
-# type GrapheneObjectType implements GrapheneInterface {
-# field: String
-# dynamic: String
-# }
-# """.lstrip()
+ assert "'unexisting_field' is an invalid keyword argument for Container" == str(excinfo.value)
diff --git a/graphene/types/tests/test_options.py b/graphene/types/tests/test_options.py
deleted file mode 100644
index 59a708cc..00000000
--- a/graphene/types/tests/test_options.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import pytest
-
-from ..options import Options
-
-
-def test_options_defaults():
- class Meta:
- valid_second = True
-
- options = Options(Meta, valid_second=False, valid_first=False)
-
- assert not options.valid_first
- assert options.valid_second
-
-
-def test_options_invalid_attrs():
- class Meta:
- invalid = True
-
- with pytest.raises(TypeError) as excinfo:
- Options(Meta, valid=True)
-
- assert "Invalid attributes: invalid" == str(excinfo.value)
diff --git a/graphene/new_types/tests/test_query.py b/graphene/types/tests/test_query.py
similarity index 100%
rename from graphene/new_types/tests/test_query.py
rename to graphene/types/tests/test_query.py
diff --git a/graphene/types/tests/test_scalars.py b/graphene/types/tests/test_scalars.py
deleted file mode 100644
index 8a2b7b12..00000000
--- a/graphene/types/tests/test_scalars.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import datetime
-
-import pytest
-
-from graphene.utils.get_graphql_type import get_graphql_type
-from graphql import graphql
-from graphql.language import ast
-from graphql.type import (GraphQLBoolean, GraphQLFieldDefinition, GraphQLFloat,
- GraphQLInt, GraphQLScalarType, GraphQLString)
-
-from ..field import Field
-from ..objecttype import ObjectType
-from ..scalars import Boolean, Float, Int, Scalar, String
-from ..schema import Schema
-
-
-class DatetimeScalar(Scalar):
-
- class Meta:
- name = 'DateTime'
-
- @staticmethod
- def serialize(dt):
- assert isinstance(dt, datetime.datetime)
- return dt.isoformat()
-
- @staticmethod
- def parse_literal(node):
- if isinstance(node, ast.StringValue):
- return datetime.datetime.strptime(node.value, "%Y-%m-%dT%H:%M:%S.%f")
-
- @staticmethod
- def parse_value(value):
- return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
-
-
-def serialize_date_time(dt):
- assert isinstance(dt, datetime.datetime)
- return dt.isoformat()
-
-
-def parse_literal(node):
- if isinstance(node, ast.StringValue):
- return datetime.datetime.strptime(node.value, "%Y-%m-%dT%H:%M:%S.%f")
-
-
-def parse_value(value):
- return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
-
-
-GraphQLDateTimeType = GraphQLScalarType(
- name='DateTime',
- serialize=serialize_date_time,
- parse_literal=parse_literal,
- parse_value=parse_value
-)
-
-
-class DatetimeScalarGraphQL(Scalar):
-
- class Meta:
- graphql_type = GraphQLDateTimeType
-
-
-scalar_classes = {
- DatetimeScalar: DatetimeScalar._meta.graphql_type,
- DatetimeScalarGraphQL: GraphQLDateTimeType,
- String: GraphQLString,
- Int: GraphQLInt,
- Float: GraphQLFloat,
- Boolean: GraphQLBoolean,
-}
-
-
-@pytest.mark.parametrize("scalar_class,expected_graphql_type", scalar_classes.items())
-def test_scalar_as_field(scalar_class, expected_graphql_type):
- field_before = Field(None)
- scalar = scalar_class()
- field = scalar.as_field()
- graphql_type = get_graphql_type(scalar_class)
- field_after = Field(None)
- assert isinstance(field, Field)
- assert field.type == graphql_type
- assert graphql_type == expected_graphql_type
- assert field_before < field < field_after
-
-
-@pytest.mark.parametrize("scalar_class,graphql_type", scalar_classes.items())
-def test_scalar_in_objecttype(scalar_class, graphql_type):
- class MyObjectType(ObjectType):
- before = Field(scalar_class)
- field = scalar_class()
- after = Field(scalar_class)
-
- graphql_type = get_graphql_type(MyObjectType)
- fields = graphql_type.get_fields()
- assert list(fields.keys()) == ['before', 'field', 'after']
- assert isinstance(fields['field'], GraphQLFieldDefinition)
-
-
-def test_custom_scalar_empty():
- with pytest.raises(AssertionError) as excinfo:
- class DatetimeScalar(Scalar):
- pass
-
- assert """DatetimeScalar must provide "serialize" function.""" in str(excinfo.value)
-
-
-@pytest.mark.parametrize("scalar_class", (DatetimeScalar, DatetimeScalarGraphQL))
-def test_custom_scalar_query(scalar_class):
- class Query(ObjectType):
- datetime = scalar_class(_in=scalar_class(name='in'))
-
- def resolve_datetime(self, args, context, info):
- return args.get('in')
-
- now = datetime.datetime.now()
- isoformat = now.isoformat()
-
- schema = Schema(query=Query)
-
- response = graphql(schema, '''
- {
- datetime(in: "%s")
- }
- ''' % isoformat)
-
- assert not response.errors
- assert response.data == {
- 'datetime': isoformat
- }
-
- response = graphql(schema, '''
- query Test($date: DateTime) {
- datetime(in: $date)
- }
- ''', variable_values={
- 'date': isoformat
- })
-
- assert not response.errors
- assert response.data == {
- 'datetime': isoformat
- }
diff --git a/graphene/new_types/tests/test_scalars_serialization.py b/graphene/types/tests/test_scalars_serialization.py
similarity index 100%
rename from graphene/new_types/tests/test_scalars_serialization.py
rename to graphene/types/tests/test_scalars_serialization.py
diff --git a/graphene/types/tests/test_schema.py b/graphene/types/tests/test_schema.py
deleted file mode 100644
index 5f3a7edc..00000000
--- a/graphene/types/tests/test_schema.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from ..field import Field
-from ..interface import Interface
-from ..objecttype import ObjectType
-from ..scalars import String
-from ..schema import Schema
-from ..structures import List
-
-
-class Character(Interface):
- name = String()
- friends = List(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):
- type = String()
-
-
-class Human(ObjectType):
-
- class Meta:
- interfaces = [Character]
-
- pet = Field(Pet)
-
- def resolve_pet(self, *args):
- return Pet(type='Dog')
-
-
-class RootQuery(ObjectType):
- character = Field(Character)
-
- def resolve_character(self, *_):
- return Human(name='Harry')
-
-
-schema = Schema(query=RootQuery, types=[Human])
-
-
-def test_schema():
- executed = schema.execute(
- '{ character {name, bestFriend { name }, friends { name}, ...on Human {pet { type } } } }')
- assert not executed.errors
- assert executed.data == {'character': {'name': 'Harry', 'bestFriend': {
- 'name': 'Best'}, 'friends': [{'name': 'Peter'}], 'pet': {'type': 'Dog'}}}
-
-
-def test_schema_introspect():
- introspection = schema.introspect()
- assert '__schema' in introspection
-
-
-def test_schema_str():
- expected = """
-schema {
- query: RootQuery
-}
-
-interface Character {
- name: String
- friends: [Character]
- bestFriend: Character
-}
-
-type Human implements Character {
- name: String
- friends: [Character]
- bestFriend: Character
- pet: Pet
-}
-
-type Pet {
- type: String
-}
-
-type RootQuery {
- character: Character
-}
-""".lstrip()
- assert str(schema) == expected
-
-
-def test_schema_get_type():
- pet = schema.get_type('Pet')
- assert pet == Pet._meta.graphql_type
-
-
-def test_schema_lazy_type():
- pet = schema.lazy('Pet')
- assert pet() == Pet._meta.graphql_type
diff --git a/graphene/types/tests/test_structures.py b/graphene/types/tests/test_structures.py
deleted file mode 100644
index 42025705..00000000
--- a/graphene/types/tests/test_structures.py
+++ /dev/null
@@ -1,51 +0,0 @@
-
-from graphql import GraphQLList, GraphQLNonNull, GraphQLString
-
-from ..field import Field
-from ..scalars import String
-from ..structures import List, NonNull
-
-
-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, GraphQLList)
- 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
-
-
-def test_preserve_order():
- field1 = List(lambda: None)
- field2 = Field(lambda: None)
-
- assert field1 < field2
diff --git a/graphene/new_types/tests/test_typemap.py b/graphene/types/tests/test_typemap.py
similarity index 100%
rename from graphene/new_types/tests/test_typemap.py
rename to graphene/types/tests/test_typemap.py
diff --git a/graphene/new_types/tests/test_union.py b/graphene/types/tests/test_union.py
similarity index 100%
rename from graphene/new_types/tests/test_union.py
rename to graphene/types/tests/test_union.py
diff --git a/graphene/new_types/typemap.py b/graphene/types/typemap.py
similarity index 100%
rename from graphene/new_types/typemap.py
rename to graphene/types/typemap.py
diff --git a/graphene/new_types/union.py b/graphene/types/union.py
similarity index 100%
rename from graphene/new_types/union.py
rename to graphene/types/union.py
diff --git a/graphene/types/unmountedtype.py b/graphene/types/unmountedtype.py
index b3a20f55..ac813e8e 100644
--- a/graphene/types/unmountedtype.py
+++ b/graphene/types/unmountedtype.py
@@ -1,6 +1,4 @@
from ..utils.orderedtype import OrderedType
-from .argument import Argument
-from .field import Field, InputField
class UnmountedType(OrderedType):
@@ -18,17 +16,18 @@ class UnmountedType(OrderedType):
'''
def __init__(self, *args, **kwargs):
+ super(UnmountedType, self).__init__()
self.args = args
self.kwargs = kwargs
- super(UnmountedType, self).__init__()
def get_type(self):
- return self._meta.graphql_type
+ raise NotImplementedError("get_type not implemented in {}".format(self))
def as_field(self):
'''
Mount the UnmountedType as Field
'''
+ from .field import Field
return Field(
self.get_type(),
*self.args,
@@ -40,6 +39,7 @@ class UnmountedType(OrderedType):
'''
Mount the UnmountedType as InputField
'''
+ from .inputfield import InputField
return InputField(
self.get_type(),
*self.args,
@@ -51,9 +51,20 @@ class UnmountedType(OrderedType):
'''
Mount the UnmountedType as Argument
'''
+ from .argument import Argument
return Argument(
self.get_type(),
*self.args,
_creation_counter=self.creation_counter,
**self.kwargs
)
+
+ def __eq__(self, other):
+ return (
+ self is other or (
+ isinstance(other, UnmountedType) and
+ self.get_type() == other.get_type() and
+ self.args == other.args and
+ self.kwargs == other.kwargs
+ )
+ )
diff --git a/graphene/new_types/utils.py b/graphene/types/utils.py
similarity index 88%
rename from graphene/new_types/utils.py
rename to graphene/types/utils.py
index dab29884..74eb52dc 100644
--- a/graphene/new_types/utils.py
+++ b/graphene/types/utils.py
@@ -6,7 +6,7 @@ from .inputfield import InputField
def merge_fields_in_attrs(bases, attrs):
- from ..new_types.abstracttype import AbstractType
+ from ..types.abstracttype import AbstractType
for base in bases:
if base == AbstractType or not issubclass(base, AbstractType):
continue
@@ -26,10 +26,10 @@ def unmounted_field_in_type(attname, unmounted_field, type):
InputObjectType -> InputField
'''
# from ..types.inputobjecttype import InputObjectType
- from ..new_types.objecttype import ObjectType
- from ..new_types.interface import Interface
- from ..new_types.abstracttype import AbstractType
- from ..new_types.inputobjecttype import InputObjectType
+ from ..types.objecttype import ObjectType
+ from ..types.interface import Interface
+ from ..types.abstracttype import AbstractType
+ from ..types.inputobjecttype import InputObjectType
if issubclass(type, (ObjectType, Interface)):
return unmounted_field.as_field()