mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-03 05:04:14 +03:00
Merge pull request #102 from graphql-python/features/source
Added source argument in Fields
This commit is contained in:
commit
141beb0364
|
@ -46,6 +46,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, FieldsClassType)):
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self._root and getattr(self._root, name)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
signals.pre_init.send(self.__class__, args=args, kwargs=kwargs)
|
signals.pre_init.send(self.__class__, args=args, kwargs=kwargs)
|
||||||
self._root = kwargs.pop('_root', None)
|
self._root = kwargs.pop('_root', None)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from functools import wraps
|
||||||
import six
|
import six
|
||||||
from graphql.core.type import GraphQLField, GraphQLInputObjectField
|
from graphql.core.type import GraphQLField, GraphQLInputObjectField
|
||||||
|
|
||||||
|
from ...utils import maybe_func
|
||||||
from ..classtypes.base import FieldsClassType
|
from ..classtypes.base import FieldsClassType
|
||||||
from ..classtypes.inputobjecttype import InputObjectType
|
from ..classtypes.inputobjecttype import InputObjectType
|
||||||
from ..classtypes.mutation import Mutation
|
from ..classtypes.mutation import Mutation
|
||||||
|
@ -18,7 +19,8 @@ class Field(NamedType, OrderedType):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, type, description=None, args=None, name=None, resolver=None,
|
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)
|
_creation_counter = kwargs.pop('_creation_counter', None)
|
||||||
if isinstance(name, (Argument, ArgumentType)):
|
if isinstance(name, (Argument, ArgumentType)):
|
||||||
kwargs['name'] = name
|
kwargs['name'] = name
|
||||||
|
@ -33,7 +35,12 @@ class Field(NamedType, OrderedType):
|
||||||
args = OrderedDict(args or {}, **kwargs)
|
args = OrderedDict(args or {}, **kwargs)
|
||||||
self.arguments = ArgumentsGroup(*args_list, **args)
|
self.arguments = ArgumentsGroup(*args_list, **args)
|
||||||
self.object_type = None
|
self.object_type = None
|
||||||
|
self.attname = None
|
||||||
|
self.default_name = None
|
||||||
self.resolver_fn = resolver
|
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
|
self.default = default
|
||||||
|
|
||||||
def contribute_to_class(self, cls, attname):
|
def contribute_to_class(self, cls, attname):
|
||||||
|
@ -68,7 +75,8 @@ class Field(NamedType, OrderedType):
|
||||||
return getattr(self.object_type, resolve_fn_name)
|
return getattr(self.object_type, resolve_fn_name)
|
||||||
|
|
||||||
def default_getter(instance, args, info):
|
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
|
return default_getter
|
||||||
|
|
||||||
def get_type(self, schema):
|
def get_type(self, schema):
|
||||||
|
@ -80,6 +88,8 @@ class Field(NamedType, OrderedType):
|
||||||
return snake_case_args(resolver)
|
return snake_case_args(resolver)
|
||||||
|
|
||||||
def internal_type(self, schema):
|
def internal_type(self, schema):
|
||||||
|
if not self.object_type:
|
||||||
|
raise Exception('The field is not mounted in any ClassType')
|
||||||
resolver = self.resolver
|
resolver = self.resolver
|
||||||
description = self.description
|
description = self.description
|
||||||
arguments = self.arguments
|
arguments = self.arguments
|
||||||
|
|
|
@ -180,3 +180,41 @@ def test_field_internal_type_deprecated():
|
||||||
type = schema.T(field)
|
type = schema.T(field)
|
||||||
assert isinstance(type, GraphQLField)
|
assert isinstance(type, GraphQLField)
|
||||||
assert type.deprecation_reason == deprecation_reason
|
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
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from .str_converters import to_camel_case, to_snake_case
|
from .str_converters import to_camel_case, to_snake_case
|
||||||
from .proxy_snake_dict import ProxySnakeDict
|
from .proxy_snake_dict import ProxySnakeDict
|
||||||
from .caching import cached_property, memoize
|
from .caching import cached_property, memoize
|
||||||
|
from .maybe_func import maybe_func
|
||||||
from .misc import enum_to_graphql_enum
|
from .misc import enum_to_graphql_enum
|
||||||
from .resolve_only_args import resolve_only_args
|
from .resolve_only_args import resolve_only_args
|
||||||
from .lazylist import LazyList
|
from .lazylist import LazyList
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
|
__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']
|
'resolve_only_args', 'LazyList']
|
||||||
|
|
7
graphene/utils/maybe_func.py
Normal file
7
graphene/utils/maybe_func.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def maybe_func(f):
|
||||||
|
if inspect.isfunction(f):
|
||||||
|
return f()
|
||||||
|
return f
|
9
graphene/utils/tests/test_maybe_func.py
Normal file
9
graphene/utils/tests/test_maybe_func.py
Normal 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
|
Loading…
Reference in New Issue
Block a user