[Python-modules-commits] [python-click-threading] 01/05: Import python-click-threading_0.4.2.orig.tar.gz

Ondřej Nový onovy at moszumanska.debian.org
Wed Dec 28 21:54:43 UTC 2016


This is an automated email from the git hooks/post-receive script.

onovy pushed a commit to branch master
in repository python-click-threading.

commit ddbbcb36c608e7a1b1ef5e5a781cb82c23c4ac96
Author: Ondřej Nový <onovy at debian.org>
Date:   Wed Dec 28 22:51:39 2016 +0100

    Import python-click-threading_0.4.2.orig.tar.gz
---
 .travis.yml                 |   3 +-
 MANIFEST.in                 |   5 +
 Makefile                    |   5 +
 README.rst                  |   6 +-
 click_threading/__init__.py |  59 +++++++++-
 click_threading/monkey.py   |  57 +++++++--
 docs/Makefile               | 225 +++++++++++++++++++++++++++++++++++
 docs/conf.py                | 112 ++++++++++++++++++
 docs/index.rst              |   6 +
 docs/make.bat               | 281 ++++++++++++++++++++++++++++++++++++++++++++
 docs/threading.rst          |   7 ++
 docs/uiworker.rst           |   7 ++
 setup.cfg                   |   3 +
 tests/test_basic.py         |  41 ++++++-
 14 files changed, 798 insertions(+), 19 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index dfb9017..eae7bcd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,5 +6,6 @@ python:
     - 3.3
     - 3.4
 
-install: pip install tox
+install:
+   - pip install -U tox setuptools wheel $(python -V |& grep -q 'Python 3.2' && echo 'pip<8.0 virtualenv<14.0')
 script: tox
diff --git a/MANIFEST.in b/MANIFEST.in
index 1aba38f..b60c198 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1 +1,6 @@
 include LICENSE
+recursive-include docs *
+recursive-include tests *
+
+prune docs/_build
+global-exclude *.py[cdo] __pycache__ *.so *.pyd
diff --git a/Makefile b/Makefile
index d257e7b..902b6ed 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,7 @@
 release:
 	python setup.py sdist bdist_wheel upload
+
+docs:
+	cd docs && make html
+
+.PHONY: docs
diff --git a/README.rst b/README.rst
index b61d024..4bcb403 100644
--- a/README.rst
+++ b/README.rst
@@ -4,10 +4,12 @@ click-threading
 .. image:: https://travis-ci.org/click-contrib/click-threading.svg?branch=master
     :target: https://travis-ci.org/click-contrib/click-threading
 
+.. image:: https://readthedocs.org/projects/click-threading/badge/?version=latest
+    :target: http://click-threading.readthedocs.io/en/latest/?badge=latest
+    :alt: Documentation Status
 
-Utilities for multithreading in `click <http://click.pocoo.org/>`_.
 
-*This is rather experimental.  See tests for usage for now.*
+Utilities for multithreading in `click <http://click.pocoo.org/>`_.
 
 License
 =======
diff --git a/click_threading/__init__.py b/click_threading/__init__.py
index 16cde06..7d9eab6 100644
--- a/click_threading/__init__.py
+++ b/click_threading/__init__.py
@@ -17,11 +17,11 @@ except ImportError:
 # Executors", but since I'm basically implementing my own executor here, I
 # think we're fine.
 try:
-    from concurrent.futures import Future
+    from concurrent.futures import Future as _Future
 except ImportError:
-    from futures import Future
+    from futures import Future as _Future
 
-__version__ = '0.4.0'
+__version__ = '0.4.2'
 
 _CTX_WORKER_KEY = __name__ + '.uiworker'
 
