Merge pull request #102 from graphql-python/features/source

Added source argument in Fields
This commit is contained in:
Syrus Akbary 2016-02-02 19:05:30 -08:00
commit 141beb0364
6 changed files with 71 additions and 3 deletions

View File

@ -46,6 +46,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, FieldsClassType)):
class Meta:
abstract = True
def __getattr__(self, name):
return self._root and getattr(self._root, name)
def __init__(self, *args, **kwargs):
signals.pre_init.send(self.__class__, args=args, kwargs=kwargs)
self._root = kwargs.pop('_root', None)

View File

@ -4,6 +4,7 @@ from functools import wraps
import six
from graphql.core.type import GraphQLField, GraphQLInputObjectField
from ...utils import maybe_func
from ..classtypes.base import FieldsClassType
from ..classtypes.inputobjecttype import InputObjectType
from ..classtypes.mutation import Mutation
@ -18,7 +19,8 @@ class Field(NamedType, OrderedType):
def __init__(
self, type, description=None, args=None, name=None, resolver=None,
required=False, default=None, deprecation_reason=None, *args_list, **kwargs):
source=None, required=False, default=None, deprecation_reason=None,
*args_list, **kwargs):
_creation_counter = kwargs.pop('_creation_counter', None)
if isinstance(name, (Argument, ArgumentType)):
kwargs['name'] = name
@ -33,7 +35,12 @@ class Field(NamedType, OrderedType):
args = OrderedDict(args or {}, **kwargs)
self.arguments = ArgumentsGroup(*args_list, **args)
self.object_type = None
self.attname = None
self.default_name = None
self.resolver_fn = resolver
self.source = source
assert not (self.source and self.resolver_fn), ('You cannot have a source'
' and a resolver at the same time')
self.default = default
def contribute_to_class(self, cls, attname):
@ -68,7 +75,8 @@ class Field(NamedType, OrderedType):
return getattr(self.object_type, resolve_fn_name)
def default_getter(instance, args, info):
return getattr(instance, self.attname, self.default)
value = getattr(instance, self.source or self.attname, self.default)
return maybe_func(value)
return default_getter
def get_type(self, schema):
@ -80,6 +88,8 @@ class Field(NamedType, OrderedType):
return snake_case_args(resolver)
def internal_type(self, schema):
if not self.object_type:
raise Exception('The field is not mounted in any ClassType')
resolver = self.resolver
description = self.description
arguments = self.arguments

View File

@ -180,3 +180,41 @@ def test_field_internal_type_deprecated():
type = schema.T(field)
assert isinstance(type, GraphQLField)
assert type.deprecation_reason == deprecation_reason
def test_field_resolve_object():
class Root(object):
att = True
@staticmethod
def att_func():
return True
field = Field(String(), description='My argument')
field_func = Field(String(), description='My argument')
class Query(ObjectType):
att = field
att_func = field_func
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None) is True
def test_field_resolve_source_object():
class Root(object):
att_source = True
@staticmethod
def att_func_source():
return True
field = Field(String(), source='att_source', description='My argument')
field_func = Field(String(), source='att_source', description='My argument')
class Query(ObjectType):
att = field
att_func = field_func
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None) is True

View File

@ -1,11 +1,12 @@
from .str_converters import to_camel_case, to_snake_case
from .proxy_snake_dict import ProxySnakeDict
from .caching import cached_property, memoize
from .maybe_func import maybe_func
from .misc import enum_to_graphql_enum
from .resolve_only_args import resolve_only_args
from .lazylist import LazyList
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
'cached_property', 'memoize', 'enum_to_graphql_enum',
'cached_property', 'memoize', 'maybe_func', 'enum_to_graphql_enum',
'resolve_only_args', 'LazyList']

View File

@ -0,0 +1,7 @@
import inspect
def maybe_func(f):
if inspect.isfunction(f):
return f()
return f

View File

@ -0,0 +1,9 @@
from ..maybe_func import maybe_func
def maybe_func_function():
assert maybe_func(lambda: True) is True
def maybe_func_value():
assert maybe_func(True) is True