Metadata-Version: 2.2
Name: promise
Version: 2.3
Summary: Promises/A+ implementation for Python
Home-page: https://github.com/syrusakbary/promise
Download-URL: https://github.com/syrusakbary/promise/releases
Author: Syrus Akbary
Author-email: me@syrusakbary.com
License: MIT
Keywords: concurrent future deferred promise
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: License :: OSI Approved :: MIT License
License-File: LICENSE
Requires-Dist: typing>=3.6.4; python_version < "3.5"
Requires-Dist: six
Provides-Extra: test
Requires-Dist: pytest>=2.7.3; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: coveralls; extra == "test"
Requires-Dist: futures; extra == "test"
Requires-Dist: pytest-benchmark; extra == "test"
Requires-Dist: mock; extra == "test"
Requires-Dist: pytest-asyncio; extra == "test"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: download-url
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: summary
Promise
=======
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 `__
|travis| |pypi| |coveralls|
Installation
------------
::
$ pip install promise
Usage
-----
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+ `__.
.. code:: python
from promise import Promise
promise = Promise(
lambda resolve, reject: resolve('RESOLVED!')
)
API
---
Before all examples, you will need:
.. code:: python
from promise import Promise
Promise(resolver)
~~~~~~~~~~~~~~~~~
This creates and returns a new promise. ``resolver`` must be a function.
The ``resolver`` function is passed two arguments:
1. ``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).
2. ``reject`` should be called with a single argument. The returned
promise will be rejected with that argument.
Class Methods
~~~~~~~~~~~~~
These methods are invoked by calling ``Promise.methodName``.
Promise.resolve(value)
^^^^^^^^^^^^^^^^^^^^^^
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).
Promise.reject(value)
^^^^^^^^^^^^^^^^^^^^^
Returns a rejected promise with the given value.
Promise.all(list)
^^^^^^^^^^^^^^^^^
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.
.. code:: python
p = Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')]) \
.then(lambda res: res == ['a', 'b', 'c'])
assert p.get() is True
Promise.cast(obj)
^^^^^^^^^^^^^^^^^
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)``.
Promise.for\_dict(d)
^^^^^^^^^^^^^^^^^^^^
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.
Promise.is\_thenable(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^
This function checks if the ``obj`` is a ``Promise``, or could be
``cast``\ ed.
Promise.promisify(func)
^^^^^^^^^^^^^^^^^^^^^^^
This function wraps the result of calling ``func`` in a ``Promise``
instance.
Instance Methods
~~~~~~~~~~~~~~~~
These methods are invoked on a promise instance by calling
``myPromise.methodName``
promise.then(did\_fulfill, did\_reject)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
promise.catch(did\_reject)
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sugar for ``promise.then(None, did_reject)``, to mirror ``catch`` in
synchronous code.
promise.done(did\_fulfill, did\_reject)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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)
Contributing
============
After cloning this repo, ensure dependencies are installed by running:
.. code:: sh
pip install -e ".[test]"
After developing, the full test suite can be evaluated by running:
.. code:: sh
py.test tests --cov=promise --benchmark-skip # Use -v -s for verbose mode
You can also run the benchmarks with:
.. code:: sh
py.test tests --benchmark-only
Static type checking
--------------------
Python type annotations are very useful for making sure we use the
libary the way is intended.
You can run ``mypy`` static type checker:
.. code:: sh
pip install mypy
mypy promise --ignore-missing-imports
Or ``pyre``:
.. code:: sh
pip install pyre-check
pyre --source-directory promise check
Notes
=====
This package is heavily insipired in
`aplus `__.
License
-------
`MIT
License `__
.. |travis| image:: https://img.shields.io/travis/syrusakbary/promise.svg?style=flat
:target: https://travis-ci.org/syrusakbary/promise
.. |pypi| image:: https://img.shields.io/pypi/v/promise.svg?style=flat
:target: https://pypi.python.org/pypi/promise
.. |coveralls| image:: https://coveralls.io/repos/syrusakbary/promise/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/syrusakbary/promise?branch=master