Skip to content

Commit

Permalink
Merge branch 'master' of github.com:dan98765/graphql-core into travis…
Browse files Browse the repository at this point in the history
…_uses_tox
  • Loading branch information
Daniel Gallagher committed Jun 23, 2018
2 parents 6448e34 + 4d2f7e7 commit 02b231a
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 30 deletions.
2 changes: 1 addition & 1 deletion graphql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@
set_default_backend,
)

VERSION = (2, 1, 0, 'rc', 1)
VERSION = (2, 1, 0, 'rc', 2)
__version__ = get_version(VERSION)


Expand Down
4 changes: 2 additions & 2 deletions graphql/backend/quiver_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"You can install it using: pip install requests"
)

from six import urlparse

from ..utils.schema_printer import print_schema
from .base import GraphQLBackend
from .compiled import GraphQLCompiledDocument

from six.moves.urllib.parse import urlparse


GRAPHQL_QUERY = """
mutation($schemaDsl: String!, $query: String!) {
Expand Down
30 changes: 25 additions & 5 deletions graphql/execution/base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# We keep the following imports to preserve compatibility
from .utils import (ExecutionContext, SubscriberExecutionContext,
collect_fields, default_resolve_fn,
does_fragment_condition_match, get_field_def,
get_field_entry_key, get_operation_root_type,
should_include_node)
from .utils import (
ExecutionContext,
SubscriberExecutionContext,
get_operation_root_type,
collect_fields,
should_include_node,
does_fragment_condition_match,
get_field_entry_key,
default_resolve_fn,
get_field_def
)
from ..error.format_error import format_error as default_format_error


class ExecutionResult(object):
Expand Down Expand Up @@ -33,6 +40,19 @@ def __eq__(self, other):
)
)

def to_dict(self, format_error=None, dict_class=dict):
if format_error is None:
format_error = default_format_error

response = dict_class()
if self.errors:
response['errors'] = [format_error(e) for e in self.errors]

if not self.invalid:
response['data'] = self.data

return response


class ResolveInfo(object):
__slots__ = ('field_name', 'field_asts', 'return_type', 'parent_type',
Expand Down
2 changes: 1 addition & 1 deletion graphql/execution/executors/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ def execute(self, fn, *args, **kwargs):
self.futures.append(future)
return Promise.resolve(future)
elif isasyncgen(result):
return asyncgen_to_observable(result)
return asyncgen_to_observable(result, loop=self.loop)
return result
30 changes: 11 additions & 19 deletions graphql/execution/executors/asyncio_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from asyncio import ensure_future
from asyncio import ensure_future, wait, CancelledError
from inspect import isasyncgen

from rx import AnonymousObserver, Observable
Expand All @@ -7,6 +7,7 @@
ObserverBase)
from rx.core.anonymousobserver import AnonymousObserver
from rx.core.autodetachobserver import AutoDetachObserver
from rx import AnonymousObservable


# class AsyncgenDisposable(Disposable):
Expand Down Expand Up @@ -102,33 +103,24 @@ def set_disposable(scheduler=None, value=None):
else:
auto_detach_observer.disposable = fix_subscriber(subscriber)

# Subscribe needs to set up the trampoline before for subscribing.
# Actually, the first call to Subscribe creates the trampoline so
# that it may assign its disposable before any observer executes
# OnNext over the CurrentThreadScheduler. This enables single-
# threaded cancellation
# https://social.msdn.microsoft.com/Forums/en-US/eb82f593-9684-4e27-
# 97b9-8b8886da5c33/whats-the-rationale-behind-how-currentthreadsche
# dulerschedulerequired-behaves?forum=rx
if current_thread_scheduler.schedule_required():
current_thread_scheduler.schedule(set_disposable)
else:
set_disposable()
def dispose():
async def await_task():
await task

# Hide the identity of the auto detach observer
return Disposable.create(auto_detach_observer.dispose)
task.cancel()
ensure_future(await_task(), loop=loop)

return dispose

def asyncgen_to_observable(asyncgen):
def emit(observer):
ensure_future(iterate_asyncgen(asyncgen, observer))
return AsyncgenObservable(emit, asyncgen)
return AnonymousObservable(emit)


async def iterate_asyncgen(asyncgen, observer):
try:
async for item in asyncgen:
observer.on_next(item)
observer.on_completed()
except CancelledError:
pass
except Exception as e:
observer.on_error(e)
4 changes: 2 additions & 2 deletions graphql/execution/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
class MiddlewareManager(object):
__slots__ = "middlewares", "wrap_in_promise", "_middleware_resolvers", "_cached_resolvers"

def __init__(self, *middlewares, wrap_in_promise=True):
def __init__(self, *middlewares, **kwargs):
self.middlewares = middlewares
self.wrap_in_promise = wrap_in_promise
self.wrap_in_promise = kwargs.get('wrap_in_promise', True)
self._middleware_resolvers = list(get_middleware_resolvers(middlewares)) if middlewares else []
self._cached_resolvers = {}

Expand Down

0 comments on commit 02b231a

Please sign in to comment.