File: README.rst

package info (click to toggle)
python-promise 2.3.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 400 kB
  • sloc: python: 2,681; sh: 13; makefile: 4
file content (220 lines) | stat: -rw-r--r-- 6,120 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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 <http://promises-aplus.github.io/promises-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+ <http://promises-aplus.github.com/promises-spec/>`__.

.. 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 <http://promises-aplus.github.io/promises-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 <https://github.com/xogeny/aplus>`__.

License
-------

`MIT
License <https://github.com/syrusakbary/promise/blob/master/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