METADATA 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. Metadata-Version: 2.2
  2. Name: promise
  3. Version: 2.3
  4. Summary: Promises/A+ implementation for Python
  5. Home-page: https://github.com/syrusakbary/promise
  6. Download-URL: https://github.com/syrusakbary/promise/releases
  7. Author: Syrus Akbary
  8. Author-email: me@syrusakbary.com
  9. License: MIT
  10. Keywords: concurrent future deferred promise
  11. Classifier: Development Status :: 5 - Production/Stable
  12. Classifier: Intended Audience :: Developers
  13. Classifier: Topic :: Software Development :: Libraries
  14. Classifier: Programming Language :: Python :: 2
  15. Classifier: Programming Language :: Python :: 2.7
  16. Classifier: Programming Language :: Python :: 3
  17. Classifier: Programming Language :: Python :: 3.3
  18. Classifier: Programming Language :: Python :: 3.4
  19. Classifier: Programming Language :: Python :: 3.5
  20. Classifier: Programming Language :: Python :: 3.6
  21. Classifier: Programming Language :: Python :: 3.7
  22. Classifier: Programming Language :: Python :: 3.8
  23. Classifier: Programming Language :: Python :: Implementation :: PyPy
  24. Classifier: License :: OSI Approved :: MIT License
  25. License-File: LICENSE
  26. Requires-Dist: typing>=3.6.4; python_version < "3.5"
  27. Requires-Dist: six
  28. Provides-Extra: test
  29. Requires-Dist: pytest>=2.7.3; extra == "test"
  30. Requires-Dist: pytest-cov; extra == "test"
  31. Requires-Dist: coveralls; extra == "test"
  32. Requires-Dist: futures; extra == "test"
  33. Requires-Dist: pytest-benchmark; extra == "test"
  34. Requires-Dist: mock; extra == "test"
  35. Requires-Dist: pytest-asyncio; extra == "test"
  36. Dynamic: author
  37. Dynamic: author-email
  38. Dynamic: classifier
  39. Dynamic: description
  40. Dynamic: download-url
  41. Dynamic: home-page
  42. Dynamic: keywords
  43. Dynamic: license
  44. Dynamic: provides-extra
  45. Dynamic: requires-dist
  46. Dynamic: summary
  47. Promise
  48. =======
  49. This is a implementation of Promises in Python. It is a super set of
  50. Promises/A+ designed to have readable, performant code and to provide
  51. just the extensions that are absolutely necessary for using promises in
  52. Python.
  53. Its fully compatible with the `Promises/A+
  54. spec <http://promises-aplus.github.io/promises-spec/>`__
  55. |travis| |pypi| |coveralls|
  56. Installation
  57. ------------
  58. ::
  59. $ pip install promise
  60. Usage
  61. -----
  62. The example below shows how you can load the promise library. It then
  63. demonstrates creating a promise from scratch. You simply call
  64. ``Promise(fn)``. There is a complete specification for what is returned
  65. by this method in
  66. `Promises/A+ <http://promises-aplus.github.com/promises-spec/>`__.
  67. .. code:: python
  68. from promise import Promise
  69. promise = Promise(
  70. lambda resolve, reject: resolve('RESOLVED!')
  71. )
  72. API
  73. ---
  74. Before all examples, you will need:
  75. .. code:: python
  76. from promise import Promise
  77. Promise(resolver)
  78. ~~~~~~~~~~~~~~~~~
  79. This creates and returns a new promise. ``resolver`` must be a function.
  80. The ``resolver`` function is passed two arguments:
  81. 1. ``resolve`` should be called with a single argument. If it is called
  82. with a non-promise value then the promise is fulfilled with that
  83. value. If it is called with a promise (A) then the returned promise
  84. takes on the state of that new promise (A).
  85. 2. ``reject`` should be called with a single argument. The returned
  86. promise will be rejected with that argument.
  87. Class Methods
  88. ~~~~~~~~~~~~~
  89. These methods are invoked by calling ``Promise.methodName``.
  90. Promise.resolve(value)
  91. ^^^^^^^^^^^^^^^^^^^^^^
  92. Converts values and foreign promises into Promises/A+ promises. If you
  93. pass it a value then it returns a Promise for that value. If you pass it
  94. something that is close to a promise (such as a jQuery attempt at a
  95. promise) it returns a Promise that takes on the state of ``value``
  96. (rejected or fulfilled).
  97. Promise.reject(value)
  98. ^^^^^^^^^^^^^^^^^^^^^
  99. Returns a rejected promise with the given value.
  100. Promise.all(list)
  101. ^^^^^^^^^^^^^^^^^
  102. Returns a promise for a list. If it is called with a single argument
  103. then this returns a promise for a copy of that list with any promises
  104. replaced by their fulfilled values. e.g.
  105. .. code:: python
  106. p = Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')]) \
  107. .then(lambda res: res == ['a', 'b', 'c'])
  108. assert p.get() is True
  109. Promise.cast(obj)
  110. ^^^^^^^^^^^^^^^^^
  111. This function wraps the ``obj`` act as a ``Promise`` if possible. Python
  112. ``Future``\ s are supported, with a callback to ``promise.done`` when
  113. resolved. Have the same effects as ``Promise.resolve(obj)``.
  114. Promise.for\_dict(d)
  115. ^^^^^^^^^^^^^^^^^^^^
  116. A special function that takes a dictionary of promises and turns them
  117. into a promise for a dictionary of values. In other words, this turns an
  118. dictionary of promises for values into a promise for a dictionary of
  119. values.
  120. Promise.is\_thenable(obj)
  121. ^^^^^^^^^^^^^^^^^^^^^^^^^
  122. This function checks if the ``obj`` is a ``Promise``, or could be
  123. ``cast``\ ed.
  124. Promise.promisify(func)
  125. ^^^^^^^^^^^^^^^^^^^^^^^
  126. This function wraps the result of calling ``func`` in a ``Promise``
  127. instance.
  128. Instance Methods
  129. ~~~~~~~~~~~~~~~~
  130. These methods are invoked on a promise instance by calling
  131. ``myPromise.methodName``
  132. promise.then(did\_fulfill, did\_reject)
  133. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  134. This method follows the `Promises/A+
  135. spec <http://promises-aplus.github.io/promises-spec/>`__. It explains
  136. things very clearly so I recommend you read it.
  137. Either ``did_fulfill`` or ``did_reject`` will be called and they will
  138. not be called more than once. They will be passed a single argument and
  139. will always be called asynchronously (in the next turn of the event
  140. loop).
  141. If the promise is fulfilled then ``did_fulfill`` is called. If the
  142. promise is rejected then ``did_reject`` is called.
  143. The call to ``.then`` also returns a promise. If the handler that is
  144. called returns a promise, the promise returned by ``.then`` takes on the
  145. state of that returned promise. If the handler that is called returns a
  146. value that is not a promise, the promise returned by ``.then`` will be
  147. fulfilled with that value. If the handler that is called throws an
  148. exception then the promise returned by ``.then`` is rejected with that
  149. exception.
  150. promise.catch(did\_reject)
  151. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  152. Sugar for ``promise.then(None, did_reject)``, to mirror ``catch`` in
  153. synchronous code.
  154. promise.done(did\_fulfill, did\_reject)
  155. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  156. The same semantics as ``.then`` except that it does not return a promise
  157. and any exceptions are re-thrown so that they can be logged (crashing
  158. the application in non-browser environments)
  159. Contributing
  160. ============
  161. After cloning this repo, ensure dependencies are installed by running:
  162. .. code:: sh
  163. pip install -e ".[test]"
  164. After developing, the full test suite can be evaluated by running:
  165. .. code:: sh
  166. py.test tests --cov=promise --benchmark-skip # Use -v -s for verbose mode
  167. You can also run the benchmarks with:
  168. .. code:: sh
  169. py.test tests --benchmark-only
  170. Static type checking
  171. --------------------
  172. Python type annotations are very useful for making sure we use the
  173. libary the way is intended.
  174. You can run ``mypy`` static type checker:
  175. .. code:: sh
  176. pip install mypy
  177. mypy promise --ignore-missing-imports
  178. Or ``pyre``:
  179. .. code:: sh
  180. pip install pyre-check
  181. pyre --source-directory promise check
  182. Notes
  183. =====
  184. This package is heavily insipired in
  185. `aplus <https://github.com/xogeny/aplus>`__.
  186. License
  187. -------
  188. `MIT
  189. License <https://github.com/syrusakbary/promise/blob/master/LICENSE>`__
  190. .. |travis| image:: https://img.shields.io/travis/syrusakbary/promise.svg?style=flat
  191. :target: https://travis-ci.org/syrusakbary/promise
  192. .. |pypi| image:: https://img.shields.io/pypi/v/promise.svg?style=flat
  193. :target: https://pypi.python.org/pypi/promise
  194. .. |coveralls| image:: https://coveralls.io/repos/syrusakbary/promise/badge.svg?branch=master&service=github
  195. :target: https://coveralls.io/github/syrusakbary/promise?branch=master