Skip to content

Commit

Permalink
Improved PromiseList implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
syrusakbary committed Mar 4, 2017
1 parent 7bd1d67 commit 93fcf22
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
6 changes: 3 additions & 3 deletions promise/promise.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ def _try_convert_to_promise(cls, obj, context=None):
return obj

add_done_callback = get_done_callback(obj) # type: Optional[Callable]
if callable(add_done_callback):
if add_done_callback and callable(add_done_callback):
def executor(resolve, reject):
if obj.done():
_process_future_result(resolve, reject)(obj)
Expand All @@ -626,13 +626,13 @@ def executor(resolve, reject):
return promise

done = getattr(obj, "done", None) # type: Optional[Callable]
if callable(done):
if done and callable(done):
def executor(resolve, reject):
done(resolve, reject)
return cls(executor)

then = getattr(obj, "then", None) # type: Optional[Callable]
if callable(then):
if then and callable(then):
def executor(resolve, reject):
then(resolve, reject)
return cls(executor)
Expand Down
42 changes: 21 additions & 21 deletions promise/promise_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@


class PromiseList(object):

__slots__ = ('_values', '_length', '_total_resolved', 'promise')

def __init__(self, values):
promise = self._promise = Promise(internal_executor)
self.promise = Promise(internal_executor)
# if (isinstance(values, Promise)):
# # promise._propagate_from(values)
# pass
Expand All @@ -19,28 +22,25 @@ def __init__(self, values):
def __len__(self):
return self._length

def promise(self):
return self._promise

def _init(self):
values = Promise._try_convert_to_promise(self._values, self._promise)
values = Promise._try_convert_to_promise(self._values, self.promise)
if isinstance(values, Promise):
values = values._target()
if values.is_fulfilled:
values = values._value()
elif values.is_rejected:
self._reject(values._reason())
return self._reject(values._reason())
# Is pending
else:
self._promise._is_async_guaranteed = True
self.promise._is_async_guaranteed = True
return values._then(
self._init,
self._reject,
)

if not isinstance(values, Iterable):
err = Exception("Received non-iterable in for Promise list.")
self._promise._reject_callback(err, False)
self.promise._reject_callback(err, False)
return

if not values:
Expand All @@ -54,16 +54,16 @@ def _iterate(self, values):
self._length = len(values)
self._values = [ None ] * self._length

result = self._promise
result = self.promise

for i, val in enumerate(values):
maybe_promise = Promise._try_convert_to_promise(val, self._promise)
maybe_promise = Promise._try_convert_to_promise(val, self.promise)
if isinstance(maybe_promise, Promise):
maybe_promise = maybe_promise._target()
if is_resolved:
# maybe_promise.suppressUnhandledRejections
pass
elif maybe_promise.is_pending:
# if is_resolved:
# # maybe_promise.suppressUnhandledRejections
# pass
if maybe_promise.is_pending:
self._values[i] = maybe_promise
maybe_promise._add_callbacks(
partial(self._promise_fulfilled, i=i),
Expand All @@ -85,9 +85,9 @@ def _iterate(self, values):
result._is_async_guaranteed = True

def _promise_fulfilled(self, value, i):
assert not self.is_resolved
assert isinstance(self._values, Iterable)
assert isinstance(i, int)
# assert not self.is_resolved
# assert isinstance(self._values, Iterable)
# assert isinstance(i, int)
self._values[i] = value
self._total_resolved = self._total_resolved+1
if self._total_resolved >= self._length:
Expand All @@ -96,8 +96,8 @@ def _promise_fulfilled(self, value, i):
return False

def _promise_rejected(self, reason):
assert not self.is_resolved
assert isinstance(self._values, Iterable)
# assert not self.is_resolved
# assert isinstance(self._values, Iterable)
self._total_resolved = self._total_resolved+1
self._reject(reason)
return True
Expand All @@ -110,9 +110,9 @@ def _resolve(self, value):
assert not self.is_resolved
assert not isinstance(value, Promise)
self._values = None
self._promise._fulfill(value)
self.promise._fulfill(value)

def _reject(self, reason):
assert not self.is_resolved
self._values = None
self._promise._reject_callback(reason, False)
self.promise._reject_callback(reason, False)
4 changes: 2 additions & 2 deletions tests/test_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def create_promise(): # unnecessary function call


def test_benchmark_promise_all(benchmark):
values = range(10000)
values = range(1000)
def create_promise(): # unnecessary function call
return Promise.all(values)

Expand All @@ -72,7 +72,7 @@ def create_promise(): # unnecessary function call


def test_benchmark_promise_all_promise(benchmark):
values = [Promise.resolve(i) for i in range(10000)]
values = [Promise.resolve(i) for i in range(1000)]
def create_promise(): # unnecessary function call
return Promise.all(values)

Expand Down
3 changes: 2 additions & 1 deletion tests/test_promise_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
from promise import Promise
from promise.promise_list import PromiseList


def all(promises):
return PromiseList(promises).promise()
return PromiseList(promises).promise


def test_empty_promises():
Expand Down

0 comments on commit 93fcf22

Please sign in to comment.