This is a implementation of Promises in Python. It is a super set of Promises/A+ designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises in Python.
Its fully compatible with the Promises/A+ spec
$ pip install promise
The example below shows how you can load the promise library. It then
demonstrates creating a promise from scratch. You simply call
Promise(fn)
. There is a complete specification for what is returned
by this method in
Promises/A+.
from promise import Promise
promise = Promise(
lambda resolve, reject: resolve('RESOLVED!')
)
Before all examples, you will need:
from promise import Promise
This creates and returns a new promise. resolver
must be a function.
The resolver
function is passed two arguments:
resolve
should be called with a single argument. If it is called with a non-promise value then the promise is fulfilled with that value. If it is called with a promise (A) then the returned promise takes on the state of that new promise (A).reject
should be called with a single argument. The returned promise will be rejected with that argument.
These methods are invoked by calling Promise.methodName
.
Converts values and foreign promises into Promises/A+ promises. If you
pass it a value then it returns a Promise for that value. If you pass it
something that is close to a promise (such as a jQuery attempt at a
promise) it returns a Promise that takes on the state of value
(rejected or fulfilled).
Returns a rejected promise with the given value.
Returns a promise for a list. If it is called with a single argument then this returns a promise for a copy of that list with any promises replaced by their fulfilled values. e.g.
p = Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')]) \
.then(lambda res: res == ['a', 'b', 'c'])
assert p.get() is True
This function wraps the obj
act as a Promise
if possible. Python
Future
s are supported, with a callback to promise.done
when
resolved. Have the same effects as Promise.resolve(obj)
.
A special function that takes a dictionary of promises and turns them into a promise for a dictionary of values. In other words, this turns an dictionary of promises for values into a promise for a dictionary of values.
This function checks if the obj
is a Promise
, or could be
cast
ed.
This function wraps the result of calling func
in a Promise
instance.
These methods are invoked on a promise instance by calling
myPromise.methodName
This method follows the Promises/A+ spec. It explains things very clearly so I recommend you read it.
Either did_fulfill
or did_reject
will be called and they will
not be called more than once. They will be passed a single argument and
will always be called asynchronously (in the next turn of the event
loop).
If the promise is fulfilled then did_fulfill
is called. If the
promise is rejected then did_reject
is called.
The call to .then
also returns a promise. If the handler that is
called returns a promise, the promise returned by .then
takes on the
state of that returned promise. If the handler that is called returns a
value that is not a promise, the promise returned by .then
will be
fulfilled with that value. If the handler that is called throws an
exception then the promise returned by .then
is rejected with that
exception.
Sugar for promise.then(None, did_reject)
, to mirror catch
in
synchronous code.
The same semantics as .then
except that it does not return a promise
and any exceptions are re-thrown so that they can be logged (crashing
the application in non-browser environments)
After cloning this repo, ensure dependencies are installed by running:
pip install -e ".[test]"
After developing, the full test suite can be evaluated by running:
py.test tests --cov=promise --benchmark-skip # Use -v -s for verbose mode
You can also run the benchmarks with:
py.test tests --benchmark-only
Python type annotations are very useful for making sure we use the libary the way is intended.
You can run mypy
static type checker:
pip install mypy
mypy promise --ignore-missing-imports
Or pyre
:
pip install pyre-check
pyre --source-directory promise check
This package is heavily insipired in aplus.