Skip to content

Commit 6d7b68c

Browse files
committed
Improved Promise.all() to accept non-promise items
1 parent f811dc9 commit 6d7b68c

File tree

3 files changed

+22
-53
lines changed

3 files changed

+22
-53
lines changed

graphql/execution/execute.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ def executor(resolve, reject):
3636
return resolve(execute_operation(context, context.operation, root_value))
3737

3838
def on_rejected(error):
39-
# print "ON=REJECTED", error
4039
context.errors.append(error)
4140
return None
4241

4342
def on_resolve(data):
44-
# print "ON=RESOLVE", data
4543
return ExecutionResult(data=data, errors=context.errors)
4644

4745
return Promise(executor).catch(on_rejected).then(on_resolve).value
@@ -133,7 +131,7 @@ def execute_fields(exe_context, parent_type, source_value, fields):
133131
if not contains_promise:
134132
return final_results
135133

136-
return promise_for_dict(final_results, collections.OrderedDict)
134+
return promise_for_dict(final_results)
137135

138136

139137
def resolve_field(exe_context, parent_type, source, field_asts):
@@ -195,17 +193,14 @@ def complete_value_catching_error(exe_context, return_type, field_asts, info, re
195193
try:
196194
completed = complete_value(exe_context, return_type, field_asts, info, result)
197195
if is_thenable(completed):
198-
# TODO: Check if is None or Undefined
199196
def handle_error(error):
200-
# print "HANDLE=ERROR", error
201197
exe_context.errors.append(error)
202-
return Promise.resolved(None)
198+
return Promise.fulfilled(None)
203199

204200
return promisify(completed).then(None, handle_error)
205201

206202
return completed
207203
except Exception as e:
208-
# print "GENERAL=EXCEPTION", e
209204
exe_context.errors.append(e)
210205
return None
211206

@@ -232,15 +227,15 @@ def complete_value(exe_context, return_type, field_asts, info, result):
232227
# If field type is NonNull, complete for inner type, and throw field error if result is null.
233228

234229
if is_thenable(result):
235-
promisify(result).then(
230+
return promisify(result).then(
236231
lambda resolved: complete_value(
237232
exe_context,
238233
return_type,
239234
field_asts,
240235
info,
241236
resolved
242237
),
243-
lambda error: Promise.rejected(GraphQLError(error.value and str(error.value), field_asts, error))
238+
lambda error: Promise.rejected(GraphQLError(error and str(error), field_asts, error))
244239
)
245240

246241
if isinstance(result, Exception):

graphql/execution/tests/test_lists.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from graphql.error import format_error
44
from graphql.execution import execute
55
from graphql.language.parser import parse
6-
from graphql.pyutils.aplus import Promisex
6+
from graphql.pyutils.aplus import Promise
77
from graphql.type import (GraphQLField, GraphQLInt, GraphQLList,
88
GraphQLNonNull, GraphQLObjectType, GraphQLSchema)
99

graphql/pyutils/aplus.py

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,19 @@ def __init__(self, fn=None):
5353
def do_resolve(self, fn):
5454
self._done = False
5555
def resolve_fn(x):
56-
print 'RESOLVE FN', x
5756
if self._done:
5857
return
5958
self._done = True
6059
self.fulfill(x)
6160
def reject_fn(x):
62-
print 'REJECT FN', x
6361
if self._done:
6462
return
6563
self._done = True
6664
self.reject(x)
67-
res = None
68-
err = None
6965
try:
70-
print 'TRY DO RES'
71-
res = fn(resolve_fn, reject_fn)
72-
print 'DO RES', res
66+
fn(resolve_fn, reject_fn)
7367
except Exception, e:
74-
err = e
75-
if not res and err:
76-
print "ERR", err
77-
self.reject(err)
68+
self.reject(e)
7869

7970
@staticmethod
8071
def fulfilled(x):
@@ -379,8 +370,8 @@ def then_all(self, *handlers):
379370
return promises
380371

381372
@staticmethod
382-
def all(*promises):
383-
return listPromise(*promises)
373+
def all(values_or_promises):
374+
return listPromise(values_or_promises)
384375

385376

386377
def _isFunction(v):
@@ -420,66 +411,49 @@ def _promisify(obj):
420411

421412
promisify = _promisify
422413

423-
def listPromise(*promises):
414+
def listPromise(values_or_promises):
424415
"""
425416
A special function that takes a bunch of promises
426417
and turns them into a promise for a vector of values.
427418
In other words, this turns an list of promises for values
428419
into a promise for a list of values.
429420
"""
430-
if len(promises) == 1 and isinstance(promises[0], list):
431-
promises = promises[0]
432-
421+
promises=filter(_isPromise, values_or_promises)
433422
if len(promises) == 0:
434-
return Promise.fulfilled([])
423+
# All the values or promises are resolved
424+
return Promise.fulfilled(values_or_promises)
435425

436426
ret = Promise()
437427
counter = CountdownLatch(len(promises))
438428

439429
def handleSuccess(_):
440430
if counter.dec() == 0:
441-
value = list(map(lambda p: p.value, promises))
442-
ret.fulfill(value)
431+
values = list(map(lambda p: p.value if p in promises else p, values_or_promises))
432+
ret.fulfill(values)
443433

444434
for p in promises:
445-
assert _isPromise(p)
446-
447435
_promisify(p).done(handleSuccess, ret.reject)
448436

449437
return ret
450438

451439

452-
def dictPromise(m, dict_type=None):
440+
def dictPromise(m):
453441
"""
454442
A special function that takes a dictionary of promises
455443
and turns them into a promise for a dictionary of values.
456444
In other words, this turns an dictionary of promises for values
457445
into a promise for a dictionary of values.
458446
"""
459-
if len(m) == 0:
447+
if not m:
460448
return Promise.fulfilled({})
461449

462-
ret = Promise()
463-
counter = CountdownLatch(len(m))
464-
465-
if not dict_type:
466-
dict_type = dict
467-
468-
def handleSuccess(_):
469-
if counter.dec() == 0:
470-
value = dict_type()
471-
472-
for k in m:
473-
value[k] = m[k].value
474-
475-
ret.fulfill(value)
450+
keys, values = zip(*m.items())
451+
dict_type = type(m)
476452

477-
for p in m.values():
478-
assert _isPromise(p)
453+
def handleSuccess(values):
454+
return dict_type(zip(keys, values))
479455

480-
_promisify(p).done(handleSuccess, ret.reject)
481-
482-
return ret
456+
return Promise.all(values).then(handleSuccess)
483457

484458

485459
promise_for_dict = dictPromise

0 commit comments

Comments
 (0)