mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-08 23:50:38 +03:00
Next types
This commit is contained in:
parent
04492600e5
commit
550ad386f0
0
graphene/new_types/__init__.py
Normal file
0
graphene/new_types/__init__.py
Normal file
37
graphene/new_types/abstracttype.py
Normal file
37
graphene/new_types/abstracttype.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import six
|
||||
from collections import OrderedDict
|
||||
|
||||
from ..utils.is_base_type import is_base_type
|
||||
from .options import Options
|
||||
|
||||
from .utils import get_fields_in_type, attrs_without_fields
|
||||
|
||||
|
||||
def merge_fields_in_attrs(bases, attrs):
|
||||
for base in bases:
|
||||
if not issubclass(base, AbstractType):
|
||||
continue
|
||||
for name, field in base._meta.fields.items():
|
||||
if name in attrs:
|
||||
continue
|
||||
attrs[name] = field
|
||||
return attrs
|
||||
|
||||
|
||||
class AbstractTypeMeta(type):
|
||||
|
||||
def __new__(cls, name, bases, attrs):
|
||||
options = attrs.get('_meta', Options())
|
||||
|
||||
attrs = merge_fields_in_attrs(bases, attrs)
|
||||
fields = get_fields_in_type(cls, attrs)
|
||||
options.fields = OrderedDict(sorted(fields, key=lambda f: f[1]))
|
||||
|
||||
attrs = attrs_without_fields(attrs, fields)
|
||||
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||
|
||||
return cls
|
||||
|
||||
|
||||
class AbstractType(six.with_metaclass(AbstractTypeMeta)):
|
||||
pass
|
70
graphene/new_types/field.py
Normal file
70
graphene/new_types/field.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
# import inspect
|
||||
from functools import partial
|
||||
from collections import OrderedDict
|
||||
|
||||
# from graphql.type import (GraphQLField, GraphQLInputObjectField)
|
||||
# from graphql.utils.assert_valid_name import assert_valid_name
|
||||
|
||||
from ..utils.orderedtype import OrderedType
|
||||
from .structures import NonNull
|
||||
# from ..utils.str_converters import to_camel_case
|
||||
# from .argument import to_arguments
|
||||
|
||||
|
||||
# class AbstractField(object):
|
||||
|
||||
# @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
|
||||
|
||||
# @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
|
||||
|
||||
def source_resolver(source, root, args, context, info):
|
||||
resolved = getattr(root, source, None)
|
||||
if callable(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)
|
||||
self.name = name
|
||||
# self.attname = None
|
||||
# self.parent = None
|
||||
if required:
|
||||
type = NonNull(type)
|
||||
self.type = type
|
||||
self.args = args or OrderedDict()
|
||||
# self.args = to_arguments(args, extra_args)
|
||||
assert not (source and resolver), ('You cannot provide a source and a '
|
||||
'resolver in a Field at the same time.')
|
||||
if source:
|
||||
resolver = partial(source_resolver, source)
|
||||
self.resolver = resolver
|
||||
self.deprecation_reason = deprecation_reason
|
||||
self.description = description
|
41
graphene/new_types/interface.py
Normal file
41
graphene/new_types/interface.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
import six
|
||||
from collections import OrderedDict
|
||||
|
||||
from ..utils.is_base_type import is_base_type
|
||||
from .options import Options
|
||||
|
||||
from .utils import get_fields_in_type, attrs_without_fields
|
||||
|
||||
|
||||
class InterfaceMeta(type):
|
||||
|
||||
def __new__(cls, name, bases, attrs):
|
||||
# Also ensure initialization is only performed for subclasses of
|
||||
# ObjectType
|
||||
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__'),
|
||||
)
|
||||
|
||||
fields = get_fields_in_type(Interface, attrs)
|
||||
options.fields = OrderedDict(sorted(fields, key=lambda f: f[1]))
|
||||
|
||||
attrs = attrs_without_fields(attrs, fields)
|
||||
cls = super(InterfaceMeta, cls).__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||
|
||||
return cls
|
||||
|
||||
|
||||
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
|
73
graphene/new_types/objecttype.py
Normal file
73
graphene/new_types/objecttype.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
import six
|
||||
from collections import OrderedDict
|
||||
|
||||
from ..utils.is_base_type import is_base_type
|
||||
from .options import Options
|
||||
|
||||
from .utils import get_fields_in_type, attrs_without_fields
|
||||
|
||||
|
||||
class ObjectTypeMeta(type):
|
||||
|
||||
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=(),
|
||||
)
|
||||
|
||||
fields = get_fields_in_type(ObjectType, attrs)
|
||||
options.fields = OrderedDict(sorted(fields, key=lambda f: f[1]))
|
||||
|
||||
attrs = attrs_without_fields(attrs, fields)
|
||||
cls = super(ObjectTypeMeta, cls).__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||
|
||||
return cls
|
||||
|
||||
|
||||
class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||
|
||||
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__
|
||||
)
|
||||
)
|
37
graphene/new_types/options.py
Normal file
37
graphene/new_types/options.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
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))
|
||||
)
|
||||
self.add_attrs_from_meta(meta, defaults)
|
||||
|
||||
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:
|
||||
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 '<Meta \n{} >'.format(props(self))
|
23
graphene/new_types/structures.py
Normal file
23
graphene/new_types/structures.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
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):
|
||||
pass
|
||||
|
||||
|
||||
class NonNull(Structure):
|
||||
pass
|
0
graphene/new_types/tests/__init__.py
Normal file
0
graphene/new_types/tests/__init__.py
Normal file
99
graphene/new_types/tests/test_abstracttype.py
Normal file
99
graphene/new_types/tests/test_abstracttype.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
import pytest
|
||||
|
||||
from ..field import Field
|
||||
from ..abstracttype import AbstractType
|
||||
from ..unmountedtype import UnmountedType
|
||||
|
||||
|
||||
class MyType(object):
|
||||
pass
|
||||
|
||||
|
||||
class MyScalar(UnmountedType):
|
||||
def get_type(self):
|
||||
return MyType
|
||||
|
||||
|
||||
def test_generate_abstracttype_with_fields():
|
||||
class MyAbstractType(AbstractType):
|
||||
field = Field(MyType)
|
||||
|
||||
assert 'field' in MyAbstractType._meta.fields
|
||||
assert isinstance(MyAbstractType._meta.fields['field'], Field)
|
||||
|
||||
|
||||
def test_generate_abstracttype_with_unmountedfields():
|
||||
class MyAbstractType(AbstractType):
|
||||
field = UnmountedType(MyType)
|
||||
|
||||
assert 'field' in MyAbstractType._meta.fields
|
||||
assert isinstance(MyAbstractType._meta.fields['field'], UnmountedType)
|
||||
|
||||
|
||||
def test_generate_abstracttype_inheritance():
|
||||
class MyAbstractType1(AbstractType):
|
||||
field1 = UnmountedType(MyType)
|
||||
|
||||
class MyAbstractType2(MyAbstractType1):
|
||||
field2 = UnmountedType(MyType)
|
||||
|
||||
assert MyAbstractType2._meta.fields.keys() == ['field1', 'field2']
|
||||
|
||||
|
||||
# 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_unmountedtype():
|
||||
# class MyObjectType(ObjectType):
|
||||
# field = MyScalar(MyType)
|
||||
|
||||
# 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)
|
55
graphene/new_types/tests/test_field.py
Normal file
55
graphene/new_types/tests/test_field.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
import pytest
|
||||
|
||||
from ..field import Field
|
||||
from ..structures import NonNull
|
||||
|
||||
|
||||
class MyInstance(object):
|
||||
value = 'value'
|
||||
value_func = staticmethod(lambda: 'value_func')
|
||||
|
||||
|
||||
def test_field_basic():
|
||||
MyType = object()
|
||||
args = {}
|
||||
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_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) == 'You cannot provide a source and a resolver in a Field 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()
|
59
graphene/new_types/tests/test_interface.py
Normal file
59
graphene/new_types/tests/test_interface.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
import pytest
|
||||
|
||||
from ..field import Field
|
||||
from ..interface import Interface
|
||||
from ..unmountedtype import UnmountedType
|
||||
|
||||
|
||||
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(MyType)
|
||||
|
||||
assert 'field' in MyInterface._meta.fields
|
||||
assert isinstance(MyInterface._meta.fields['field'], Field)
|
108
graphene/new_types/tests/test_objecttype.py
Normal file
108
graphene/new_types/tests/test_objecttype.py
Normal file
|
@ -0,0 +1,108 @@
|
|||
import pytest
|
||||
|
||||
from ..field import Field
|
||||
from ..objecttype import ObjectType
|
||||
from ..unmountedtype import UnmountedType
|
||||
|
||||
|
||||
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_unmountedtype():
|
||||
class MyObjectType(ObjectType):
|
||||
field = MyScalar(MyType)
|
||||
|
||||
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)
|
60
graphene/new_types/unmountedtype.py
Normal file
60
graphene/new_types/unmountedtype.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
from ..utils.orderedtype import OrderedType
|
||||
# from .argument import Argument
|
||||
|
||||
|
||||
|
||||
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
|
||||
# '''
|
||||
# return InputField(
|
||||
# self.get_type(),
|
||||
# *self.args,
|
||||
# _creation_counter=self.creation_counter,
|
||||
# **self.kwargs
|
||||
# )
|
||||
|
||||
# def as_argument(self):
|
||||
# '''
|
||||
# Mount the UnmountedType as Argument
|
||||
# '''
|
||||
# return Argument(
|
||||
# self.get_type(),
|
||||
# *self.args,
|
||||
# _creation_counter=self.creation_counter,
|
||||
# **self.kwargs
|
||||
# )
|
42
graphene/new_types/utils.py
Normal file
42
graphene/new_types/utils.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from .unmountedtype import UnmountedType
|
||||
from .field import Field
|
||||
|
||||
|
||||
def unmounted_field_in_type(attname, unmounted_field, type):
|
||||
'''
|
||||
Mount the UnmountedType dinamically as Field or InputField
|
||||
depending on where mounted in.
|
||||
|
||||
ObjectType -> Field
|
||||
InputObjectType -> InputField
|
||||
'''
|
||||
# from ..types.inputobjecttype import InputObjectType
|
||||
from ..new_types.objecttype import ObjectTypeMeta
|
||||
from ..new_types.interface import Interface
|
||||
from ..new_types.abstracttype import AbstractTypeMeta
|
||||
|
||||
if issubclass(type, (ObjectTypeMeta, Interface)):
|
||||
return unmounted_field.as_field()
|
||||
|
||||
elif issubclass(type, (AbstractTypeMeta)):
|
||||
return unmounted_field
|
||||
# elif issubclass(type, (InputObjectType)):
|
||||
# return unmounted_field.as_inputfield()
|
||||
|
||||
raise Exception(
|
||||
'Unmounted field "{}" cannot be mounted in {}.{}.'.format(
|
||||
unmounted_field, type, attname
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_fields_in_type(in_type, attrs):
|
||||
for attname, value in list(attrs.items()):
|
||||
if isinstance(value, (Field)): # , InputField
|
||||
yield attname, value
|
||||
elif isinstance(value, UnmountedType):
|
||||
yield attname, unmounted_field_in_type(attname, value, in_type)
|
||||
|
||||
|
||||
def attrs_without_fields(attrs, fields):
|
||||
return {k: v for k, v in attrs.items() if k not in fields}
|
Loading…
Reference in New Issue
Block a user