@@ -33,7 +33,21 @@ def _is_main_thread(thread=None):
 
 class Thread(threading.Thread):
     '''A thread that automatically pushes the parent thread's context in the
-    new thread.'''
+    new thread.
+
+    Since version 5.0, click maintains global stacks of context objects. The
+    topmost context on that stack can be accessed with
+    :py:func:`get_current_context`.
+
+    There is one stack for each Python thread. That means if you are in the
+    main thread (where you can use :py:func:`get_current_context` just fine)
+    and spawn a :py:class:`threading.Thread`, that thread won't be able to
+    access the same context using :py:func:`get_current_context`.
+
+    :py:class:`Thread` is a subclass of :py:class:`threading.Thread` that
+    preserves the current thread context when spawning a new one, by pushing it
+    on the stack of the new thread as well.
+    '''
 
     def __init__(self, *args, **kwargs):
         self._click_context = click.get_current_context()
@@ -45,6 +59,41 @@ class Thread(threading.Thread):
 
 
 class UiWorker(object):
+    '''
+    A worker-queue system to manage and synchronize output and prompts from
+    other threads.
+
+    >>> import click
+    >>> from click_threading import UiWorker, Thread, get_ui_worker
+    >>> ui = UiWorker()  # on main thread
+    >>> def target():
+    ...     click.echo("Hello world!")
+    ...     get_ui_worker().shutdown()
+    ...
+    >>>
+    >>> @click.command()
+    ... def cli():
+    ...     with ui.patch_click():
+    ...         t = Thread(target=target)
+    ...         t.start()
+    ...         ui.run()
+    >>> runner = click.testing.CliRunner()
+    >>> result = runner.invoke(cli, [])
+    >>> assert result.output.strip() == 'Hello world!'
+
+    Using this class instead of just spawning threads brings a few advantages:
+
+    - If one thread prompts for input, other output from other threads is
+      queued until the :py:func:`click.prompt` call returns.
+    - If you call echo with a multiline-string, it is guaranteed that this
+      string is not interleaved with other output.
+
+    Disadvantages:
+
+    - The main thread is used for the output (using any other thread produces
+      weird behavior with interrupts). ``ui.run()`` in the above example blocks
+      until ``ui.shutdown()`` is called.
+    '''
     SHUTDOWN = object()
 
     def __init__(self):
@@ -73,7 +122,7 @@ class UiWorker(object):
         if _is_main_thread():
             return func()
 
-        future = Future()
+        future = _Future()
         self.tasks.put((func, future))
         if not wait:
             return
diff --git a/click_threading/monkey.py b/click_threading/monkey.py
index 93f426f..4eb2662 100644
--- a/click_threading/monkey.py
+++ b/click_threading/monkey.py
@@ -1,11 +1,17 @@
 # -*- coding: utf-8 -*-
 
+import types
 import contextlib
+import inspect
+
+from ._compat import PY2
+
 
 class FunctionInfo(object):
     def __init__(self, interactive):
         self.interactive = interactive
 
+
 _ui_functions = {
     'echo_via_pager': FunctionInfo(interactive=True),
     'prompt': FunctionInfo(interactive=True),
@@ -23,17 +29,52 @@ _ui_functions = {
 def patch_ui_functions(wrapper):
     '''Wrap all termui functions with a custom decorator.'''
     NONE = object()
-    saved = {}
     import click
 
-    for name, info in _ui_functions.items():
-        orig = getattr(click, name, NONE)
-        if orig is not NONE:
-            saved[name] = orig
-            setattr(click, name, wrapper(orig, info))
+    saved = []
+
+    for name, info in sorted(_ui_functions.items()):
+        f = getattr(click, name, NONE)
+        if f is NONE:
+            continue
+
+        new_f = wrapper(_copy_fn(f), info)
+
+        argspec = inspect.getargspec(f)
+        signature = inspect.formatargspec(*argspec) \
+            .lstrip('(') \
+            .rstrip(')')
+        args = ', '.join(arg.split('=')[0].split(':')[0].strip()
+                         for arg in signature.split(','))
+
+        stub_f = eval('lambda {s}: {n}._real_click_fn({a})'
+                      .format(n=f.__name__, s=signature, a=args))
+
+        if PY2:
+            saved.append((f, f.func_code))
+            f.func_code = stub_f.func_code
+        else:
+            saved.append((f, f.__code__))
+            f.__code__ = stub_f.__code__
+
+        f._real_click_fn = new_f
 
     try:
         yield
     finally:
-        for name, orig in saved.items():
-            setattr(click, name, orig)
+        for f, code in saved:
+            if PY2:
+                f.func_code = code
+            else:
+                f.__code__ = code
+
+            del f._real_click_fn
+
+
+def _copy_fn(f):
+    if PY2:
+        return types.FunctionType(f.func_code, f.func_globals, f.func_name,
+                                  f.func_defaults, f.func_closure)
+    else:
+        return types.FunctionType(f.__code__, f.__globals__, f.__name__,
+                                  f.__defaults__, f.__closure__)
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..a49e6a4
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,225 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# 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 <target>' where <target> 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 "  dummy      to check syntax errors of document sources"
+
+.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/click-threading.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/click-threading.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/click-threading"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/click-threading"
+	@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: 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."
+
+.PHONY: dummy
+dummy:
+	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
+	@echo
+	@echo "Build finished. Dummy builder generates no files."
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..9e2d488
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import pkg_resources
+
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.viewcode',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'click_threading'
+
+with open(os.path.join(os.path.dirname(__file__), '../LICENSE')) as f:
+    copyright = next(iter(f))[len('Copyright (c) '):]
+
+try:
+    # The full version, including alpha/beta/rc tags.
+    release = pkg_resources.require(project)[0].version
+except pkg_resources.DistributionNotFound:
+    print('To build the documentation, the distribution information of '
+          '{} has to be available. Run "setup.py develop" to do '
+          'this.'.format(project))
+    sys.exit(1)
+
+version = '.'.join(release.split('.')[:2])  # The short X.Y version.
+
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+try:
+    import sphinx_rtd_theme
+    html_theme = 'sphinx_rtd_theme'
+    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+except ImportError:
+    html_theme = 'default'
+    if not on_rtd:
+        print('-' * 74)
+        print('Warning: sphinx-rtd-theme not installed, building with default '
+              'theme.')
+        print('-' * 74)
+
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = '{}doc'.format(project)
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+  ('index', 'atomicwrites.tex', '{} Documentation'.format(project),
+   'Markus Unterwaditzer', 'manual'),
+]
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'atomicwrites', 'atomicwrites Documentation',
+     ['Markus Unterwaditzer'], 1)
+]
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'atomicwrites', 'atomicwrites Documentation',
+   'Markus Unterwaditzer', 'atomicwrites', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Bibliographic Dublin Core info.
+epub_title = 'atomicwrites'
+epub_author = 'Markus Unterwaditzer'
+epub_publisher = 'Markus Unterwaditzer'
+epub_copyright = copyright
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {
+    'http://docs.python.org/': None,
+    'http://click.pocoo.org/': None,
+}
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..ddae66f
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,6 @@
+Utilities for multithreaded applications with Click
+===================================================
+
+.. toctree::
+   threading
+   uiworker
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..711d86b
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,281 @@
+ at 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 ^<target^>` where ^<target^> 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
+	echo.  dummy      to check syntax errors of document sources
+	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\click-threading.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\click-threading.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
+)
+
+if "%1" == "dummy" (
+	%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. Dummy builder generates no files.
+	goto end
+)
+
+:end
diff --git a/docs/threading.rst b/docs/threading.rst
new file mode 100644
index 0000000..1c6b99d
--- /dev/null
+++ b/docs/threading.rst
@@ -0,0 +1,7 @@
+================
+The Thread class
+================
+
+.. currentmodule:: click_threading
+
+.. autoclass:: click_threading.Thread
diff --git a/docs/uiworker.rst b/docs/uiworker.rst
new file mode 100644
index 0000000..a28d6f7
--- /dev/null
+++ b/docs/uiworker.rst
@@ -0,0 +1,7 @@
+========================================
+Output and prompts from multiple threads
+========================================
+
+.. currentmodule:: click_threading
+
+.. autoclass:: UiWorker
diff --git a/setup.cfg b/setup.cfg
index b090585..423f64a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -4,3 +4,6 @@ universal = 1
 [flake8]
 # W503: Line break before operator
 ignore = W503
+
+[tool:pytest]
+addopts = --doctest-modules --ignore=setup.py
diff --git a/tests/test_basic.py b/tests/test_basic.py
index d705e52..99b69ac 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -1,6 +1,7 @@
 import pytest
 
 import click_threading
+from click_threading._compat import PY2
 
 import click
 from click.testing import CliRunner
@@ -30,15 +31,12 @@ def test_context_pushing_thread(runner):
 
 
 def test_ui_worker_basic(runner):
-    orig_click_prompt = click.prompt
-
     @click.command()
     def cli():
 
         ui = click_threading.UiWorker()
 
         def target():
-            assert click.prompt is not orig_click_prompt
             click.prompt('two')
             ui.shutdown()
 
@@ -54,3 +52,40 @@ def test_ui_worker_basic(runner):
 
     result = runner.invoke(cli, catch_exceptions=False, input='y\n' * 3)
     assert result.output.splitlines() == ['one: y', 'two: y', 'three: y']
+
+
+def test_monkey_patch(capsys):
+    old_echo = click.echo
+    if PY2:
+        old_code = old_echo.func_code
+    else:
+        old_code = old_echo.__code__
+
+    def wrapper(f, info):
+        def new_f(*a, **kw):
+            assert old_echo is not f
+            if PY2:
+                assert f.func_code is old_code
+            else:
+                assert f.__code__ is old_code
+
+            print("LOL")
+            rv = f(*a, **kw)
+            print("LOL")
+            return rv
+        return new_f
+
+    with click_threading.monkey.patch_ui_functions(wrapper):
+        assert click.echo is old_echo
+        click.echo('Hello world')
+
+    assert click.echo is old_echo
+    click.echo('Hello second world')
+
+    out, err = capsys.readouterr()
... 6 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-click-threading.git



More information about the Python-modules-commits mailing list