mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-26 19:43:56 +03:00
Added InputObjectType and InputField
This commit is contained in:
parent
8cf5b1d9ab
commit
70a9de63f9
17
graphene/new_types/inputfield.py
Normal file
17
graphene/new_types/inputfield.py
Normal 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
|
36
graphene/new_types/inputobjecttype.py
Normal file
36
graphene/new_types/inputobjecttype.py
Normal 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")
|
|
@ -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)
|
||||
|
|
83
graphene/new_types/tests/test_inputobjecttype.py
Normal file
83
graphene/new_types/tests/test_inputobjecttype.py
Normal 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]
|
|
@ -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):
|
||||
# '''
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user