Skip to content

Use Promises in execute context #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 3 additions & 34 deletions graphql/execution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,11 @@
2) fragment "spreads" e.g. "...c"
3) inline fragment "spreads" e.g. "...on Type { a }"
"""

from .execute import execute as _execute
from .base import ExecutionResult
from .executor import Executor
from .middlewares.sync import SynchronousExecutionMiddleware


def execute(schema, root, ast, operation_name='', args=None):
"""
Executes an AST synchronously. Assumes that the AST is already validated.
"""
return get_default_executor().execute(schema, ast, root, args, operation_name, validate_ast=False)


_default_executor = None


def get_default_executor():
"""
Gets the default executor to be used in the `execute` function above.
"""
global _default_executor
if _default_executor is None:
_default_executor = Executor([SynchronousExecutionMiddleware()])

return _default_executor


def set_default_executor(executor):
"""
Sets the default executor to be used in the `execute` function above.

If passed `None` will reset to the original default synchronous executor.
"""
assert isinstance(executor, Executor) or executor is None
global _default_executor
_default_executor = executor

return _execute(schema, ast, root, variable_values=args, operation_name=operation_name)

__all__ = ['ExecutionResult', 'Executor', 'execute', 'get_default_executor', 'set_default_executor']
__all__ = ['execute', 'ExecutionResult']
62 changes: 19 additions & 43 deletions graphql/execution/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from ..error import GraphQLError
from ..language import ast
from ..pyutils.defer import DeferredException
from ..type.definition import GraphQLInterfaceType, GraphQLUnionType
from ..type.directives import GraphQLIncludeDirective, GraphQLSkipDirective
from ..type.introspection import (SchemaMetaFieldDef, TypeMetaFieldDef,
Expand All @@ -18,10 +17,10 @@ class ExecutionContext(object):
Namely, schema of the type system that is currently executing,
and the fragments defined in the query document"""

__slots__ = 'schema', 'fragments', 'root', 'operation', 'variables', 'errors', 'request_context', \
'argument_values_cache'
__slots__ = 'schema', 'fragments', 'root_value', 'operation', 'variable_values', 'errors', 'context_value', \
'argument_values_cache', 'executor'

def __init__(self, schema, root, document_ast, operation_name, args, request_context):
def __init__(self, schema, document_ast, root_value, context_value, variable_values, operation_name, executor):
"""Constructs a ExecutionContext object from the arguments passed
to execute, which we will pass throughout the other execution
methods."""
Expand Down Expand Up @@ -53,24 +52,25 @@ def __init__(self, schema, root, document_ast, operation_name, args, request_con
else:
raise GraphQLError('Must provide an operation.')

variables = get_variable_values(schema, operation.variable_definitions or [], args)
variable_values = get_variable_values(schema, operation.variable_definitions or [], variable_values)

self.schema = schema
self.fragments = fragments
self.root = root
self.root_value = root_value
self.operation = operation
self.variables = variables
self.variable_values = variable_values
self.errors = errors
self.request_context = request_context
self.context_value = context_value
self.argument_values_cache = {}
self.executor = executor

def get_argument_values(self, field_def, field_ast):
k = field_def, field_ast
result = self.argument_values_cache.get(k)

if not result:
result = self.argument_values_cache[k] = get_argument_values(field_def.args, field_ast.arguments,
self.variables)
self.variable_values)

return result

Expand All @@ -84,12 +84,6 @@ class ExecutionResult(object):

def __init__(self, data=None, errors=None, invalid=False):
self.data = data
if errors:
errors = [
error.value if isinstance(error, DeferredException) else error
for error in errors
]

self.errors = errors

if invalid:
Expand Down Expand Up @@ -190,6 +184,7 @@ def collect_fields(ctx, runtime_type, selection_set, fields, prev_fragment_names
def should_include_node(ctx, directives):
"""Determines if a field should be included based on the @include and
@skip directives, where @skip has higher precidence than @include."""
# TODO: Refactor based on latest code
if directives:
skip_ast = None

Expand All @@ -202,7 +197,7 @@ def should_include_node(ctx, directives):
args = get_argument_values(
GraphQLSkipDirective.args,
skip_ast.arguments,
ctx.variables,
ctx.variable_values,
)
return not args.get('if')

Expand All @@ -217,7 +212,7 @@ def should_include_node(ctx, directives):
args = get_argument_values(
GraphQLIncludeDirective.args,
include_ast.arguments,
ctx.variables,
ctx.variable_values,
)

return bool(args.get('if'))
Expand Down Expand Up @@ -249,36 +244,17 @@ def get_field_entry_key(node):

class ResolveInfo(object):

def __init__(self, field_name, field_asts, return_type, parent_type, context):
def __init__(self, field_name, field_asts, return_type, parent_type,
schema, fragments, root_value, operation, variable_values):
self.field_name = field_name
self.field_asts = field_asts
self.return_type = return_type
self.parent_type = parent_type
self.context = context

@property
def schema(self):
return self.context.schema

@property
def fragments(self):
return self.context.fragments

@property
def root_value(self):
return self.context.root

@property
def operation(self):
return self.context.operation

@property
def variable_values(self):
return self.context.variables

@property
def request_context(self):
return self.context.request_context
self.schema = schema
self.fragments = fragments
self.root_value = root_value
self.operation = operation
self.variable_values = variable_values


def default_resolve_fn(source, args, info):
Expand Down
Loading