mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-11 04:07:16 +03:00
Added Field arguments.
This commit is contained in:
parent
70a9de63f9
commit
a7b3d193eb
33
graphene/new_types/argument.py
Normal file
33
graphene/new_types/argument.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
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
|
|
@ -1,9 +1,10 @@
|
|||
import inspect
|
||||
from functools import partial
|
||||
from collections import OrderedDict
|
||||
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):
|
||||
|
@ -25,7 +26,9 @@ class Field(OrderedType):
|
|||
if required:
|
||||
type = NonNull(type)
|
||||
self._type = type
|
||||
self.args = args or OrderedDict()
|
||||
if args:
|
||||
assert isinstance(args, Mapping), 'Arguments in a field have to be a mapping, received "{}".'.format(args)
|
||||
self.args = to_arguments(args or OrderedDict(), extra_args)
|
||||
# self.args = to_arguments(args, extra_args)
|
||||
assert not (source and resolver), ('A Field cannot have a source and a '
|
||||
'resolver in at the same time.')
|
||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
|||
|
||||
from ..field import Field
|
||||
from ..structures import NonNull
|
||||
from ..argument import Argument
|
||||
|
||||
|
||||
class MyInstance(object):
|
||||
|
@ -11,7 +12,7 @@ class MyInstance(object):
|
|||
|
||||
def test_field_basic():
|
||||
MyType = object()
|
||||
args = {}
|
||||
args = {'my arg': Argument(True)}
|
||||
resolver = lambda: None
|
||||
deprecation_reason = 'Deprecated now'
|
||||
description = 'My Field'
|
||||
|
@ -49,7 +50,22 @@ def test_field_not_source_and_resolver():
|
|||
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
|
||||
|
|
|
@ -54,7 +54,7 @@ def test_ordered_fields_in_interface():
|
|||
|
||||
def test_generate_interface_unmountedtype():
|
||||
class MyInterface(Interface):
|
||||
field = MyScalar(MyType)
|
||||
field = MyScalar()
|
||||
|
||||
assert 'field' in MyInterface._meta.fields
|
||||
assert isinstance(MyInterface._meta.fields['field'], Field)
|
||||
|
@ -62,10 +62,10 @@ def test_generate_interface_unmountedtype():
|
|||
|
||||
def test_generate_interface_inherit_abstracttype():
|
||||
class MyAbstractType(AbstractType):
|
||||
field1 = MyScalar(MyType)
|
||||
field1 = MyScalar()
|
||||
|
||||
class MyInterface(Interface, MyAbstractType):
|
||||
field2 = MyScalar(MyType)
|
||||
field2 = MyScalar()
|
||||
|
||||
assert MyInterface._meta.fields.keys() == ['field1', 'field2']
|
||||
assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
|
||||
|
@ -73,10 +73,10 @@ def test_generate_interface_inherit_abstracttype():
|
|||
|
||||
def test_generate_interface_inherit_abstracttype_reversed():
|
||||
class MyAbstractType(AbstractType):
|
||||
field1 = MyScalar(MyType)
|
||||
field1 = MyScalar()
|
||||
|
||||
class MyInterface(MyAbstractType, Interface):
|
||||
field2 = MyScalar(MyType)
|
||||
field2 = MyScalar()
|
||||
|
||||
assert MyInterface._meta.fields.keys() == ['field1', 'field2']
|
||||
assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]
|
||||
|
|
|
@ -62,10 +62,10 @@ def test_ordered_fields_in_objecttype():
|
|||
|
||||
def test_generate_objecttype_inherit_abstracttype():
|
||||
class MyAbstractType(AbstractType):
|
||||
field1 = MyScalar(MyType)
|
||||
field1 = MyScalar()
|
||||
|
||||
class MyObjectType(ObjectType, MyAbstractType):
|
||||
field2 = MyScalar(MyType)
|
||||
field2 = MyScalar()
|
||||
|
||||
assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
|
||||
assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
|
||||
|
@ -73,10 +73,10 @@ def test_generate_objecttype_inherit_abstracttype():
|
|||
|
||||
def test_generate_objecttype_inherit_abstracttype_reversed():
|
||||
class MyAbstractType(AbstractType):
|
||||
field1 = MyScalar(MyType)
|
||||
field1 = MyScalar()
|
||||
|
||||
class MyObjectType(MyAbstractType, ObjectType):
|
||||
field2 = MyScalar(MyType)
|
||||
field2 = MyScalar()
|
||||
|
||||
assert MyObjectType._meta.fields.keys() == ['field1', 'field2']
|
||||
assert [type(x) for x in MyObjectType._meta.fields.values()] == [Field, Field]
|
||||
|
@ -84,7 +84,7 @@ def test_generate_objecttype_inherit_abstracttype_reversed():
|
|||
|
||||
def test_generate_objecttype_unmountedtype():
|
||||
class MyObjectType(ObjectType):
|
||||
field = MyScalar(MyType)
|
||||
field = MyScalar()
|
||||
|
||||
assert 'field' in MyObjectType._meta.fields
|
||||
assert isinstance(MyObjectType._meta.fields['field'], Field)
|
||||
|
|
|
@ -49,13 +49,14 @@ class UnmountedType(OrderedType):
|
|||
**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
|
||||
# )
|
||||
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
|
||||
)
|
||||
|
|
|
@ -54,9 +54,13 @@ def get_fields_in_type(in_type, attrs):
|
|||
(attname, value)
|
||||
)
|
||||
elif isinstance(value, UnmountedType):
|
||||
fields_with_names.append(
|
||||
(attname, unmounted_field_in_type(attname, value, in_type))
|
||||
)
|
||||
try:
|
||||
value = unmounted_field_in_type(attname, value, in_type)
|
||||
fields_with_names.append(
|
||||
(attname, value)
|
||||
)
|
||||
except Exception as e:
|
||||
raise Exception('Exception while mounting the field "{}": {}'.format(attname, str(e)))
|
||||
|
||||
return OrderedDict(sorted(fields_with_names, key=lambda f: f[1]))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user