vine-1.3.0/0000755000175000017500000000000013444127245012410 5ustar omeromer00000000000000vine-1.3.0/Changelog0000644000175000017500000000711413444127120014215 0ustar omeromer00000000000000Changes ======= .. _version-1.3.0: :release-date: 2019-03-19 11:00 A.M UTC+2 :release-by: Omer Katz - Added the option to ignore the result of a function and simply call the callback without arguments. Contributed by **Omer Katz** .. _version-1.2.0: :release-date: 2018-01-06 4:30 P.M UTC+2 :release-by: Omer Katz 1.2.0 ===== - Added Python 3.7 support. Contributed by **Jon Dufresne** & **:github_user:`dequis`** - Handle bound methods in weak reference promise instances. Contributed by **George Psarakis** Documentation fixes, CI adjustments and cleanups by: - **Omer Katz** - **Jon Dufresne** - **Edward Betts** - **Jacopo Notarstefano** - **Christopher Hoskin** - **Fahad Siddiqui** .. _version-1.1.4: 1.1.4 ===== :release-date: 2017-07-16 10:30 P.M UTC+2 :release-by: Ask Solem - Added official support for Python 3.5 & 3.6. - Improve Python 2/3 compatibility. - Don't set mutable default values to keyword arguments. .. _version-1.1.3: 1.1.3 ===== :release-date: 2016-10-13 06:02 P.M PDT :release-by: Ask Solem - New ``promise(fun, weak=True)`` argument, creates weakref to callback. .. _version-1.1.2: 1.1.2 ===== :release-date: 2016-09-07 04:18 P.M PDT :release-by: Ask Solem - barrier: now handles the case where len(promises) returns NotImplemented. .. _version-1.1.1: 1.1.1 ===== :release-date: 2016-06-30 12:05 P.M PDT :release-by: Ask Solem - Requirements: Tests now depends on :pypi:`case` 1.2.2 - Five: python_2_unicode_compatible now ensures `__repr__` returns bytes on Python 2. .. _version-1.1.0: 1.1.0 ===== :release-date: 2016-04-21 01:30 P.M PDT :release-by: Ask Solem - :meth:`promise.throw() ` now passes partial args/kwargs to the errback: .. code-block:: pycon >>> p = promise(args=(self,), on_error=handle_error) >>> p.throw(exc) # --> handle_error(self, exc) - New :class:`vine.abstract.ThenableProxy` can be used to add promise-capabilities to a class by forwarding to a different promise. .. code-block:: python from vine import promise from vine.abstract import ThenableProxy class P(ThenableProxy): def __init__(self, on_success=None, on_error=None): self._set_promise_target(promise( args=(self,), callback=on_success, on_error=on_error, )) p = P() p.then(download_file(url)).then(extract_file) - :meth:`promise.throw() ` now supports a propagate argument that can be set to False to never reraise the exception. - :meth:`promise.throw() ` now also reraises the current exception from the stack, if the exc argument is passed and that value is the same as the current exception. - :meth:`Thenable.register() ` can now be used as a decorator. - Argument to :meth:`promise.throw1(exc) ` can now be :const:`None` to use the current exception. - ``monotonic()`` now uses ``librt.so.0`` as an alternative if ``librt.so.1`` does not exist. Contributed by Fahad Siddiqui. .. _version-1.0.2: 1.0.2 ===== :release-date: 2016-04-11 05:30 P.M PDT :release-by: Ask Solem - ``promise.throw()`` now supports second ``traceback`` argument to throw exception with specific traceback. Contributed by Ionel Cristian Mărieș. .. _version-1.0.1: 1.0.1 ===== :release-date: 2016-04-11 03:00 P.M PDT :release-by: Ask Solem - Adds vine.five.python_2_unicode_compatible. .. _version-1.0.0: 1.0.0 ===== :release-date: 2016-04-07 06:02 P.M PDT :release-by: Ask Solem - Initial release. vine-1.3.0/LICENSE0000644000175000017500000000463513414403510013412 0ustar omeromer00000000000000Copyright (c) 2015-2016 Ask Solem & contributors. All rights reserved. Vine is licensed under The BSD License (3 Clause, also known as the new BSD license). The license is an OSI approved Open Source license and is GPL-compatible(1). The license text can also be found here: http://www.opensource.org/licenses/BSD-3-Clause License ======= Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Ask Solem, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Ask Solem OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Documentation License ===================== The documentation portion of Vine (the rendered contents of the "docs" directory of a software distribution or checkout) is supplied under the "Creative Commons Attribution-ShareAlike 4.0 International" (CC BY-SA 4.0) License as described by http://creativecommons.org/licenses/by-sa/4.0/ Footnotes ========= (1) A GPL-compatible license makes it possible to combine Vine with other software that is released under the GPL, it does not mean that we're distributing Vine under the GPL license. The BSD license, unlike the GPL, let you distribute a modified version without making your changes open source. vine-1.3.0/MANIFEST.in0000644000175000017500000000043113414403510014131 0ustar omeromer00000000000000include README.rst Changelog LICENSE recursive-include docs * recursive-include extra README *.py recursive-include requirements *.txt recursive-include t *.py recursive-exclude docs/_build * recursive-exclude * __pycache__ recursive-exclude * *.py[co] recursive-exclude * .*.sw* vine-1.3.0/PKG-INFO0000644000175000017500000000520313444127245013505 0ustar omeromer00000000000000Metadata-Version: 1.2 Name: vine Version: 1.3.0 Summary: Promises, promises, promises. Home-page: http://github.com/celery/vine Author: Ask Solem Author-email: ask@celeryproject.org License: BSD Description: ===================================================================== vine - Python Promises ===================================================================== |build-status| |coverage| |license| |wheel| |pyversion| |pyimp| :Version: 1.3.0 :Web: https://vine.readthedocs.io/ :Download: https://pypi.org/project/vine/ :Source: http://github.com/celery/vine/ :Keywords: promise, async, future About ===== .. |build-status| image:: https://secure.travis-ci.org/celery/vine.png?branch=master :alt: Build status :target: https://travis-ci.org/celery/vine .. |coverage| image:: https://codecov.io/github/celery/vine/coverage.svg?branch=master :target: https://codecov.io/github/celery/vine?branch=master .. |license| image:: https://img.shields.io/pypi/l/vine.svg :alt: BSD License :target: https://opensource.org/licenses/BSD-3-Clause .. |wheel| image:: https://img.shields.io/pypi/wheel/vine.svg :alt: Vine can be installed via wheel :target: https://pypi.org/project/vine/ .. |pyversion| image:: https://img.shields.io/pypi/pyversions/vine.svg :alt: Supported Python versions. :target: https://pypi.org/project/vine/ .. |pyimp| image:: https://img.shields.io/pypi/implementation/vine.svg :alt: Support Python implementations. :target: https://pypi.org/project/vine/ Keywords: promise promises lazy future futures Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 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 :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: License :: OSI Approved :: BSD License Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* vine-1.3.0/README.rst0000644000175000017500000000245213444127200014071 0ustar omeromer00000000000000===================================================================== vine - Python Promises ===================================================================== |build-status| |coverage| |license| |wheel| |pyversion| |pyimp| :Version: 1.3.0 :Web: https://vine.readthedocs.io/ :Download: https://pypi.org/project/vine/ :Source: http://github.com/celery/vine/ :Keywords: promise, async, future About ===== .. |build-status| image:: https://secure.travis-ci.org/celery/vine.png?branch=master :alt: Build status :target: https://travis-ci.org/celery/vine .. |coverage| image:: https://codecov.io/github/celery/vine/coverage.svg?branch=master :target: https://codecov.io/github/celery/vine?branch=master .. |license| image:: https://img.shields.io/pypi/l/vine.svg :alt: BSD License :target: https://opensource.org/licenses/BSD-3-Clause .. |wheel| image:: https://img.shields.io/pypi/wheel/vine.svg :alt: Vine can be installed via wheel :target: https://pypi.org/project/vine/ .. |pyversion| image:: https://img.shields.io/pypi/pyversions/vine.svg :alt: Supported Python versions. :target: https://pypi.org/project/vine/ .. |pyimp| image:: https://img.shields.io/pypi/implementation/vine.svg :alt: Support Python implementations. :target: https://pypi.org/project/vine/ vine-1.3.0/docs/0000755000175000017500000000000013444127245013340 5ustar omeromer00000000000000vine-1.3.0/docs/Makefile0000644000175000017500000001751213414403510014773 0ustar omeromer00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " epub3 to make an epub3" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" @echo " apicheck to make sure all modules are documented by autodoc" .PHONY: clean clean: rm -rf $(BUILDDIR)/* .PHONY: html html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." .PHONY: dirhtml dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." .PHONY: singlehtml singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." .PHONY: pickle pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." .PHONY: json json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." .PHONY: htmlhelp htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." .PHONY: qthelp qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PROJ.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PROJ.qhc" .PHONY: applehelp applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." .PHONY: devhelp devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/PROJ" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PROJ" @echo "# devhelp" .PHONY: epub epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." .PHONY: epub3 epub3: $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 @echo @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." .PHONY: latex latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." .PHONY: latexpdf latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: latexpdfja latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: text text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." .PHONY: man man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." .PHONY: texinfo texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." .PHONY: info info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." .PHONY: gettext gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." .PHONY: changes changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." .PHONY: linkcheck linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." .PHONY: doctest doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." .PHONY: coverage coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." .PHONY: apicheck apicheck: $(SPHINXBUILD) -b apicheck $(ALLSPHINXOPTS) $(BUILDDIR)/apicheck .PHONY: xml xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." .PHONY: pseudoxml pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." vine-1.3.0/docs/_static/0000755000175000017500000000000013444127245014766 5ustar omeromer00000000000000vine-1.3.0/docs/_static/.keep0000644000175000017500000000000013414403510015666 0ustar omeromer00000000000000vine-1.3.0/docs/_templates/0000755000175000017500000000000013444127245015475 5ustar omeromer00000000000000vine-1.3.0/docs/_templates/sidebardonations.html0000644000175000017500000000601213414403510021677 0ustar omeromer00000000000000 vine-1.3.0/docs/changelog.rst0000644000175000017500000000003213414403510016001 0ustar omeromer00000000000000.. include:: ../Changelog vine-1.3.0/docs/conf.py0000644000175000017500000000137313414403510014630 0ustar omeromer00000000000000# -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals from sphinx_celery import conf globals().update(conf.build_config( 'vine', __file__, project='Vine', description='Python Promises', # version_dev='2.0', # version_stable='1.0', canonical_url='https://vine.readthedocs.io', webdomain='celeryproject.org', github_project='celery/vine', author='Ask Solem & contributors', author_name='Ask Solem', copyright='2016', publisher='Celery Project', html_logo='images/celery_128.png', html_favicon='images/favicon.ico', html_prepend_sidebars=['sidebardonations.html'], extra_extensions=[], include_intersphinx={'python', 'sphinx'}, apicheck_ignore_modules=['vine'], )) vine-1.3.0/docs/images/0000755000175000017500000000000013444127245014605 5ustar omeromer00000000000000vine-1.3.0/docs/images/celery_128.png0000644000175000017500000005301713414403510017163 0ustar omeromer00000000000000PNG  IHDR>a pHYs  UIDATx{fU[{so?<4H#i@ aX`Ǣ~T9MW?cTpIv1 0XBH3yOO?뜽kךV7NQMMu߾s^{=~"f^ |; / "~_,DD"~ok{>0~|A~"r̜/7kZ̜r{tW%晙yo=qZ=yKU.軮⽸^uF_!x{қʣsÐ6ܙ^zYQfތj{UK}pn83sڣG+@N*Dx|K/[\My]=/sr!O(?=\,? ~ݳ~Wxw?_G~?p]Ѝָ913@:G Dp"'rf0!B~,uqP6ޖYړCbBp..@e^GV&#lGP23$S|"32ɽef )M0 LFϛ ß1ë enO3șr'3ӐuČX933Z&~L=2n;:q=ٗܿW_ċ*t9spu8J??{O=n .,6QGT".\ I!Jsp$Nstf';BLvr^m@A, %Q>öa#pf =bG1G,3?!r0詯/\4*r3r6'?߼]I^֕""B-9B̌RJEL㤜뿓H8BȵbJU=\m]4p^iʩl2@ daIudjzB=i BUU3e!u,׍9P9Y)u󁔹<CBN>/kS3xB>pkgoDDDwU³ǔ;uYlt#sơ jզ$9O$BYb=Y6rʈh jQЩ=6-Yli0uM5^4n@Ŭ80}||~7Sά߭)#~;^w﾿FDSSvִ^ńΣ>9+fx,0,89% }`VAuU gߣ״Sl޽8\Rxwu"l"$)gx_H S.3 Y \Z){_4[ȤΨSfY@NrLf=)9Я"6do//﷿Ƿu?81x H9HB9);'Mh$`T.6܁F 4$uDH!% I16raT`5bް } ӘS.뛳>ؕM5\͈[n=pŴ%=rѶQcnV+2i /'gb74C:5Ewi2\A8G%S}TAm3zrrUレ\bZ2mj^dBu - A)F3,$@e%1O 9r "FN0=zt()|pdP<:qdUzaR llH j)RGЌ!2Hebb~{Sl[|<@nı~gБ QTp>Wx^UN"~ y\NԈ> u9{:4V&~99tZ˫SA޳nېkқJIJ䁜DU8 VA5=Ջ*' (ڊBI"ʿ3Ps<OACImAzMтEeW"Zpf05 0HDt)s,U8-"i}5ю>I/# <.(N r䐞|Yl9LmH3YyE0 "<85Tޡ C.jS 5sf8_A~&AlXJp 'K_YӞYGQ,9YHYS1\Tlk6$c,8z:MšaQפ<:/,B]N7áS4R(BHŤDf r=#gYʍ@a,G@ix !SsW_oKi@@3#7s 8'ATyTB /U9%d;;x1A۴ X-#Nzq/g)ic;t>vѶ &] 39%q! &yz#("9f"q31Ar\T~WsqTasJbqbSNSke|7bY &ߩmIT}\ߍĘsB)t +1oG;]xt8>Gy |8! @NN g@H1cp9gz8ʣxÛ«_{+yx]'pꖣႀB tՓ0۠Tm<pf )jG ?KI )9 'Y+8 QnF gY-(8#Ǭ0n,jTY#A^"tJwƵ;-!]u==0ΣŦ MAmB vfwzp&p& l_d7}x[_w'~)滻jº_#sBp#((3Ē#)vﷳ1Fsk @<@ 9%GR21cJ `Y=~*Q"cm4<99h o'0*GN6 *~g"5=aRb$…mw¤)֔n8EG 4I"˿躃 j{ +{u**;쌲_bNv6:@@Hv@"t{xg0 (x4j iSr1W "'r9`2 1fH)cubыșR д C|AJ =&a;-2<N ӝNG||7$N}7,c5:, f%(Kib 'Mv]N[ITlyWˁ )x#h8,a3c2C>G> ?aE\ hNO7G:O8<)6 vw]``)V+m$Vm8|A?$ C|"r9{??N"vXV ~Y#N)Q8r3RQ|1 <j˽Xl1})rP8ι hTL򡇀S@M<"vw;qxcg'y9`wEy)8xK#p^s8ybO?,>()'d,V*6YY]dr1#4'wo$r&yrʏvENZ<̋x 7yݸ[\ZspxO?xgG_&;_ p E':L `Ӂ\1m4}d4 , ,}DITJ[9+XQF3alKhlT*Nbx.ybJw5m9U \i`֏ 3S⩇r1I@Όa1ߑ]L-f)el6 C…'1'?ft;xt׈GpOpr# ` g\ċO/=xOggp!4:nf`8,#`r `0Z2qK3sFI2N TN sQPW\ (4:Z_wQF9*UP C/!b^0,Nr66_R9Fb ֝E' ȉpSJvoqnڠDĔ168ztA Opv3#GU,GNG⌄pss u'pt6;Fo4~_=;^{¹$E4Ź#RbW\sOKd`RekKEr•^Wt3RFӐvH}Ig丝S-RӒZ$]@"^:}'G3!z!d2b6k"Ebѣk|F[ތ.~9EAkH8}uV'IE[4!gNȃ6ָ8t1۽ o;7E| ԧ_Ek8r/^TAg|'bVF ԁV3 [laV)+j;!Va#dC-aw]R(R\bosj5`QǕ8$BQRfh#)0ĕlQG!8}Vz&VUԪ•.l zV@=9XXn5rhxV^WM۟1J"us R*K@-dؘ8^p:b9O5Xo>MpX.6J1!gպKZ(ފ4.V)޸Ra-[$rҲ=8K3<~Q;+^7o_ֳZ֢Z\M0 uhJS@  ĘL x1b7䁴g +QhBV2boofbc6m3od- %%Œd^uIsN$M)fTʸ<ƛFa8KK6n&t m(:IYG%LKȉOѲPҶMk-a~U"ty P %B6tf%$iAR4qbd,TL&+y#x|yr@$0_#S;ԝ˹dsLS ˳f\} xK rԆR,c< c*AeRy{ɿZMo Za\ie@|XOOPK6S֋:_55y$-+4&Ӏ3넦 hySh!ގݟ`IQ"DbF(# a}ɪ75f0NpvFs|qԩ_WZ6~)ڋ/ ^+a%dgH\n&Oyp#G:M~#!|zg-Sv eU-r&leG0 sBJCMG=mF?\>pYFo,b'0"zJ^{t]XX+XP4rk3)V'4Xc>o2c7AL-&1fhtIU.p--bTݺV gha@Vn\Ԛs)K*.i|CF6ɒbp/%D-OPKR=}ѯX(PUzNR;8Hֺh!wMXo᠔1(cp=]#Lbf-609 qȊ#:8@×竎"ХcikMc#]z;"86`n0~c2.b* QC5ٰ.!rD%#^Q+`3KVkV OT*a( I {W>GiѶ33,m\r@7 $ جS.6N[Lg YhZ>ٌ7CaBi"`l/.~%G Q$eH)[ 0!tX7:jT?֨g3`!&;˘bK8B ͺe=Rl}>@71G:LAX?`L '\`60:`9Y/j&jM.] gQ%*47X.I0Ns^9gˆiN(п9$ՔY/fdֳ%J(&J6xib7Lt}`,93BْA66(!]*8 TQ qX-|>b6od9`JFd,{6Wi%;)G.I,.,˒p 2߭?/B:Զq[ E $]Krq]sJPX1%zĪ?٥=O٧ڦ54gےlV PZD+5+l#1M8OX.{x17ll&1bi@ؿ-S5YM,FZ>(}-9Sj᜽xGQͭsceJ2 Дī6ܱϹS/й^ Ҟ(n1>8 *f׌a,zC =qX-`e)T_ MO13lr}SVGYR&FHR[Poi0~[Ԓ:aʘ̓ p048X `/ڧG3o%0&3c-{d q=xl(XBBOqє( U~:e5L3X} !c-Ʋx1Y⢲{Ja'UMQvI ^šOR hۀDOLmѴl؉G>DeWLAʌ_zhGѕir5*:gaX#3FcvyǸ{3e!V"8FB2kwFGLPo6қaպе2f>c8PLSQ5d6dLFte?0&hem,Al [OFXV+H~JLuƼ>H)Luf먒%x\5չIڑ+p5ZI1c:0 =h5RdZDZӺg7Tu3vrmZaʣA;HUtqdGBg9kP_bj96_#-㔹m 2 QByJ\։*0r#Gײh19Kd@pXa>oYJMl{ORgVLV *jq+!Ul09Sf՘ea\1ȼBk(@a)R" ##7uT=J `9҇H7#L'bU(HiB$Ũ)3bq śIlQeƀU+ݿwќHPFxB\#-~Ŝ&<:v͐V+%ͭg)w"ڶ)Mfsa,&3RbH2P\ꞤsjjR-fuuw˩7>%g)pm (ZGPMڰEH[wSK#$< 3Mv@I?w>Q%ETT9X9k!XGtFTr٣xxp? e퐀IHe -':XFydf$WKmtF SI3INjn >k` "q5^o=nBL(;*r$A&f#qe@7i^% sX5$&lYJ xe*:< K)waICLhQFI$C4L>CK5jttqߗPWW LHR &L0Yn6ذtgiP1nef@cň-5 G#! Lgr)Y,q^ aJ!)&v} Ʈ#zQ5@ŀ84r+(a qK4b!w3R5 N\Sac h6ȕ wMn`2JϯO>O| L x/=4 jû1Ms=>ُ=1ǣ+^s O?rY߻UC"<Hg[QHQN:iw9|2oUx_i5&Vo*r69LZ]WucL>)du9W &a^$L u^-2چp͇N▻h)(:x'>0{eu|ݤAӈ)ܬ^/G>>_#4]' qۦ-2,rs猑G;\b^IP<s5U}mB _Ng;xx>g+.'YC'Ǹ5,`7MUj:{77>|It]Eh-֎x5LDo^(|Tiϋ; 1b|Y1#&طT8G,+p\2bMln M<(38mM$OĀN: w?+xӻܱc-g4m@iHXna W8>^xzO}a^ܯ1nkqpANuhR"HF9 x/u܈jU`oIh*yWw1`0$!P$f0Ĉ&+q7qcX-V;;N$'zw ~7>}oA50]Än p7 M ^?$>'so#W N/^o}^œ~|+ }| ,0%8zk7߄tD̪}k eZ`&, v45b)pD2#3|QQ!:%!s6*kDI~F0Bf KW r8cgA7791kv,M뤾` Ǹ=[RilgE:HQ6;\ZU2)D4o^֫vO-2ډ'`"CY=V+8Z::R d4/k]7n5'J3%W˭ɑҤ+÷H/WF4 lj2=3s7U /`2eDBp &zд8Hȴ0(dc8LwEւ @o %:8SB;qm:]9ʽdۉ_y:KVa CMu-j:,4)q]2X֔ZQ&`#OjQDAm?oӟY!rmW5U mVڀgāMgG.4H10x1KCNio(“*Ϣ0E|<~ 'WC<ʊd>G?ƩCc|idKf`^<? w8{% {d9>LHQ8 f7άˆN\C+C} SAv"mh\YgFcn ? *!g!xx's~g>GШ o483.]zA $c%^ 4!R#_aܽjLJf䵿3p1i<7W€-¥FS/MF7 HT.J7#0B#EɉOQtGfK$urcrRAm,mč gϝ~ğM/C w`2Ju+ܴu^#+T6iBȤJ-QM3sDk93!"_~q'Σ_JP7ȉ^H QřeC9 iwzQԃ0ltFHy5Z:!%Z2!,v>16 !Lg/D^; ? kuB CJy(ؽRgkĚ7/%@)0 ;'pob\YWqmIbBF1b&;Dep"P ltO=>&'m'Hh"ÄɎG;FI&-wt;pf4ntsa-3f1ta,:jM*L```̏tpnx-m}^W8O<N~ }x0A'ZiŹiڊ6̚@ʥ5 PjC(g QwTHf"YdC(ڜTN a`qǞz7= KA Fg[-"ډt"736vج4Ed1ϛulG,"d&nH f"]y<);w}xƫ^{+vohpG,Ν?j#$"W%Fg;`+ -HJu^0̎g%WqKԚ3 uz´%`%"z~|  {n8âNau;rjiANt\~'`u1LfqHK~CЋh¡xGKxQ-h?˯=GNt¹cbYEN>o2g\C8* ƹWLs#IB+ @i_lU{+FPN(`SY[瀁qi<uo??W4AʼnZ-4G7԰$L^K):)6P+{̴;:p~ 4%]{_;  }aHcT̄qxJpfZ+ӚhĘ@Tyy}/J4!r$3RWN>UV-oyn+\dU2w8{|v~;ހgC8sn<qנk%Ldvv$ڡl{<>h,Vm7 ݋_u^q׍c;1k}Z/pr$u` GގJ%(%D䦜K}^ SN}Nz7}=/>4g@6>niyE. ܄+nnyq<ݣsv=IXk/.OKl6phtB5йFS4 &aPeEY(m}ٺ1>` 4``iAGN;~ĭVn;Wv*|\3X֛$enp\pGSMr3;1&.b .;@{aע$wlG5:%l~ sSq<@Zۘtϸg/)5UL|: KC[ mM}ݏK;_ pRD)cc,5\6 ƮVX\s= @Ѩ~l5TU@edSpm`6cwL3y.Z?AmjI#)Ga>:DcZbZ6I{*E F@UȺJ-NESX\ͺRíX`$f.Ϛ󕝀5`O,qj3~4kJ԰:13[7s(呑! gϞ)#au [0%!@V ȨC눜}g:GJ9B6ɪt[jp'qѸVV}G_p,3Ǒ5 'c}'C_`qH<ڼu\OP}z!q)Q#r 9@نS8KJ֞Kj찵퇡t;UkՌܓ BF{oGygSANyo*tl6ϯ&ra,*9e茮/jQOP4 #zιzvI^H숿5ҌhCVmY2r5s%Z( %T-ȍT,l_s=iHUA28•)WQ[o6Ds'GJEZ7 kL4R5OFRXac]&4.*vyS͛8r[_ >ݫ<цS!cU_udP1AF7&TBA4peaTf=~S4~+ KէirY҈v ai31ꋌHl+.}Ik[V6vL8K蜷;Tf b) lʔTR)zـ+7ÚRr8)Q#Z#m=-D2JUډܶ72jEFQ}"+"A3~;Yr[b:lB;[\#^_z2Ja,SUkCqcg-E7vMR$嘅!mB9rJ }6/ n 33~̫>Vv`"ш×NMmd4)\yQ욛w#4*QrdӬ55=y^'5hZV+C.?^Q{F6)אH (*bf6s*PȢB-9M[a-{ib:;_8>bqͿ!f/`͛7Vnqp1Ϗ~k*DowXI\m:})Sv tuD׿;VNfxO3S\Zþ| ?ZLO>ɗЕ7YGqa5tq N7x4'a c@qBU{՞:C_IFN47$9/^}^+gq=%M%7ryϥMY;̴Ëz!DH@w(B $ c~88׿9p7?<?!W5ևkAo_o}W|ɕϾu=~ߊ|W}PM=IENDB`vine-1.3.0/docs/images/favicon.ico0000644000175000017500000001027613414403510016721 0ustar omeromer00000000000000  ( @   O1w U4S3V4 V4 V4 V6 V6 W6 W6 W6 W7 W7 W7 W6 W6 W6 W6 V6 V4 V4 V4T4S3 S2O1w `:tFvHxJzKzL{M}N~O~OQRRRRQP~P~P}O|N{LzKxJwItGtF`: [8_zJ{NR!S"U$V%X%Y%Z(]'\%[%[&\&\'](](]'[%Y%X$W#V"TRRzMyJ[;_iCzR"T"V#W%Z&[&](_(`"]&c.j2n1m-j(e#`!]$](_(_&\%Z%Y#V"U!SQiCzjDxV$V$X%Z&\'^(a(a)fD}OOyMuNxO{PME~8s(e!\&^'^&[%Y#W#UUjDxlFx X%X&['^'_)b)c,kM?lZ9,+ ( +. :,-OA=jYKqQE~.i'`(_&\%Y%WWjFxlHx!Z'[&](`*d+f(hH2VH;'B->*9&=(>):$0%:->gW@q*f(a'_&]%X XlFxlHx#\(^(`)c,h)g9y?{d# E0?+&- :,.! ,=) >)8l-l)d)b(_&["ZoHxoJx$^(a*d*f-k*kA+WE7"F0/2kVHCC@v8}d+[H6)1fQ=~*i,i*d(a(_#]oJxqMx%a*c+f,j/n-qC#L: A) C+"J8M858;?CE6~d;u3w.n-l+h)d)a%`qMxqOx&c+f+i-m0q/uE#L:E-B(/_LJ5:87556;5}1v0s.n,j+h*d%aqMxsQx'f,h,k.o1t0wF#O<H/ G+._KL8;;::974~4}3y1u/r.m,j*e&cqOxsQx(i,j.n0s2v2zH#P=N2 K//bNN9=<<;::864|3x1t/p-k+h'fsQxsSx)j.l/q1u3x3~I$T?Q5 O20ePP;?>>=;;:764{2w0r.n-j(hsQxuSx)k/n/r2v5|4K%V@U8 U60gQP=A@??>;:975~3x0t/p-k'hsQxuSx*l/o0s3x6~5L%XBY; X91iSR¤@CBAA?=;;864z2v/q-k(isSxuUx*m/o0t1x4}3K%ZC\= [;2lUSĦADDC@?=:9642{0u.q/n(juSxsQx)l0q4w:~?@Y*]F^?]=;pZeβSȫWʭVɬUǪSŧQOLHE@<7z2s/n'jsQx-dx?FILNNf/^I_?_?>r\lӷYͰ^г]ϲ[ͰYʭXȫYŦVTROMJHC~<|+bx7oxHKLNQPgå/^I`@_?@t^mԸ^гaҵaҵ_г[̯UȫOťWɧVáSQOMLIG7ox9qxLNORSTiƨ.]H_@`@@q[~WӴ[ѳ[Ҵ\Եb׹nھîoƪUßUSQNMJ9ox>sxQQTWXXàk̭6cP[;gI Z;{ɵ{^uG-dkԱUXURQOT0Z8`=1VDwǬ\ɣ\YWTS@uxDwxY˜Z[^ĝ`ɣa˦hԮoƪ:+O/gHjKdA`=b@fEgG]?E(+6+fdѫ^Ş]Ü[XWDwxFyx\ƛ]˜`ƞbȠdͥfϩfЫr߸m(H;(7A$@#90/%F8Crb`sбkհdͧcʢ`ƞ^Ú]—[ŚFyxJ{xaʞbƛdɟf̣gШiҫk֯k֯uyںgYUwW{\fr©yع{vlڲiӬhѩfΥdʡbǝař`ɝJyxL~yc̠gʠhͣiϥjҪl֮nٰp۳o۴rz~|wsoܶnٲnٱmׯkԫiЧhͣg̡eǜa˞L~yS~Ylթd̟g͢hХjөkլmدo۳pܵp޸o޷opppppqpݷo۴nڱl׮jԪiҧhϣf̠bʝkӧS{Yp}߷zߵ}~~}|yݳ|޵oxWtqrrrrrrrrrrrrrrrrrrrrqtxW@@vine-1.3.0/docs/includes/0000755000175000017500000000000013444127245015146 5ustar omeromer00000000000000vine-1.3.0/docs/includes/introduction.txt0000644000175000017500000000026513444127200020422 0ustar omeromer00000000000000:Version: 1.3.0 :Web: https://vine.readthedocs.io/ :Download: https://pypi.org/project/vine/ :Source: http://github.com/celery/vine/ :Keywords: promise, async, future About ===== vine-1.3.0/docs/index.rst0000644000175000017500000000051613414403510015170 0ustar omeromer00000000000000============================================= vine - Python Promises ============================================= .. include:: includes/introduction.txt Contents ======== .. toctree:: :maxdepth: 2 reference/index changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` vine-1.3.0/docs/make.bat0000644000175000017500000001646413414403510014745 0ustar omeromer00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. epub3 to make an epub3 echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 1>NUL 2>NUL if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PROJ.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PROJ.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "epub3" ( %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end vine-1.3.0/docs/reference/0000755000175000017500000000000013444127245015276 5ustar omeromer00000000000000vine-1.3.0/docs/reference/index.rst0000644000175000017500000000042113414403510017121 0ustar omeromer00000000000000.. _apiref: =============== API Reference =============== :Release: |version| :Date: |today| .. toctree:: :maxdepth: 1 vine.promises vine.synchronization vine.funtools vine.abstract vine.five vine.utils vine.backports.weakref_backports vine-1.3.0/docs/reference/vine.abstract.rst0000644000175000017500000000037013414403510020560 0ustar omeromer00000000000000===================================================== vine.abstract ===================================================== .. contents:: :local: .. currentmodule:: vine.abstract .. automodule:: vine.abstract :members: :undoc-members: vine-1.3.0/docs/reference/vine.backports.rst0000644000175000017500000000037313414403510020750 0ustar omeromer00000000000000===================================================== vine.backports ===================================================== .. contents:: :local: .. currentmodule:: vine.backports .. automodule:: vine.backports :members: :undoc-members: vine-1.3.0/docs/reference/vine.backports.weakref_backports.rst0000644000175000017500000000046013414403510024440 0ustar omeromer00000000000000===================================================== vine.backports.weakref_backports ===================================================== .. contents:: :local: .. currentmodule:: vine.backports.weakref_backports .. automodule:: vine.backports.weakref_backports :members: :undoc-members: vine-1.3.0/docs/reference/vine.five.rst0000644000175000017500000000035413414403510017710 0ustar omeromer00000000000000===================================================== vine.five ===================================================== .. contents:: :local: .. currentmodule:: vine.five .. automodule:: vine.five :members: :undoc-members: vine-1.3.0/docs/reference/vine.funtools.rst0000644000175000017500000000037013414403510020626 0ustar omeromer00000000000000===================================================== vine.funtools ===================================================== .. contents:: :local: .. currentmodule:: vine.funtools .. automodule:: vine.funtools :members: :undoc-members: vine-1.3.0/docs/reference/vine.promises.rst0000644000175000017500000000037013414403510020616 0ustar omeromer00000000000000===================================================== vine.promises ===================================================== .. contents:: :local: .. currentmodule:: vine.promises .. automodule:: vine.promises :members: :undoc-members: vine-1.3.0/docs/reference/vine.synchronization.rst0000644000175000017500000000041513414403510022216 0ustar omeromer00000000000000===================================================== vine.synchronization ===================================================== .. contents:: :local: .. currentmodule:: vine.synchronization .. automodule:: vine.synchronization :members: :undoc-members: vine-1.3.0/docs/reference/vine.utils.rst0000644000175000017500000000035713414403510020122 0ustar omeromer00000000000000===================================================== vine.utils ===================================================== .. contents:: :local: .. currentmodule:: vine.utils .. automodule:: vine.utils :members: :undoc-members: vine-1.3.0/docs/templates/0000755000175000017500000000000013444127245015336 5ustar omeromer00000000000000vine-1.3.0/docs/templates/readme.txt0000644000175000017500000000223613414403510017324 0ustar omeromer00000000000000===================================================================== vine - Python Promises ===================================================================== |build-status| |coverage| |license| |wheel| |pyversion| |pyimp| .. include:: ../includes/introduction.txt .. |build-status| image:: https://secure.travis-ci.org/celery/vine.png?branch=master :alt: Build status :target: https://travis-ci.org/celery/vine .. |coverage| image:: https://codecov.io/github/celery/vine/coverage.svg?branch=master :target: https://codecov.io/github/celery/vine?branch=master .. |license| image:: https://img.shields.io/pypi/l/vine.svg :alt: BSD License :target: https://opensource.org/licenses/BSD-3-Clause .. |wheel| image:: https://img.shields.io/pypi/wheel/vine.svg :alt: Vine can be installed via wheel :target: https://pypi.org/project/vine/ .. |pyversion| image:: https://img.shields.io/pypi/pyversions/vine.svg :alt: Supported Python versions. :target: https://pypi.org/project/vine/ .. |pyimp| image:: https://img.shields.io/pypi/implementation/vine.svg :alt: Support Python implementations. :target: https://pypi.org/project/vine/ vine-1.3.0/requirements/0000755000175000017500000000000013444127245015133 5ustar omeromer00000000000000vine-1.3.0/requirements/docs.txt0000644000175000017500000000002313414403510016604 0ustar omeromer00000000000000sphinx_celery>=1.1 vine-1.3.0/requirements/pkgutils.txt0000644000175000017500000000016013414403510017520 0ustar omeromer00000000000000setuptools>=20.6.7 wheel>=0.29.0 flake8>=2.5.4 flakeplus>=1.1 tox>=2.3.1 sphinx2rst>=1.0 bumpversion pydocstyle vine-1.3.0/requirements/test-ci.txt0000644000175000017500000000002313414403510017224 0ustar omeromer00000000000000pytest-cov codecov vine-1.3.0/requirements/test.txt0000644000175000017500000000003013414403510016631 0ustar omeromer00000000000000case>=1.3.1 pytest>=3.0 vine-1.3.0/setup.cfg0000644000175000017500000000037413444127245014235 0ustar omeromer00000000000000[tool:pytest] testpaths = t/unit/ python_classes = test_* [flake8] ignore = N806, N802, N801, N803 [pep257] ignore = D102,D104,D203,D105,D213,D107 [bdist_wheel] universal = 1 [metadata] license_file = LICENSE [egg_info] tag_build = tag_date = 0 vine-1.3.0/setup.py0000644000175000017500000000622213414403510014111 0ustar omeromer00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os import re import sys import codecs import setuptools import setuptools.command.test if sys.version_info < (2, 7): raise Exception('vine requires Python 2.7 or higher.') NAME = 'vine' # -*- Classifiers -*- classes = """ Development Status :: 5 - Production/Stable Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy License :: OSI Approved :: BSD License Intended Audience :: Developers Operating System :: OS Independent """ classifiers = [s.strip() for s in classes.split('\n') if s] # -*- Distribution Meta -*- re_meta = re.compile(r'__(\w+?)__\s*=\s*(.*)') re_doc = re.compile(r'^"""(.+?)"""') def add_default(m): attr_name, attr_value = m.groups() return ((attr_name, attr_value.strip("\"'")),) def add_doc(m): return (('doc', m.groups()[0]),) pats = {re_meta: add_default, re_doc: add_doc} here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'vine', '__init__.py')) as meta_fh: meta = {} for line in meta_fh: if line.strip() == '# -eof meta-': break for pattern, handler in pats.items(): m = pattern.match(line.strip()) if m: meta.update(handler(m)) # -*- Installation Requires -*- py_version = sys.version_info is_jython = sys.platform.startswith('java') is_pypy = hasattr(sys, 'pypy_version_info') def strip_comments(l): return l.split('#', 1)[0].strip() def reqs(f): return filter(None, [strip_comments(l) for l in open( os.path.join(os.getcwd(), 'requirements', f)).readlines()]) # -*- Long Description -*- if os.path.exists('README.rst'): long_description = codecs.open('README.rst', 'r', 'utf-8').read() else: long_description = 'See https://pypi.org/project/vine/' # -*- Entry Points -*- # # -*- %%% -*- class pytest(setuptools.command.test.test): user_options = [('pytest-args=', 'a', 'Arguments to pass to py.test')] def initialize_options(self): setuptools.command.test.test.initialize_options(self) self.pytest_args = [] def run_tests(self): import pytest sys.exit(pytest.main(self.pytest_args)) setuptools.setup( name=NAME, packages=setuptools.find_packages(exclude=['t', 't.*']), version=meta['version'], description=meta['doc'], long_description=long_description, keywords='promise promises lazy future futures', author=meta['author'], author_email=meta['contact'], url=meta['homepage'], platforms=['any'], classifiers=classifiers, license='BSD', python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", install_requires=[], tests_require=reqs('test.txt'), cmdclass={'test': pytest}, zip_safe=False, include_package_data=False, ) vine-1.3.0/t/0000755000175000017500000000000013444127245012653 5ustar omeromer00000000000000vine-1.3.0/t/__init__.py0000644000175000017500000000000013414403510014737 0ustar omeromer00000000000000vine-1.3.0/t/unit/0000755000175000017500000000000013444127245013632 5ustar omeromer00000000000000vine-1.3.0/t/unit/__init__.py0000644000175000017500000000000013414403510015716 0ustar omeromer00000000000000vine-1.3.0/t/unit/conftest.py0000644000175000017500000000124713414403510016022 0ustar omeromer00000000000000from __future__ import absolute_import, unicode_literals import pytest @pytest.fixture(autouse=True) def zzzz_test_cases_calls_setup_teardown(request): if request.instance: # we set the .patching attribute for every test class. setup = getattr(request.instance, 'setup', None) # we also call .setup() and .teardown() after every test method. setup and setup() yield if request.instance: teardown = getattr(request.instance, 'teardown', None) teardown and teardown() @pytest.fixture(autouse=True) def test_cases_has_patching(request, patching): if request.instance: request.instance.patching = patching vine-1.3.0/t/unit/test_abstract.py0000644000175000017500000000072113414403510017033 0ustar omeromer00000000000000from __future__ import absolute_import, unicode_literals from vine.abstract import Thenable from vine.promises import promise class CanThen(object): def then(self, x, y): pass class CannotThen(object): pass class test_Thenable: def test_isa(self): assert isinstance(CanThen(), Thenable) assert not isinstance(CannotThen(), Thenable) def test_promise(self): assert isinstance(promise(lambda x: x), Thenable) vine-1.3.0/t/unit/test_funtools.py0000644000175000017500000000320013414403510017074 0ustar omeromer00000000000000from __future__ import absolute_import, unicode_literals import pytest from case import Mock from vine.abstract import Thenable from vine.funtools import ( maybe_promise, ppartial, preplace, ready_promise, starpromise, transform, wrap, ) from vine.promises import promise def test_wrap(): cb1 = Mock() cb2 = Mock() x = wrap(promise(cb1)) x(1, y=2) cb1.assert_called_with(1, y=2) p2 = promise(cb2) x(p2) p2() cb1.assert_called_with(cb2()) def test_transform(): callback = Mock() def filter_key_value(key, filter_, mapping): return filter_(mapping[key]) x = transform(filter_key_value, promise(callback), 'Value', int) x({'Value': 303}) callback.assert_called_with(303) with pytest.raises(KeyError): x({}) class test_maybe_promise: def test_when_none(self): assert maybe_promise(None) is None def test_when_promise(self): p = promise() assert maybe_promise(p) is p def test_when_other(self): m = Mock() p = maybe_promise(m) assert isinstance(p, Thenable) def test_starpromise(): m = Mock() p = starpromise(m, 1, 2, z=3) p() m.assert_called_with(1, 2, z=3) def test_ready_promise(): m = Mock() p = ready_promise(m, 1, 2, 3) m.assert_called_with(1, 2, 3) assert p.ready def test_ppartial(): m = Mock() p = ppartial(m, 1) p() m.assert_called_with(1) p = ppartial(m, z=2) p() m.assert_called_with(z=2) def test_preplace(): m = Mock() p = promise(m) p2 = preplace(p, 1, 2, z=3) p2(4, 5, x=3) m.assert_called_with(1, 2, z=3) vine-1.3.0/t/unit/test_promises.py0000644000175000017500000002327713444126345017117 0ustar omeromer00000000000000from __future__ import absolute_import, unicode_literals import pytest import sys import traceback from collections import deque from struct import pack, unpack import weakref from case import Mock from vine.funtools import wrap from vine.promises import promise class test_promise: def test_example(self): _pending = deque() class Protocol(object): def __init__(self): self.buffer = [] def read(self, size, callback=None): callback = callback or promise() _pending.append((size, callback)) return callback def read_header(self, callback=None): return self.read(4, callback) def read_body(self, header, callback=None): body_size, = unpack('>L', header) return self.read(body_size, callback) def prepare_body(self, value): self.buffer.append(value) proto = Protocol() proto.read_header().then( proto.read_body).then(wrap(proto.prepare_body)) while _pending: size, callback = _pending.popleft() if size == 4: callback(pack('>L', 1231012302)) else: callback('Hello world') assert proto.buffer assert proto.buffer[0] == 'Hello world' def test_signal(self): callback = Mock(name='callback') a = promise() a.then(callback) a(42) callback.assert_called_once_with(42) def test_signal_callback_kwargs(self): callback = Mock(name='callback') a = promise(callback=callback) a(42) callback.assert_called_once_with(42) def test_call_ignore_result(self): fun = Mock(name='fun') callback = Mock(name='callback') a = promise(fun=fun, ignore_result=True) a.then(callback) a() fun.assert_called_once_with() callback.assert_called_once_with() def test_call_ignore_result_callback_kwarg(self): fun = Mock(name='fun') callback = Mock(name='callback') a = promise(fun=fun, ignore_result=True, callback=callback) a() callback.assert_called_once_with() def test_chained(self): def add(x, y): return x + y def pow2(x): return x ** 2 adder = Mock(name='adder') adder.side_effect = add power = Mock(name='multiplier') power.side_effect = pow2 final = Mock(name='final') p = promise() p.then(adder).then(power).then(final) p(42, 42) assert p.value == ((42, 42), {}) adder.assert_called_with(42, 42) power.assert_called_with(84) final.assert_called_with(7056) def test_shallow_filter(self): a, b = promise(Mock(name='a')), promise(Mock(name='b')) p = promise(a, callback=b) assert p._svpending is not None assert p._lvpending is None p(30) assert p._svpending is None a.fun.assert_called_with(30) b.fun.assert_called_with(a.fun.return_value) c, d = Mock(name='c'), Mock(name='d') promise(c, callback=d)(1) c.assert_called_with(1) d.assert_called_with(c.return_value) def test_deep_filter(self): a = promise(Mock(name='a')) b1, b2, b3 = ( promise(Mock(name='a1')), promise(Mock(name='a2')), promise(Mock(name='a3')), ) p = promise(a) p.then(b1) assert p._lvpending is None assert p._svpending is not None p.then(b2) assert p._lvpending is not None assert p._svpending is None p.then(b3) p(42) a.fun.assert_called_with(42) b1.fun.assert_called_with(a.fun.return_value) b2.fun.assert_called_with(a.fun.return_value) b3.fun.assert_called_with(a.fun.return_value) def test_chained_filter(self): a = promise(Mock(name='a')) b = promise(Mock(name='b')) c = promise(Mock(name='c')) d = promise(Mock(name='d')) p = promise(a) p.then(b).then(c).then(d) p(42, kw=300) a.fun.assert_called_with(42, kw=300) b.fun.assert_called_with(a.fun.return_value) c.fun.assert_called_with(b.fun.return_value) d.fun.assert_called_with(c.fun.return_value) def test_repr(self): assert repr(promise()) assert repr(promise(Mock())) def test_cancel(self): on_error = promise(Mock(name='on_error')) p = promise(on_error=on_error) a, b, c = ( promise(Mock(name='a')), promise(Mock(name='b')), promise(Mock(name='c')), ) a2 = promise(Mock(name='a1')) p.then(a).then(b).then(c) p.then(a2) p.cancel() p(42) assert p.cancelled assert a.cancelled assert a2.cancelled assert b.cancelled assert c.cancelled assert on_error.cancelled d = promise(Mock(name='d')) p.then(d) assert d.cancelled def test_svpending_raises(self): p = promise() a_on_error = promise(Mock(name='a_on_error')) a = promise(Mock(name='a'), on_error=a_on_error) p.then(a) exc = KeyError() a.fun.side_effect = exc p(42) a_on_error.fun.assert_called_with(exc) def test_empty_promise(self): p = promise() p(42) x = Mock(name='x') p.then(x) x.assert_called_with(42) def test_with_partial_args(self): m = Mock(name='m') p = promise(m, (1, 2, 3), {'foobar': 2}) p() m.assert_called_with(1, 2, 3, foobar=2) def test_with_partial_args_and_args(self): m = Mock(name='m') p = promise(m, (1, 2, 3), {'foobar': 2}) p(4, 5, bazbar=3) m.assert_called_with(1, 2, 3, 4, 5, foobar=2, bazbar=3) def test_lvpending_raises(self): p = promise() a_on_error = promise(Mock(name='a_on_error')) a = promise(Mock(name='a'), on_error=a_on_error) b_on_error = promise(Mock(name='b_on_error')) b = promise(Mock(name='a'), on_error=b_on_error) p.then(a) p.then(b) exc = KeyError() a.fun.side_effect = exc a.then(Mock(name='foobar')) a.then(Mock(name='foozi')) p.on_error = a_on_error p(42) a_on_error.fun.assert_called_with(exc) b.fun.assert_called_with(42) def test_cancel_sv(self): p = promise() a = promise(Mock(name='a')) p.then(a) p.cancel() assert p.cancelled assert a.cancelled p.throw(KeyError()) p.throw1(KeyError()) def test_cancel_no_cb(self): p = promise() p.cancel() assert p.cancelled assert p.on_error is None p.throw(KeyError()) def test_throw_no_exc(self): p = promise() with pytest.raises((TypeError, RuntimeError)): p.throw() def test_throw_no_excinfo(self): p = promise() with pytest.raises(KeyError): p.throw(KeyError()) def test_throw_with_tb(self): p = promise() def foo(): raise KeyError() try: foo() except KeyError: try: p.throw() except KeyError: err = traceback.format_exc() assert 'in foo\n raise KeyError()' in err else: raise AssertionError('Did not throw.') def test_throw_with_other_tb(self): p = promise() def foo(): raise KeyError() def bar(): raise ValueError() try: bar() except ValueError: tb = sys.exc_info()[2] try: foo() except KeyError as exc: try: p.throw(exc, tb) except KeyError: err = traceback.format_exc() assert 'in bar\n raise ValueError()' in err else: raise AssertionError('Did not throw.') def test_throw_None(self): try: raise KeyError() except Exception: with pytest.raises(KeyError): promise().throw() def test_listeners(self): p = promise() p.then(Mock()) assert len(p.listeners) == 1 p.then(Mock()) assert len(p.listeners) == 2 def test_throw_from_cb(self): ae = promise(Mock(name='ae')) a = Mock(name='a') be = promise(Mock(name='be')) b = promise(Mock(name='b'), on_error=be) ce = promise(Mock(name='ce')) c = promise(Mock(name='c'), on_error=ce) exc = a.side_effect = KeyError() p1 = promise(a, on_error=ae) p1.then(b) assert p1._svpending p1(42) p1.on_error.fun.assert_called_with(exc) p2 = promise(a) p2.then(b).then(c) with pytest.raises(KeyError): p2(42) de = promise(Mock(name='de')) d = promise(Mock(name='d'), on_error=de) p2.then(d) de.fun.assert_called_with(exc) def test_weak_reference_unbound(self): def f(x): return x ** 2 promise_f = promise(f, weak=True) assert isinstance(promise_f.fun, weakref.ref) assert promise_f(2) == 4 def test_weak_reference_bound(self): class Example(object): def __init__(self, y): self.y = y def f(self, x): return self.y + x ** 2 example = Example(5) promise_f = promise(example.f, weak=True) assert isinstance(promise_f.fun, weakref.ref) assert promise_f(2) == 9 vine-1.3.0/t/unit/test_synchronization.py0000644000175000017500000000230213414403510020466 0ustar omeromer00000000000000from __future__ import absolute_import, unicode_literals import pytest from case import Mock from vine.promises import promise from vine.synchronization import barrier class test_barrier: def setup(self): self.m1, self.m2, self.m3 = Mock(), Mock(), Mock() self.ps = [promise(self.m1), promise(self.m2), promise(self.m3)] def test_evaluate(self): x = barrier(self.ps) x() assert not x.ready x() assert not x.ready x.add(promise()) x() assert not x.ready x() assert x.ready x() x() with pytest.raises(ValueError): x.add(promise()) def test_reverse(self): callback = Mock() x = barrier(self.ps, callback=promise(callback)) for p in self.ps: p() assert x.ready callback.assert_called_with() def test_cancel(self): x = barrier(self.ps) x.cancel() for p in self.ps: p() x.add(promise()) x.throw(KeyError()) assert not x.ready def test_throw(self): x = barrier(self.ps) with pytest.raises(KeyError): x.throw(KeyError(10)) vine-1.3.0/vine/0000755000175000017500000000000013444127245013351 5ustar omeromer00000000000000vine-1.3.0/vine/__init__.py0000644000175000017500000000211013444127200015443 0ustar omeromer00000000000000"""Promises, promises, promises.""" from __future__ import absolute_import, unicode_literals import re from collections import namedtuple from .abstract import Thenable from .promises import promise from .synchronization import barrier from .funtools import ( maybe_promise, ensure_promise, ppartial, preplace, starpromise, transform, wrap, ) __version__ = '1.3.0' __author__ = 'Ask Solem' __contact__ = 'ask@celeryproject.org' __homepage__ = 'http://github.com/celery/vine' __docformat__ = 'restructuredtext' # -eof meta- version_info_t = namedtuple('version_info_t', ( 'major', 'minor', 'micro', 'releaselevel', 'serial', )) # bump version can only search for {current_version} # so we have to parse the version here. _temp = re.match( r'(\d+)\.(\d+).(\d+)(.+)?', __version__).groups() VERSION = version_info = version_info_t( int(_temp[0]), int(_temp[1]), int(_temp[2]), _temp[3] or '', '') del(_temp) del(re) __all__ = [ 'Thenable', 'promise', 'barrier', 'maybe_promise', 'ensure_promise', 'ppartial', 'preplace', 'starpromise', 'transform', 'wrap', ] vine-1.3.0/vine/abstract.py0000644000175000017500000000324313414403510015515 0ustar omeromer00000000000000"""Abstract classes.""" from __future__ import absolute_import, unicode_literals import abc from .five import with_metaclass, Callable __all__ = ['Thenable'] @with_metaclass(abc.ABCMeta) class Thenable(Callable): # pragma: no cover """Object that supports ``.then()``.""" __slots__ = () @abc.abstractmethod def then(self, on_success, on_error=None): raise NotImplementedError() @abc.abstractmethod def throw(self, exc=None, tb=None, propagate=True): raise NotImplementedError() @abc.abstractmethod def cancel(self): raise NotImplementedError() @classmethod def __subclasshook__(cls, C): if cls is Thenable: if any('then' in B.__dict__ for B in C.__mro__): return True return NotImplemented @classmethod def register(cls, other): # overide to return other so `register` can be used as a decorator type(cls).register(cls, other) return other @Thenable.register class ThenableProxy(object): """Proxy to object that supports ``.then()``.""" def _set_promise_target(self, p): self._p = p def then(self, on_success, on_error=None): return self._p.then(on_success, on_error) def cancel(self): return self._p.cancel() def throw1(self, exc=None): return self._p.throw1(exc) def throw(self, exc=None, tb=None, propagate=True): return self._p.throw(exc, tb=tb, propagate=propagate) @property def cancelled(self): return self._p.cancelled @property def ready(self): return self._p.ready @property def failed(self): return self._p.failed vine-1.3.0/vine/backports/0000755000175000017500000000000013444127245015341 5ustar omeromer00000000000000vine-1.3.0/vine/backports/__init__.py0000644000175000017500000000000013414403510017425 0ustar omeromer00000000000000vine-1.3.0/vine/backports/weakref_backports.py0000644000175000017500000000432613414403510021401 0ustar omeromer00000000000000"""Weakref compatibility. weakref_backports is a partial backport of the weakref module for Python versions below 3.4. Copyright (C) 2013 Python Software Foundation, see LICENSE.python for details. The following changes were made to the original sources during backporting: * Added ``self`` to ``super`` calls. * Removed ``from None`` when raising exceptions. """ from __future__ import absolute_import, unicode_literals from weakref import ref class WeakMethod(ref): """Weak reference to bound method. A custom :class:`weakref.ref` subclass which simulates a weak reference to a bound method, working around the lifetime problem of bound methods. """ __slots__ = '_func_ref', '_meth_type', '_alive', '__weakref__' def __new__(cls, meth, callback=None): try: obj = meth.__self__ func = meth.__func__ except AttributeError: raise TypeError( "Argument should be a bound method, not {0}".format( type(meth))) def _cb(arg): # The self-weakref trick is needed to avoid creating a # reference cycle. self = self_wr() if self._alive: self._alive = False if callback is not None: callback(self) self = ref.__new__(cls, obj, _cb) self._func_ref = ref(func, _cb) self._meth_type = type(meth) self._alive = True self_wr = ref(self) return self def __call__(self): obj = super(WeakMethod, self).__call__() func = self._func_ref() if obj is not None and func is not None: return self._meth_type(func, obj) def __eq__(self, other): if not isinstance(other, WeakMethod): return False if not self._alive or not other._alive: return self is other return ref.__eq__(self, other) and self._func_ref == other._func_ref def __ne__(self, other): if not isinstance(other, WeakMethod): return True if not self._alive or not other._alive: return self is not other return ref.__ne__(self, other) or self._func_ref != other._func_ref __hash__ = ref.__hash__ vine-1.3.0/vine/five.py0000644000175000017500000002616513414403510014653 0ustar omeromer00000000000000# -*- coding: utf-8 -*- """Python 2/3 compatibility. Compatibility implementations of features only available in newer Python versions. """ from __future__ import absolute_import, unicode_literals import errno import io import sys try: from collections import Counter except ImportError: # pragma: no cover from collections import defaultdict def Counter(): # noqa """Create counter.""" return defaultdict(int) try: buffer_t = buffer except NameError: # pragma: no cover # Py3 does not have buffer, only use this for isa checks. class buffer_t(object): # noqa """Python 3 does not have a buffer type.""" bytes_t = bytes __all__ = [ 'Counter', 'reload', 'UserList', 'UserDict', 'Callable', 'Iterable', 'Mapping', 'Queue', 'Empty', 'Full', 'LifoQueue', 'builtins', 'array', 'zip_longest', 'map', 'zip', 'string', 'string_t', 'bytes_t', 'bytes_if_py2', 'long_t', 'text_t', 'int_types', 'module_name_t', 'range', 'items', 'keys', 'values', 'nextfun', 'reraise', 'WhateverIO', 'with_metaclass', 'StringIO', 'getfullargspec', 'THREAD_TIMEOUT_MAX', 'format_d', 'monotonic', 'buffer_t', 'python_2_unicode_compatible', ] # ############# py3k ######################################################## PY3 = sys.version_info[0] >= 3 PY2 = sys.version_info[0] < 3 try: reload = reload # noqa except NameError: # pragma: no cover try: from importlib import reload # noqa except ImportError: # pragma: no cover from imp import reload # noqa try: from collections import UserList # noqa except ImportError: # pragma: no cover from UserList import UserList # noqa try: from collections import UserDict # noqa except ImportError: # pragma: no cover from UserDict import UserDict # noqa try: from collections.abc import Callable # noqa except ImportError: # pragma: no cover from collections import Callable # noqa try: from collections.abc import Iterable # noqa except ImportError: # pragma: no cover from collections import Iterable # noqa try: from collections.abc import Mapping # noqa except ImportError: # pragma: no cover from collections import Mapping # noqa # ############# time.monotonic ############################################# if sys.version_info < (3, 3): import platform SYSTEM = platform.system() try: import ctypes except ImportError: # pragma: no cover ctypes = None # noqa if SYSTEM == 'Darwin' and ctypes is not None: from ctypes.util import find_library libSystem = ctypes.CDLL(find_library('libSystem.dylib')) CoreServices = ctypes.CDLL(find_library('CoreServices'), use_errno=True) mach_absolute_time = libSystem.mach_absolute_time mach_absolute_time.restype = ctypes.c_uint64 absolute_to_nanoseconds = CoreServices.AbsoluteToNanoseconds absolute_to_nanoseconds.restype = ctypes.c_uint64 absolute_to_nanoseconds.argtypes = [ctypes.c_uint64] def _monotonic(): return absolute_to_nanoseconds(mach_absolute_time()) * 1e-9 elif SYSTEM == 'Linux' and ctypes is not None: # from stackoverflow: # questions/1205722/how-do-i-get-monotonic-time-durations-in-python import os CLOCK_MONOTONIC = 1 # see class timespec(ctypes.Structure): _fields_ = [ ('tv_sec', ctypes.c_long), ('tv_nsec', ctypes.c_long), ] try: librt = ctypes.CDLL('librt.so.1', use_errno=True) except Exception: try: librt = ctypes.CDLL('librt.so.0', use_errno=True) except Exception as exc: error = OSError( "Could not detect working librt library: {0}".format( exc)) error.errno = errno.ENOENT raise error clock_gettime = librt.clock_gettime clock_gettime.argtypes = [ ctypes.c_int, ctypes.POINTER(timespec), ] def _monotonic(): # noqa t = timespec() if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0: errno_ = ctypes.get_errno() raise OSError(errno_, os.strerror(errno_)) return t.tv_sec + t.tv_nsec * 1e-9 else: from time import time as _monotonic try: from time import monotonic except ImportError: monotonic = _monotonic # noqa # ############# Py3 <-> Py2 ################################################# if PY3: # pragma: no cover import builtins from array import array from queue import Queue, Empty, Full, LifoQueue from itertools import zip_longest map = map zip = zip string = str string_t = str long_t = int text_t = str range = range int_types = (int,) module_name_t = str def bytes_if_py2(s): """Convert str to bytes if running under Python 2.""" return s def items(d): """Get dict items iterator.""" return d.items() def keys(d): """Get dict keys iterator.""" return d.keys() def values(d): """Get dict values iterator.""" return d.values() def nextfun(it): """Get iterator next method.""" return it.__next__ exec_ = getattr(builtins, 'exec') def reraise(tp, value, tb=None): """Reraise exception.""" if value.__traceback__ is not tb: raise value.with_traceback(tb) raise value else: import __builtin__ as builtins # noqa from array import array as _array from Queue import Queue, Empty, Full, LifoQueue # noqa from itertools import ( # noqa imap as map, izip as zip, izip_longest as zip_longest, ) string = unicode # noqa string_t = basestring # noqa text_t = unicode long_t = long # noqa range = xrange module_name_t = str int_types = (int, long) def array(typecode, *args, **kwargs): """Create array.""" if isinstance(typecode, unicode): typecode = typecode.encode() return _array(typecode, *args, **kwargs) def bytes_if_py2(s): """Convert str to bytes if running under Python 2.""" if isinstance(s, unicode): return s.encode() return s def items(d): # noqa """Return dict items iterator.""" return d.iteritems() def keys(d): # noqa """Return dict key iterator.""" return d.iterkeys() def values(d): # noqa """Return dict values iterator.""" return d.itervalues() def nextfun(it): # noqa """Return iterator next method.""" return it.next def exec_(code, globs=None, locs=None): # pragma: no cover """Execute code in a namespace.""" if globs is None: frame = sys._getframe(1) globs = frame.f_globals if locs is None: locs = frame.f_locals del frame elif locs is None: locs = globs exec("""exec code in globs, locs""") exec_("""def reraise(tp, value, tb=None): raise tp, value, tb""") def with_metaclass(Type, skip_attrs=None): """Class decorator to set metaclass. Works with both Python 2 and Python 3 and it does not add an extra class in the lookup order like ``six.with_metaclass`` does (that is -- it copies the original class instead of using inheritance). """ if skip_attrs is None: skip_attrs = {'__dict__', '__weakref__'} def _clone_with_metaclass(Class): attrs = {key: value for key, value in items(vars(Class)) if key not in skip_attrs} return Type(Class.__name__, Class.__bases__, attrs) return _clone_with_metaclass # ############# threading.TIMEOUT_MAX ######################################## try: from threading import TIMEOUT_MAX as THREAD_TIMEOUT_MAX except ImportError: THREAD_TIMEOUT_MAX = 1e10 # noqa # ############# format(int, ',d') ############################################ if sys.version_info >= (2, 7): # pragma: no cover def format_d(i): """Format number.""" return format(i, ',d') else: # pragma: no cover def format_d(i): # noqa """Format number.""" s = '%d' % i groups = [] while s and s[-1].isdigit(): groups.append(s[-3:]) s = s[:-3] return s + ','.join(reversed(groups)) StringIO = io.StringIO _SIO_write = StringIO.write _SIO_init = StringIO.__init__ class WhateverIO(StringIO): """StringIO that takes bytes or str.""" def __init__(self, v=None, *a, **kw): _SIO_init(self, v.decode() if isinstance(v, bytes) else v, *a, **kw) def write(self, data): _SIO_write(self, data.decode() if isinstance(data, bytes) else data) def python_2_unicode_compatible(cls): """Class decorator to ensure class is compatible with Python 2.""" return python_2_non_unicode_str(python_2_non_unicode_repr(cls)) def python_2_non_unicode_repr(cls): """Ensure cls.__repr__ returns unicode. A class decorator that ensures ``__repr__`` returns non-unicode when running under Python 2. """ if PY2: try: cls.__dict__['__repr__'] except KeyError: pass else: def __repr__(self, *args, **kwargs): return self.__unicode_repr__(*args, **kwargs).encode( 'utf-8', 'replace') cls.__unicode_repr__, cls.__repr__ = cls.__repr__, __repr__ return cls def python_2_non_unicode_str(cls): """Python 2 class string compatibility. A class decorator that defines ``__unicode__`` and ``__str__`` methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a ``__str__`` method returning text and apply this decorator to the class. """ if PY2: try: cls.__dict__['__str__'] except KeyError: pass else: def __str__(self, *args, **kwargs): return self.__unicode__(*args, **kwargs).encode( 'utf-8', 'replace') cls.__unicode__, cls.__str__ = cls.__str__, __str__ return cls try: # pragma: no cover from inspect import formatargspec, getfullargspec except ImportError: # Py2 from collections import namedtuple from inspect import formatargspec, getargspec as _getargspec # noqa FullArgSpec = namedtuple('FullArgSpec', ( 'args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', 'kwonlydefaults', 'annotations', )) def getfullargspec(fun, _fill=(None, ) * 3): # noqa """For compatibility with Python 3.""" s = _getargspec(fun) return FullArgSpec(*s + _fill) vine-1.3.0/vine/funtools.py0000644000175000017500000000554713414403510015574 0ustar omeromer00000000000000"""Functional utilities.""" from __future__ import absolute_import, unicode_literals from .abstract import Thenable from .promises import promise __all__ = [ 'maybe_promise', 'ensure_promise', 'ppartial', 'preplace', 'ready_promise', 'starpromise', 'transform', 'wrap', ] def maybe_promise(p): """Return None if p is unefined, otherwise make sure it's a promise.""" if p: if not isinstance(p, Thenable): return promise(p) return p def ensure_promise(p): """Ensure p is a promise. If p is not a promise, a new promise is created with p' as callback. """ if p is None: return promise() return maybe_promise(p) def ppartial(p, *args, **kwargs): """Create/modify promise with partial arguments.""" p = ensure_promise(p) if args: p.args = args + p.args if kwargs: p.kwargs.update(kwargs) return p def preplace(p, *args, **kwargs): """Replace promise arguments. This will force the promise to disregard any arguments the promise is fulfilled with, and to be called with the provided arguments instead. """ def _replacer(*_, **__): return p(*args, **kwargs) return promise(_replacer) def ready_promise(callback=None, *args): """Create promise that is already fulfilled.""" p = ensure_promise(callback) p(*args) return p def starpromise(fun, *args, **kwargs): """Create promise, using star arguments.""" return promise(fun, args, kwargs) def transform(filter_, callback, *filter_args, **filter_kwargs): """Filter final argument to a promise. E.g. to coerce callback argument to :class:`int`:: transform(int, callback) or a more complex example extracting something from a dict and coercing the value to :class:`float`: .. code-block:: python def filter_key_value(key, filter_, mapping): return filter_(mapping[key]) def get_page_expires(self, url, callback=None): return self.request( 'GET', url, callback=transform(get_key, callback, 'PageExpireValue', int), ) """ callback = ensure_promise(callback) P = promise(_transback, (filter_, callback, filter_args, filter_kwargs)) P.then(promise(), callback.throw) return P def _transback(filter_, callback, args, kwargs, ret): try: ret = filter_(*args + (ret,), **kwargs) except Exception: callback.throw() else: return callback(ret) def wrap(p): """Wrap promise. This wraps the promise such that if the promise is called with a promise as argument, we attach ourselves to that promise instead. """ def on_call(*args, **kwargs): if len(args) == 1 and isinstance(args[0], promise): return args[0].then(p) else: return p(*args, **kwargs) return on_call vine-1.3.0/vine/promises.py0000644000175000017500000001733613444126074015575 0ustar omeromer00000000000000"""Promise implementation.""" from __future__ import absolute_import, unicode_literals import sys from collections import deque import inspect from weakref import ref try: from weakref import WeakMethod except ImportError: from vine.backports.weakref_backports import WeakMethod from .abstract import Thenable from .five import python_2_unicode_compatible, reraise __all__ = ['promise'] @Thenable.register @python_2_unicode_compatible class promise(object): """Promise of future evaluation. This is a special implementation of promises in that it can be used both for "promise of a value" and lazy evaluation. The biggest upside for this is that everything in a promise can also be a promise, e.g. filters, callbacks and errbacks can all be promises. Usage examples: .. code-block:: python >>> from __future__ import print_statement # noqa >>> p = promise() >>> p.then(promise(print, ('OK',))) # noqa >>> p.on_error = promise(print, ('ERROR',)) # noqa >>> p(20) OK, 20 >>> p.then(promise(print, ('hello',))) # noqa hello, 20 >>> p.throw(KeyError('foo')) ERROR, KeyError('foo') >>> p2 = promise() >>> p2.then(print) # noqa >>> p2.cancel() >>> p(30) Example: .. code-block:: python from vine import promise, wrap class Protocol(object): def __init__(self): self.buffer = [] def receive_message(self): return self.read_header().then( self.read_body).then( wrap(self.prepare_body)) def read(self, size, callback=None): callback = callback or promise() tell_eventloop_to_read(size, callback) return callback def read_header(self, callback=None): return self.read(4, callback) def read_body(self, header, callback=None): body_size, = unpack('>L', header) return self.read(body_size, callback) def prepare_body(self, value): self.buffer.append(value) """ if not hasattr(sys, 'pypy_version_info'): # pragma: no cover __slots__ = ( 'fun', 'args', 'kwargs', 'ready', 'failed', 'value', 'ignore_result', 'reason', '_svpending', '_lvpending', 'on_error', 'cancelled', 'weak', '__weakref__', ) def __init__(self, fun=None, args=None, kwargs=None, callback=None, on_error=None, weak=False, ignore_result=False): self.weak = weak self.ignore_result = ignore_result self.fun = self._get_fun_or_weakref(fun=fun, weak=weak) self.args = args or () self.kwargs = kwargs or {} self.ready = False self.failed = False self.value = None self.reason = None # Optimization # Most promises will only have one callback, so we optimize for this # case by using a list only when there are multiple callbacks. # s(calar) pending / l(ist) pending self._svpending = None self._lvpending = None self.on_error = on_error self.cancelled = False if callback is not None: self.then(callback) if self.fun: assert self.fun and callable(fun) @staticmethod def _get_fun_or_weakref(fun, weak): """Return the callable or a weak reference. Handles both bound and unbound methods. """ if not weak: return fun if inspect.ismethod(fun): return WeakMethod(fun) else: return ref(fun) def __repr__(self): return ('<{0} --> {1!r}>' if self.fun else '<{0}>').format( '{0}@0x{1:x}'.format(type(self).__name__, id(self)), self.fun, ) def cancel(self): self.cancelled = True try: if self._svpending is not None: self._svpending.cancel() if self._lvpending is not None: for pending in self._lvpending: pending.cancel() if isinstance(self.on_error, Thenable): self.on_error.cancel() finally: self._svpending = self._lvpending = self.on_error = None def __call__(self, *args, **kwargs): retval = None if self.cancelled: return final_args = self.args + args if args else self.args final_kwargs = dict(self.kwargs, **kwargs) if kwargs else self.kwargs # self.fun may be a weakref fun = self._fun_is_alive(self.fun) if fun is not None: try: if self.ignore_result: fun(*final_args, **final_kwargs) ca = () ck = {} else: retval = fun(*final_args, **final_kwargs) self.value = (ca, ck) = (retval,), {} except Exception: return self.throw() else: self.value = (ca, ck) = final_args, final_kwargs self.ready = True svpending = self._svpending if svpending is not None: try: svpending(*ca, **ck) finally: self._svpending = None else: lvpending = self._lvpending try: while lvpending: p = lvpending.popleft() p(*ca, **ck) finally: self._lvpending = None return retval def _fun_is_alive(self, fun): return fun() if self.weak else self.fun def then(self, callback, on_error=None): if not isinstance(callback, Thenable): callback = promise(callback, on_error=on_error) if self.cancelled: callback.cancel() return callback if self.failed: callback.throw(self.reason) elif self.ready: args, kwargs = self.value callback(*args, **kwargs) if self._lvpending is None: svpending = self._svpending if svpending is not None: self._svpending, self._lvpending = None, deque([svpending]) else: self._svpending = callback return callback self._lvpending.append(callback) return callback def throw1(self, exc=None): if not self.cancelled: exc = exc if exc is not None else sys.exc_info()[1] self.failed, self.reason = True, exc if self.on_error: self.on_error(*self.args + (exc,), **self.kwargs) def throw(self, exc=None, tb=None, propagate=True): if not self.cancelled: current_exc = sys.exc_info()[1] exc = exc if exc is not None else current_exc try: self.throw1(exc) svpending = self._svpending if svpending is not None: try: svpending.throw1(exc) finally: self._svpending = None else: lvpending = self._lvpending try: while lvpending: lvpending.popleft().throw1(exc) finally: self._lvpending = None finally: if self.on_error is None and propagate: if tb is None and (exc is None or exc is current_exc): raise reraise(type(exc), exc, tb) @property def listeners(self): if self._lvpending: return self._lvpending return [self._svpending] vine-1.3.0/vine/synchronization.py0000644000175000017500000000533213414403510017154 0ustar omeromer00000000000000"""Synchronization primitives.""" from __future__ import absolute_import, unicode_literals from .abstract import Thenable from .promises import promise __all__ = ['barrier'] class barrier(object): """Barrier. Synchronization primitive to call a callback after a list of promises have been fulfilled. Example: .. code-block:: python # Request supports the .then() method. p1 = http.Request('http://a') p2 = http.Request('http://b') p3 = http.Request('http://c') requests = [p1, p2, p3] def all_done(): pass # all requests complete b = barrier(requests).then(all_done) # oops, we forgot we want another request b.add(http.Request('http://d')) Note that you cannot add new promises to a barrier after the barrier is fulfilled. """ def __init__(self, promises=None, args=None, kwargs=None, callback=None, size=None): self.p = promise() self.args = args or () self.kwargs = kwargs or {} self._value = 0 self.size = size or 0 if not self.size and promises: # iter(l) calls len(l) so generator wrappers # can only return NotImplemented in the case the # generator is not fully consumed yet. plen = promises.__len__() if plen is not NotImplemented: self.size = plen self.ready = self.failed = False self.reason = None self.cancelled = False self.finalized = False [self.add_noincr(p) for p in promises or []] self.finalized = bool(promises or self.size) if callback: self.then(callback) def __call__(self, *args, **kwargs): if not self.ready and not self.cancelled: self._value += 1 if self.finalized and self._value >= self.size: self.ready = True self.p(*self.args, **self.kwargs) def finalize(self): if not self.finalized and self._value >= self.size: self.p(*self.args, **self.kwargs) self.finalized = True def cancel(self): self.cancelled = True self.p.cancel() def add_noincr(self, p): if not self.cancelled: if self.ready: raise ValueError('Cannot add promise to full barrier') p.then(self) def add(self, p): if not self.cancelled: self.add_noincr(p) self.size += 1 def then(self, callback, errback=None): self.p.then(callback, errback) def throw(self, *args, **kwargs): if not self.cancelled: self.p.throw(*args, **kwargs) throw1 = throw Thenable.register(barrier) # noqa: E305 vine-1.3.0/vine/utils.py0000644000175000017500000000135613414403510015055 0ustar omeromer00000000000000"""Python compatibility utilities.""" from __future__ import absolute_import, unicode_literals from functools import ( WRAPPER_ASSIGNMENTS, WRAPPER_UPDATES, update_wrapper as _update_wrapper, partial, ) __all__ = ['update_wrapper', 'wraps'] def update_wrapper(wrapper, wrapped, *args, **kwargs): """Update wrapper, also setting .__wrapped__.""" wrapper = _update_wrapper(wrapper, wrapped, *args, **kwargs) wrapper.__wrapped__ = wrapped return wrapper def wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES): """Backport of Python 3.5 wraps that adds .__wrapped__.""" return partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) vine-1.3.0/vine.egg-info/0000755000175000017500000000000013444127245015043 5ustar omeromer00000000000000vine-1.3.0/vine.egg-info/PKG-INFO0000644000175000017500000000520313444127245016140 0ustar omeromer00000000000000Metadata-Version: 1.2 Name: vine Version: 1.3.0 Summary: Promises, promises, promises. Home-page: http://github.com/celery/vine Author: Ask Solem Author-email: ask@celeryproject.org License: BSD Description: ===================================================================== vine - Python Promises ===================================================================== |build-status| |coverage| |license| |wheel| |pyversion| |pyimp| :Version: 1.3.0 :Web: https://vine.readthedocs.io/ :Download: https://pypi.org/project/vine/ :Source: http://github.com/celery/vine/ :Keywords: promise, async, future About ===== .. |build-status| image:: https://secure.travis-ci.org/celery/vine.png?branch=master :alt: Build status :target: https://travis-ci.org/celery/vine .. |coverage| image:: https://codecov.io/github/celery/vine/coverage.svg?branch=master :target: https://codecov.io/github/celery/vine?branch=master .. |license| image:: https://img.shields.io/pypi/l/vine.svg :alt: BSD License :target: https://opensource.org/licenses/BSD-3-Clause .. |wheel| image:: https://img.shields.io/pypi/wheel/vine.svg :alt: Vine can be installed via wheel :target: https://pypi.org/project/vine/ .. |pyversion| image:: https://img.shields.io/pypi/pyversions/vine.svg :alt: Supported Python versions. :target: https://pypi.org/project/vine/ .. |pyimp| image:: https://img.shields.io/pypi/implementation/vine.svg :alt: Support Python implementations. :target: https://pypi.org/project/vine/ Keywords: promise promises lazy future futures Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 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 :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: License :: OSI Approved :: BSD License Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* vine-1.3.0/vine.egg-info/SOURCES.txt0000644000175000017500000000223313444127245016727 0ustar omeromer00000000000000Changelog LICENSE MANIFEST.in README.rst setup.cfg setup.py docs/Makefile docs/changelog.rst docs/conf.py docs/index.rst docs/make.bat docs/_static/.keep docs/_templates/sidebardonations.html docs/images/celery_128.png docs/images/favicon.ico docs/includes/introduction.txt docs/reference/index.rst docs/reference/vine.abstract.rst docs/reference/vine.backports.rst docs/reference/vine.backports.weakref_backports.rst docs/reference/vine.five.rst docs/reference/vine.funtools.rst docs/reference/vine.promises.rst docs/reference/vine.synchronization.rst docs/reference/vine.utils.rst docs/templates/readme.txt requirements/docs.txt requirements/pkgutils.txt requirements/test-ci.txt requirements/test.txt t/__init__.py t/unit/__init__.py t/unit/conftest.py t/unit/test_abstract.py t/unit/test_funtools.py t/unit/test_promises.py t/unit/test_synchronization.py vine/__init__.py vine/abstract.py vine/five.py vine/funtools.py vine/promises.py vine/synchronization.py vine/utils.py vine.egg-info/PKG-INFO vine.egg-info/SOURCES.txt vine.egg-info/dependency_links.txt vine.egg-info/not-zip-safe vine.egg-info/top_level.txt vine/backports/__init__.py vine/backports/weakref_backports.pyvine-1.3.0/vine.egg-info/dependency_links.txt0000644000175000017500000000000113444127245021111 0ustar omeromer00000000000000 vine-1.3.0/vine.egg-info/not-zip-safe0000644000175000017500000000000113444127245017271 0ustar omeromer00000000000000 vine-1.3.0/vine.egg-info/top_level.txt0000644000175000017500000000000513444127245017570 0ustar omeromer00000000000000vine