diff --git a/graphene/core/schema.py b/graphene/core/schema.py index b9e6f56d..46e8768f 100644 --- a/graphene/core/schema.py +++ b/graphene/core/schema.py @@ -8,20 +8,11 @@ from graphql.utils.schema_printer import print_schema from graphene import signals from ..plugins import CamelCase, PluginManager +from ..utils import promise_middleware from .classtypes.base import ClassType from .types.base import InstanceType -class ACI(object): - def __init__(self, args, context, info): - self.args = args - self.context = context - self.info = info - - def __repr__(self): - return "ACI(args={}, context={}, info={})".format(repr(self.args), repr(self.context), repr(self.info)) - - class GraphQLSchema(_GraphQLSchema): def __init__(self, schema, *args, **kwargs): @@ -121,25 +112,9 @@ class Schema(object): raise KeyError('Type %r not found in %r' % (type_name, self)) return self._types_names[type_name] - def resolve(self, resolver, root, args, context, info): - aci = ACI(args, context, info) - plugins_process_aci = self.plugins.get_plugin_functions('process_aci') - plugins_process_response = self.plugins.get_plugin_functions('process_response') - for process_aci in plugins_process_aci: - processed_aci = process_aci(aci) - if processed_aci is None: - continue - return processed_aci - - response = resolver(root, aci.args, aci.context, aci.info) - - for process_response in plugins_process_response: - processed_response = process_response(response, aci) - if processed_response is None: - continue - return processed_response - - return response + def resolver_with_middleware(self, resolver): + plugins_resolve = self.plugins.get_plugin_functions('resolve') + return promise_middleware(resolver, plugins_resolve) @property def types(self): diff --git a/graphene/core/tests/test_old_fields.py b/graphene/core/tests/test_old_fields.py index a1d8ac60..696115d0 100644 --- a/graphene/core/tests/test_old_fields.py +++ b/graphene/core/tests/test_old_fields.py @@ -93,7 +93,7 @@ def test_field_resolve(): f = StringField(required=True, resolve=lambda *args: 'RESOLVED').as_field() f.contribute_to_class(MyOt, 'field_name') field_type = schema.T(f) - assert 'RESOLVED' == field_type.resolver(MyOt, None, None, None) + assert 'RESOLVED' == field_type.resolver(MyOt, None, None, None).value def test_field_resolve_type_custom(): diff --git a/graphene/core/types/field.py b/graphene/core/types/field.py index 837f505e..e7a36f84 100644 --- a/graphene/core/types/field.py +++ b/graphene/core/types/field.py @@ -115,10 +115,13 @@ class Field(NamedType, OrderedType): resolver = wrapped_func assert type, 'Internal type for field %s is None' % str(self) - return GraphQLField(type, args=schema.T(arguments), - resolver=partial(schema.resolve, resolver), - deprecation_reason=self.deprecation_reason, - description=description,) + return GraphQLField( + type, + args=schema.T(arguments), + resolver=schema.resolver_with_middleware(resolver), + deprecation_reason=self.deprecation_reason, + description=description, + ) def __repr__(self): """ @@ -172,7 +175,8 @@ class InputField(NamedType, OrderedType): def internal_type(self, schema): return GraphQLInputObjectField( schema.T(self.type), - default_value=self.default, description=self.description) + default_value=self.default, description=self.description + ) class FieldsGroupType(GroupNamedType): diff --git a/graphene/core/types/tests/test_field.py b/graphene/core/types/tests/test_field.py index eb99594c..38792705 100644 --- a/graphene/core/types/tests/test_field.py +++ b/graphene/core/types/tests/test_field.py @@ -24,7 +24,7 @@ def test_field_internal_type(): assert field.attname == 'my_field' assert isinstance(type, GraphQLField) assert type.description == 'My argument' - assert type.resolver(None, {}, None, None) == 'RESOLVED' + assert type.resolver(None, {}, None, None).value == 'RESOLVED' assert type.type == GraphQLString @@ -43,7 +43,7 @@ def test_field_objectype_resolver(): type = schema.T(field) assert isinstance(type, GraphQLField) assert type.description == 'Custom description' - assert type.resolver(Query(), {}, None, None) == 'RESOLVED' + assert type.resolver(Query(), {}, None, None).value == 'RESOLVED' def test_field_custom_name(): @@ -161,7 +161,7 @@ def test_field_resolve_argument(): schema = Schema(query=Query) type = schema.T(field) - assert type.resolver(None, {'firstName': 'Peter'}, None, None) == 'Peter' + assert type.resolver(None, {'firstName': 'Peter'}, None, None).value == 'Peter' def test_field_resolve_vars(): @@ -216,7 +216,6 @@ def test_field_resolve_object(): att_func = field_func assert field.resolver(Root, {}, None) is True - assert field.resolver(Root, {}, None) is True def test_field_resolve_source_object(): @@ -235,4 +234,3 @@ def test_field_resolve_source_object(): att_func = field_func assert field.resolver(Root, {}, None) is True - assert field.resolver(Root, {}, None) is True diff --git a/graphene/plugins/camel_case.py b/graphene/plugins/camel_case.py index 8b1c2bde..1f1c6690 100644 --- a/graphene/plugins/camel_case.py +++ b/graphene/plugins/camel_case.py @@ -6,5 +6,6 @@ class CamelCase(object): def get_default_namedtype_name(self, value): return to_camel_case(value) - def process_aci(self, aci): - aci.args = ProxySnakeDict(aci.args) + def resolve(self, next, root, args, context, info): + args = ProxySnakeDict(args) + return next(root, args, context, info) diff --git a/graphene/utils/__init__.py b/graphene/utils/__init__.py index 2ed0f036..261f33e3 100644 --- a/graphene/utils/__init__.py +++ b/graphene/utils/__init__.py @@ -3,6 +3,7 @@ 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 .promise_middleware import promise_middleware from .resolve_only_args import resolve_only_args from .lazylist import LazyList from .wrap_resolver_function import with_context, wrap_resolver_function @@ -10,5 +11,5 @@ from .wrap_resolver_function import with_context, wrap_resolver_function __all__ = ['to_camel_case', 'to_snake_case', 'to_const', 'ProxySnakeDict', 'cached_property', 'memoize', 'maybe_func', 'enum_to_graphql_enum', - 'resolve_only_args', 'LazyList', 'with_context', + 'promise_middleware', 'resolve_only_args', 'LazyList', 'with_context', 'wrap_resolver_function'] diff --git a/graphene/utils/promise_middleware.py b/graphene/utils/promise_middleware.py new file mode 100644 index 00000000..5190ed02 --- /dev/null +++ b/graphene/utils/promise_middleware.py @@ -0,0 +1,17 @@ +from functools import partial +from itertools import chain + +from promise import Promise + + +def promise_middleware(func, middlewares): + middlewares = chain((func, make_it_promise), middlewares) + past = None + for m in middlewares: + past = partial(m, past) if past else m + + return past + + +def make_it_promise(next, *a, **b): + return Promise.resolve(next(*a, **b))