Skip to content

Commit c3b08e1

Browse files
committed
Refactored promise code
1 parent 0844623 commit c3b08e1

File tree

1 file changed

+47
-67
lines changed

1 file changed

+47
-67
lines changed

graphql/pyutils/aplus.py

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ def fulfill(self, x):
8989

9090
if self is x:
9191
raise TypeError("Cannot resolve promise with itself.")
92-
elif _isPromise(x):
92+
elif is_thenable(x):
9393
try:
94-
_promisify(x).done(self.fulfill, self.reject)
94+
promisify(x).done(self.fulfill, self.reject)
9595
except Exception as e:
9696
self.reject(e)
9797
else:
@@ -159,17 +159,17 @@ def reject(self, reason):
159159
pass
160160

161161
@property
162-
def isPending(self):
162+
def is_pending(self):
163163
"""Indicate whether the Promise is still pending. Could be wrong the moment the function returns."""
164164
return self._state == self.PENDING
165165

166166
@property
167-
def isFulfilled(self):
167+
def is_fulfilled(self):
168168
"""Indicate whether the Promise has been fulfilled. Could be wrong the moment the function returns."""
169169
return self._state == self.FULFILLED
170170

171171
@property
172-
def isRejected(self):
172+
def is_rejected(self):
173173
"""Indicate whether the Promise has been rejected. Could be wrong the moment the function returns."""
174174
return self._state == self.REJECTED
175175

@@ -200,13 +200,13 @@ def wait(self, timeout=None):
200200
"""
201201
self._event.wait(timeout)
202202

203-
def addCallback(self, f):
203+
def add_callback(self, f):
204204
"""
205205
Add a callback for when this promis is fulfilled. Note that
206206
if you intend to use the value of the promise somehow in
207207
the callback, it is more convenient to use the 'then' method.
208208
"""
209-
assert _isFunction(f)
209+
assert _is_function(f)
210210

211211
with self._cb_lock:
212212
if self._state == self.PENDING:
@@ -221,14 +221,14 @@ def addCallback(self, f):
221221
else:
222222
pass
223223

224-
def addErrback(self, f):
224+
def add_errback(self, f):
225225
"""
226226
Add a callback for when this promis is rejected. Note that
227227
if you intend to use the rejection reason of the promise
228228
somehow in the callback, it is more convenient to use
229229
the 'then' method.
230230
"""
231-
assert _isFunction(f)
231+
assert _is_function(f)
232232

233233
with self._cb_lock:
234234
if self._state == self.PENDING:
@@ -256,9 +256,9 @@ def done(self, success=None, failure=None):
256256
"""
257257
with self._cb_lock:
258258
if success is not None:
259-
self.addCallback(success)
259+
self.add_callback(success)
260260
if failure is not None:
261-
self.addErrback(failure)
261+
self.add_errback(failure)
262262

263263
def done_all(self, *handlers):
264264
"""
@@ -311,33 +311,33 @@ def then(self, success=None, failure=None):
311311
"""
312312
ret = Promise()
313313

314-
def callAndFulfill(v):
314+
def call_and_fulfill(v):
315315
"""
316316
A callback to be invoked if the "self promise"
317317
is fulfilled.
318318
"""
319319
try:
320-
if _isFunction(success):
320+
if _is_function(success):
321321
ret.fulfill(success(v))
322322
else:
323323
ret.fulfill(v)
324324
except Exception as e:
325325
ret.reject(e)
326326

327-
def callAndReject(r):
327+
def call_and_reject(r):
328328
"""
329329
A callback to be invoked if the "self promise"
330330
is rejected.
331331
"""
332332
try:
333-
if _isFunction(failure):
333+
if _is_function(failure):
334334
ret.fulfill(failure(r))
335335
else:
336336
ret.reject(r)
337337
except Exception as e:
338338
ret.reject(e)
339339

340-
self.done(callAndFulfill, callAndReject)
340+
self.done(call_and_fulfill, call_and_reject)
341341

342342
return ret
343343

@@ -374,74 +374,65 @@ def then_all(self, *handlers):
374374

