File: README.md

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 (160 lines) | stat: -rw-r--r-- 5,703 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
# 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][travis-image]][travis-url]
[![pypi][pypi-image]][pypi-url]
[![coveralls][coveralls-image]][coveralls-url]

[travis-image]: https://img.shields.io/travis/syrusakbary/promise.svg?style=flat
[travis-url]: https://travis-ci.org/syrusakbary/promise
[pypi-image]: https://img.shields.io/pypi/v/promise.svg?style=flat
[pypi-url]: https://pypi.python.org/pypi/promise
[coveralls-image]: https://coveralls.io/repos/syrusakbary/promise/badge.svg?branch=master&service=github
[coveralls-url]: https://coveralls.io/github/syrusakbary/promise?branch=master

## 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/).

```python
from promise import Promise

promise = Promise(
    lambda resolve, reject: resolve('RESOLVED!')
)
```

## API

Before all examples, you will need:

```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.

```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` ect as a `Promise` if possible.
Python `Future`s are supported, with a callback to `promise.done` when resolved.
Has 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
a 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:

```sh
pip install -e ".[test]"
```

After developing, the full test suite can be evaluated by running:

```sh
py.test tests --cov=promise --benchmark-skip # Use -v -s for verbose mode
```

You can also run the benchmarks with:

```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:

```sh
pip install mypy
mypy promise  --ignore-missing-imports
```

Or `pyre`:

```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)