Skip to content

Commit 02b231a

Browse files
author
Daniel Gallagher
committed
Merge branch 'master' of github.com:dan98765/graphql-core into travis_uses_tox
2 parents 6448e34 + 4d2f7e7 commit 02b231a

File tree

6 files changed

+42
-30
lines changed

6 files changed

+42
-30
lines changed

graphql/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@
205205
set_default_backend,
206206
)
207207

208-
VERSION = (2, 1, 0, 'rc', 1)
208+
VERSION = (2, 1, 0, 'rc', 2)
209209
__version__ = get_version(VERSION)
210210

211211

graphql/backend/quiver_cloud.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
"You can install it using: pip install requests"
77
)
88

9-
from six import urlparse
10-
119
from ..utils.schema_printer import print_schema
1210
from .base import GraphQLBackend
1311
from .compiled import GraphQLCompiledDocument
1412

13+
from six.moves.urllib.parse import urlparse
14+
1515

1616
GRAPHQL_QUERY = """
1717
mutation($schemaDsl: String!, $query: String!) {

graphql/execution/base.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
# We keep the following imports to preserve compatibility
2-
from .utils import (ExecutionContext, SubscriberExecutionContext,
3-
collect_fields, default_resolve_fn,
4-
does_fragment_condition_match, get_field_def,
5-
get_field_entry_key, get_operation_root_type,
6-
should_include_node)
2+
from .utils import (
3+
ExecutionContext,
4+
SubscriberExecutionContext,
5+
get_operation_root_type,
6+
collect_fields,
7+
should_include_node,
8+
does_fragment_condition_match,
9+
get_field_entry_key,
10+
default_resolve_fn,
11+
get_field_def
12+
)
13+
from ..error.format_error import format_error as default_format_error
714

815

916
class ExecutionResult(object):
@@ -33,6 +40,19 @@ def __eq__(self, other):
3340
)
3441
)
3542

43+
def to_dict(self, format_error=None, dict_class=dict):
44+
if format_error is None:
45+
format_error = default_format_error
46+
47+
response = dict_class()
48+
if self.errors:
49+
response['errors'] = [format_error(e) for e in self.errors]
50+
51+
if not self.invalid:
52+
response['data'] = self.data
53+
54+
return response
55+
3656

3757
class ResolveInfo(object):
3858
__slots__ = ('field_name', 'field_asts', 'return_type', 'parent_type',

graphql/execution/executors/asyncio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ def execute(self, fn, *args, **kwargs):
6262
self.futures.append(future)
6363
return Promise.resolve(future)
6464
elif isasyncgen(result):
65-
return asyncgen_to_observable(result)
65+
return asyncgen_to_observable(result, loop=self.loop)
6666
return result

graphql/execution/executors/asyncio_utils.py

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from asyncio import ensure_future
1+
from asyncio import ensure_future, wait, CancelledError
22
from inspect import isasyncgen
33

44
from rx import AnonymousObserver, Observable
@@ -7,6 +7,7 @@
77
ObserverBase)
88
from rx.core.anonymousobserver import AnonymousObserver
99
from rx.core.autodetachobserver import AutoDetachObserver
10+
from rx import AnonymousObservable
1011

1112

1213
# class AsyncgenDisposable(Disposable):
@@ -102,33 +103,24 @@ def set_disposable(scheduler=None, value=None):
102103
else:
103104
auto_detach_observer.disposable = fix_subscriber(subscriber)
104105

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

118-
# Hide the identity of the auto detach observer
119-
return Disposable.create(auto_detach_observer.dispose)
110+
task.cancel()
111+
ensure_future(await_task(), loop=loop)
120112

113+
return dispose
121114

122-
def asyncgen_to_observable(asyncgen):
123-
def emit(observer):
124-
ensure_future(iterate_asyncgen(asyncgen, observer))
125-
return AsyncgenObservable(emit, asyncgen)
115+
return AnonymousObservable(emit)
126116

127117

128118
async def iterate_asyncgen(asyncgen, observer):
129119
try:
130120
async for item in asyncgen:
131121
observer.on_next(item)
132122
observer.on_completed()
123+
except CancelledError:
124+
pass
133125
except Exception as e:
134126
observer.on_error(e)

graphql/execution/middleware.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
class MiddlewareManager(object):
1111
__slots__ = "middlewares", "wrap_in_promise", "_middleware_resolvers", "_cached_resolvers"
1212

13-
def __init__(self, *middlewares, wrap_in_promise=True):
13+
def __init__(self, *middlewares, **kwargs):
1414
self.middlewares = middlewares
15-
self.wrap_in_promise = wrap_in_promise
15+
self.wrap_in_promise = kwargs.get('wrap_in_promise', True)
1616
self._middleware_resolvers = list(get_middleware_resolvers(middlewares)) if middlewares else []
1717
self._cached_resolvers = {}
1818

0 commit comments

Comments
 (0)