Added InputObjectType and InputField

This commit is contained in:
Syrus Akbary 2016-08-12 19:23:33 -07:00
parent 8cf5b1d9ab
commit 70a9de63f9
6 changed files with 152 additions and 14 deletions

View File

@ -0,0 +1,17 @@
from ..utils.orderedtype import OrderedType
from .structures import NonNull
class InputField(OrderedType):
def __init__(self, type, name=None, default_value=None,
deprecation_reason=None, description=None,
required=False, _creation_counter=None, **extra_args):
super(InputField, self).__init__(_creation_counter=_creation_counter)
self.name = name
if required:
type = NonNull(type)
self.type = type
self.deprecation_reason = deprecation_reason
self.default_value = default_value
self.description = description

View File

@ -0,0 +1,36 @@
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")

View File

@ -19,7 +19,6 @@ class InterfaceMeta(AbstractTypeMeta):
attrs.pop('Meta', None),
name=name,
description=attrs.get('__doc__'),
interfaces=(),
)
attrs = merge_fields_in_attrs(bases, attrs)

View File

@ -0,0 +1,83 @@
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]

View File

@ -37,16 +37,17 @@ class UnmountedType(OrderedType):
**self.kwargs
)
# def as_inputfield(self):
# '''
# Mount the UnmountedType as InputField
# '''
# return InputField(
# 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):
# '''

View File

@ -2,6 +2,7 @@ from collections import OrderedDict
from .unmountedtype import UnmountedType
from .field import Field
from .inputfield import InputField
def merge_fields_in_attrs(bases, attrs):
@ -28,14 +29,15 @@ def unmounted_field_in_type(attname, unmounted_field, type):
from ..new_types.objecttype import ObjectType
from ..new_types.interface import Interface
from ..new_types.abstracttype import AbstractType
from ..new_types.inputobjecttype import InputObjectType
if issubclass(type, (ObjectType, Interface)):
return unmounted_field.as_field()
elif issubclass(type, (AbstractType)):
return unmounted_field
# elif issubclass(type, (InputObjectType)):
# return unmounted_field.as_inputfield()
elif issubclass(type, (InputObjectType)):
return unmounted_field.as_inputfield()
raise Exception(
'Unmounted field "{}" cannot be mounted in {}.{}.'.format(
@ -47,7 +49,7 @@ def unmounted_field_in_type(attname, unmounted_field, type):
def get_fields_in_type(in_type, attrs):
fields_with_names = []
for attname, value in list(attrs.items()):
if isinstance(value, (Field)): # , InputField
if isinstance(value, (Field, InputField)):
fields_with_names.append(
(attname, value)
)