375375
@staticmethod
376376
def all(values_or_promises):
377-
return listPromise(values_or_promises)
377+
"""
378+
A special function that takes a bunch of promises
379+
and turns them into a promise for a vector of values.
380+
In other words, this turns an list of promises for values
381+
into a promise for a list of values.
382+
"""
383+
promises = list(filter(is_thenable, values_or_promises))
384+
if len(promises) == 0:
385+
# All the values or promises are resolved
386+
return Promise.fulfilled(values_or_promises)
387+
388+
all_promise = Promise()
389+
counter = CountdownLatch(len(promises))
390+
391+
def handleSuccess(_):
392+
if counter.dec() == 0:
393+
values = list(map(lambda p: p.value if p in promises else p, values_or_promises))
394+
all_promise.fulfill(values)
395+
396+
for p in promises:
397+
promisify(p).done(handleSuccess, all_promise.reject)
398+
399+
return all_promise
378400

379401

380-
def _isFunction(v):
402+
def _is_function(v):
381403
"""
382404
A utility function to determine if the specified
383405
value is a function.
384406
"""
385407
return v is not None and hasattr(v, "__call__")
386408

387409

388-
def _isPromise(obj):
410+
def is_thenable(obj):
389411
"""
390412
A utility function to determine if the specified
391413
object is a promise using "duck typing".
392414
"""
393415
return isinstance(obj, Promise) or (
394-
hasattr(obj, "done") and _isFunction(getattr(obj, "done"))) or (
395-
hasattr(obj, "then") and _isFunction(getattr(obj, "then")))
416+
hasattr(obj, "done") and _is_function(getattr(obj, "done"))) or (
417+
hasattr(obj, "then") and _is_function(getattr(obj, "then")))
396418

397419

398-
is_thenable = _isPromise
399-
400-
401-
def _promisify(obj):
420+
def promisify(obj):
402421
if isinstance(obj, Promise):
403422
return obj
404-
elif hasattr(obj, "done") and _isFunction(getattr(obj, "done")):
423+
elif hasattr(obj, "done") and _is_function(getattr(obj, "done")):
405424
p = Promise()
406425
obj.done(p.fulfill, p.reject)
407426
return p
408-
elif hasattr(obj, "then") and _isFunction(getattr(obj, "then")):
427+
elif hasattr(obj, "then") and _is_function(getattr(obj, "then")):
409428
p = Promise()
410429
obj.then(p.fulfill, p.reject)
411430
return p
412431
else:
413432
raise TypeError("Object is not a Promise like object.")
414433

415-
promisify = _promisify
416-
417434

418-
def listPromise(values_or_promises):
419-
"""
420-
A special function that takes a bunch of promises
421-
and turns them into a promise for a vector of values.
422-
In other words, this turns an list of promises for values
423-
into a promise for a list of values.
424-
"""
425-
promises = list(filter(_isPromise, values_or_promises))
426-
if len(promises) == 0:
427-
# All the values or promises are resolved
428-
return Promise.fulfilled(values_or_promises)
429-
430-
ret = Promise()
431-
counter = CountdownLatch(len(promises))
432-
433-
def handleSuccess(_):
434-
if counter.dec() == 0:
435-
values = list(map(lambda p: p.value if p in promises else p, values_or_promises))
436-
ret.fulfill(values)
437-
438-
for p in promises:
439-
_promisify(p).done(handleSuccess, ret.reject)
440-
441-
return ret
442-
443-
444-
def dictPromise(m):
435+
def promise_for_dict(m):
445436
"""
446437
A special function that takes a dictionary of promises
447438
and turns them into a promise for a dictionary of values.
@@ -458,14 +449,3 @@ def handleSuccess(resolved_values):
458449
return dict_type(zip(keys, resolved_values))
459450

460451
return Promise.all(values).then(handleSuccess)
461-
462-
463-
promise_for_dict = dictPromise
464-
465-
466-
def _process(p, f):
467-
try:
468-
val = f()
469-
p.fulfill(val)
470-
except Exception as e:
471-
p.reject(e)

0 commit comments

Comments
 (0)