[Python-modules-commits] [tqdm] 01/04: Import tqdm_4.10.0.orig.tar.gz

Sandro Tosi morph at moszumanska.debian.org
Sat Dec 10 23:39:21 UTC 2016


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

morph pushed a commit to branch master
in repository tqdm.

commit 1298cea41e6a8ca74ff73ab2ce15c0d90bcc458e
Author: Sandro Tosi <morph at debian.org>
Date:   Sat Dec 10 18:35:10 2016 -0500

    Import tqdm_4.10.0.orig.tar.gz
---
 CONTRIBUTE                          |  26 ++++
 Makefile                            |  17 ++-
 PKG-INFO                            |  88 +++++++++--
 README.rst                          |  86 +++++++++--
 examples/include_no_requirements.py |   2 +-
 examples/pandas_progress_apply.py   |   2 +-
 examples/simple_examples.py         |  18 ++-
 setup.py                            |  14 +-
 tox.ini                             |   7 +-
 tqdm.egg-info/PKG-INFO              |  88 +++++++++--
 tqdm/_main.py                       |  39 ++++-
 tqdm/_tqdm.py                       | 185 ++++++++++++++++++----
 tqdm/_tqdm_notebook.py              |  20 +--
 tqdm/_utils.py                      |   1 -
 tqdm/_version.py                    |   2 +-
 tqdm/tests/tests_main.py            |  24 +--
 tqdm/tests/tests_perf.py            |  27 ++--
 tqdm/tests/tests_tqdm.py            | 296 ++++++++++++++++++++++++++++++++++--
 18 files changed, 794 insertions(+), 148 deletions(-)

diff --git a/CONTRIBUTE b/CONTRIBUTE
index 5973a19..8f942cb 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -249,6 +249,32 @@ cannot re-upload another with the same version number
 updating just the metadata is possible: `[python setup.py] make pypimeta`
 
 
+UPDATING GH-PAGES
+-----------------
+
+The most important file is README.rst, which sould always be kept up-to-date
+and in sync with the in-line source documentation. This will affect all of the
+following:
+
+- The [main repository site](https://github.com/tqdm/tqdm) which automatically
+  serves the latest README.rst as well as links to all of github's features.
+  This is the preferred online referral link for tqdm.
+- The [PyPi mirror](https://pypi.python.org/pypi/tqdm) which automatically
+  serves the latest release built from README.rst as well as links to past
+  releases.
+- Many external web crawlers.
+
+
+Additionally (less maintained), there exists:
+
+- A [wiki](https://github.com/tqdm/tqdm/wiki) which is publicly editable.
+- The [gh-pages project](https://tqdm.github.io/tqdm/) which is built from the
+  [gh-pages branch](https://github.com/tqdm/tqdm/tree/gh-pages), which is
+  built using [asv](https://github.com/spacetelescope/asv/).
+- The [gh-pages root](https://tqdm.github.io/) which is built from a separate
+  outdated [github.io repo](https://github.com/tqdm/tqdm.github.io).
+
+
 QUICK DEV SUMMARY
 -----------------
 
diff --git a/Makefile b/Makefile
index 6688e77..7135760 100644
--- a/Makefile
+++ b/Makefile
@@ -48,10 +48,7 @@ all:
 	@+make build
 
 flake8:
-	@+flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/
-	@+flake8 --max-line-length=80 --count --statistics --exit-zero examples/
-	@+flake8 --max-line-length=80 --count --statistics --exit-zero .
-	@+flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/tests/
+	@+flake8 --max-line-length=80 --count --statistics --exit-zero -j 8 --exclude .asv .
 
 test:
 	tox --skip-missing-interpreters
@@ -73,6 +70,18 @@ testperf:  # do not use coverage (which is extremely slow)
 testtimer:
 	nosetests tqdm --with-timer -d -v
 
+testasv:
+	asv run -j 8 HEAD~3..HEAD
+	@make viewasv
+
+testasvfull:
+	asv run -j 8 v1.0.0..master
+	@make testasv
+
+viewasv:
+	asv publish
+	asv preview
+
 distclean:
 	@+make coverclean
 	@+make prebuildclean
diff --git a/PKG-INFO b/PKG-INFO
index 95caff0..33e1f38 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tqdm
-Version: 4.8.4
+Version: 4.10.0
 Summary: A Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Author: tqdm developers
@@ -11,14 +11,15 @@ Description: |Logo|
         tqdm
         ====
         
-        |PyPI-Status| |PyPI-Versions|
+        |PyPI-Status| |PyPI-Versions| |Conda-Forge-Status|
         
-        |Build-Status| |Coverage-Status| |Branch-Coverage-Status|
+        |Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade|
         
         |DOI-URI| |LICENCE|
         
         
-        ``tqdm`` (read taqadum, تقدّم) means "progress" in arabic.
+        ``tqdm`` means "progress" in Arabic (taqadum, تقدّم)
+        and an abbreviation for "I love you so much" in Spanish (te quiero demasiado).
         
         Instantly make your loops show a smart progress meter - just wrap any
         iterable with ``tqdm(iterable)``, and you're done!
@@ -94,6 +95,15 @@ Description: |Logo|
         
             pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm
         
+        Latest Conda release
+        ~~~~~~~~~~~~~~~~~~~~
+        
+        |Conda-Forge-Status|
+        
+        .. code:: sh
+        
+            conda install -c conda-forge tqdm
+        
         
         Changelog
         ---------
@@ -254,15 +264,15 @@ Description: |Logo|
             The number of expected iterations. If (default: None),
             len(iterable) is used if possible. As a last resort, only basic
             progress statistics are displayed (no ETA, no progressbar).
-            If `gui` is True and this parameter needs subsequent updating,
+            If ``gui`` is True and this parameter needs subsequent updating,
             specify an initial arbitrary large positive integer,
             e.g. int(9e9).
         * leave  : bool, optional  
             If [default: True], keeps all traces of the progressbar
             upon termination of iteration.
-        * file  : `io.TextIOWrapper` or `io.StringIO`, optional  
+        * file  : ``io.TextIOWrapper`` or ``io.StringIO``, optional  
             Specifies where to output the progress messages
-            [default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
+            [default: sys.stderr]. Uses ``file.write(str)`` and ``file.flush()``
             methods.
         * ncols  : int, optional  
             The width of the entire output message. If specified,
@@ -271,15 +281,23 @@ Description: |Logo|
             fallback is a meter width of 10 and no limit for the counter and
             statistics. If 0, will not print any meter (only stats).
         * mininterval  : float, optional  
-            Minimum progress update interval, in seconds [default: 0.1].
+            Minimum progress display update interval, in seconds [default: 0.1].
         * maxinterval  : float, optional  
-            Maximum progress update interval, in seconds [default: 10.0].
+            Maximum progress display update interval, in seconds [default: 10].
+            Automatically adjusts ``miniters`` to correspond to ``mininterval``
+            after long display update lag. Only works if ``dynamic_miniters``
+            or monitor thread is enabled.
         * miniters  : int, optional  
-            Minimum progress update interval, in iterations.
-            If specified, will set `mininterval` to 0.
+            Minimum progress display update interval, in iterations.
+            If 0 and ``dynamic_miniters``, will automatically adjust to equal
+            ``mininterval`` (more CPU efficient, good for tight loops).
+            If > 0, will skip display of specified number of iterations.
+            Tweak this and ``mininterval`` to get very efficient loops.
+            If your progress is erratic with both fast and slow iterations
+            (network, skipping items, etc) you should set miniters=1.
         * ascii  : bool, optional  
             If unspecified or False, use unicode (smooth blocks) to fill
-            the meter. The fallback is to use ASCII characters `1-9 #`.
+            the meter. The fallback is to use ASCII characters ``1-9 #``.
         * disable  : bool, optional  
             Whether to disable the entire progressbar wrapper
             [default: False].
@@ -292,7 +310,7 @@ Description: |Logo|
             International System of Units standard will be added
             (kilo, mega, etc.) [default: False].
         * dynamic_ncols  : bool, optional  
-            If set, constantly alters `ncols` to the environment (allowing
+            If set, constantly alters ``ncols`` to the environment (allowing
             for window resizes) [default: False].
         * smoothing  : float, optional  
             Exponential moving average smoothing factor for speed estimates
@@ -321,7 +339,9 @@ Description: |Logo|
             N.B.: on Windows systems, Python converts '\n' to '\r\n'.
         * buf_size  : int, optional  
             String buffer size in bytes [default: 256]
-            used when `delim` is specified.
+            used when ``delim`` is specified.
+        * bytes  : bool, optional  
+            If true, will count bytes and ignore ``delim``.
         
         Returns
         ~~~~~~~
@@ -341,7 +361,7 @@ Description: |Logo|
                   ...    t.update(len(current_buffer))
                   >>> t.close()
                   The last line is highly recommended, but possibly not necessary if
-                  `t.update()` will be called in such a way that `filesize` will be
+                  ``t.update()`` will be called in such a way that ``filesize`` will be
                   exactly reached and printed.
         
                   Parameters
@@ -405,7 +425,7 @@ Description: |Logo|
           folder;
         - import the module and run ``help()``, or
         - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__.
-            - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-Make-a-Great-Progressbar>`__ on how to make a **great** progressbar.
+            - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar.
         
         Nested progress bars
         ~~~~~~~~~~~~~~~~~~~~
@@ -630,6 +650,38 @@ Description: |Logo|
             # After the `with`, printing is restored
             print('Done!')
         
+        Monitoring thread, intervals and miniters
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        ``tqdm`` implements a few tricks to to increase efficiency and reduce overhead.
+        
+        1. Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long
+           to wait between each refresh. ``tqdm`` always gets updated in the background,
+           but it will diplay only every ``mininterval``.
+        2. Reduce number of calls to check system clock/time.
+        3. ``mininterval`` is more intuitive to configure than ``miniters``.
+           A clever adjustment system ``dynamic_miniters`` will automatically adjust
+           ``miniters`` to the amount of iterations that fit into time ``mininterval``.
+           Essentially, ``tqdm`` will check if it's time to print without actually
+           checking time. This behavior can be still be bypassed by manually setting
+           ``miniters``.
+        
+        However, consider a case with a combination of fast and slow iterations.
+        After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a
+        large number. When interation rate subsequently slows, ``miniters`` will
+        remain large and thus reduce display update frequency. To address this:
+        
+        4. ``maxinterval`` defines the maximum time between display refreshes.
+           A concurrent monitoring thread checks for overdue updates and forces one
+           where necessary.
+        
+        The monitoring thread should not have a noticeable overhead, and guarantees
+        updates at least every 10 seconds by default.
+        This value can be directly changed by setting the ``monitor_interval`` of
+        any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).
+        The monitor thread may be disabled application-wide by setting
+        ``tqdm.tqdm.monitor_interval = 0`` before instantiatiation of any ``tqdm`` bar.
+        
         
         Contributions
         -------------
@@ -674,6 +726,8 @@ Description: |Logo|
            :target: https://coveralls.io/r/tqdm/tqdm
         .. |Branch-Coverage-Status| image:: https://codecov.io/github/tqdm/tqdm/coverage.svg?branch=master
            :target: https://codecov.io/github/tqdm/tqdm?branch=master
+        .. |Codacy-Grade| image:: https://api.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177
+           :target: https://www.codacy.com/app/tqdm/tqdm?utm_source=github.com&utm_medium=referral&utm_content=tqdm/tqdm&utm_campaign=Badge_Grade
         .. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=2592000
            :target: https://github.com/tqdm/tqdm/releases
         .. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg
@@ -686,6 +740,8 @@ Description: |Logo|
            :target: https://pypi.python.org/pypi/tqdm
         .. |PyPI-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg
            :target: https://pypi.python.org/pypi/tqdm
+        .. |Conda-Forge-Status| image:: https://anaconda.org/conda-forge/tqdm/badges/version.svg
+           :target: https://anaconda.org/conda-forge/tqdm
         .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg
            :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE
         .. |DOI-URI| image:: https://zenodo.org/badge/21637/tqdm/tqdm.svg
diff --git a/README.rst b/README.rst
index 958474b..77cda1b 100644
--- a/README.rst
+++ b/README.rst
@@ -3,14 +3,15 @@
 tqdm
 ====
 
-|PyPI-Status| |PyPI-Versions|
+|PyPI-Status| |PyPI-Versions| |Conda-Forge-Status|
 
-|Build-Status| |Coverage-Status| |Branch-Coverage-Status|
+|Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade|
 
 |DOI-URI| |LICENCE|
 
 
-``tqdm`` (read taqadum, تقدّم) means "progress" in arabic.
+``tqdm`` means "progress" in Arabic (taqadum, تقدّم)
+and an abbreviation for "I love you so much" in Spanish (te quiero demasiado).
 
 Instantly make your loops show a smart progress meter - just wrap any
 iterable with ``tqdm(iterable)``, and you're done!
@@ -86,6 +87,15 @@ Pull and install in the current directory:
 
     pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm
 
+Latest Conda release
+~~~~~~~~~~~~~~~~~~~~
+
+|Conda-Forge-Status|
+
+.. code:: sh
+
+    conda install -c conda-forge tqdm
+
 
 Changelog
 ---------
@@ -246,15 +256,15 @@ Parameters
     The number of expected iterations. If (default: None),
     len(iterable) is used if possible. As a last resort, only basic
     progress statistics are displayed (no ETA, no progressbar).
-    If `gui` is True and this parameter needs subsequent updating,
+    If ``gui`` is True and this parameter needs subsequent updating,
     specify an initial arbitrary large positive integer,
     e.g. int(9e9).
 * leave  : bool, optional  
     If [default: True], keeps all traces of the progressbar
     upon termination of iteration.
-* file  : `io.TextIOWrapper` or `io.StringIO`, optional  
+* file  : ``io.TextIOWrapper`` or ``io.StringIO``, optional  
     Specifies where to output the progress messages
-    [default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
+    [default: sys.stderr]. Uses ``file.write(str)`` and ``file.flush()``
     methods.
 * ncols  : int, optional  
     The width of the entire output message. If specified,
@@ -263,15 +273,23 @@ Parameters
     fallback is a meter width of 10 and no limit for the counter and
     statistics. If 0, will not print any meter (only stats).
 * mininterval  : float, optional  
-    Minimum progress update interval, in seconds [default: 0.1].
+    Minimum progress display update interval, in seconds [default: 0.1].
 * maxinterval  : float, optional  
-    Maximum progress update interval, in seconds [default: 10.0].
+    Maximum progress display update interval, in seconds [default: 10].
+    Automatically adjusts ``miniters`` to correspond to ``mininterval``
+    after long display update lag. Only works if ``dynamic_miniters``
+    or monitor thread is enabled.
 * miniters  : int, optional  
-    Minimum progress update interval, in iterations.
-    If specified, will set `mininterval` to 0.
+    Minimum progress display update interval, in iterations.
+    If 0 and ``dynamic_miniters``, will automatically adjust to equal
+    ``mininterval`` (more CPU efficient, good for tight loops).
+    If > 0, will skip display of specified number of iterations.
+    Tweak this and ``mininterval`` to get very efficient loops.
+    If your progress is erratic with both fast and slow iterations
+    (network, skipping items, etc) you should set miniters=1.
 * ascii  : bool, optional  
     If unspecified or False, use unicode (smooth blocks) to fill
-    the meter. The fallback is to use ASCII characters `1-9 #`.
+    the meter. The fallback is to use ASCII characters ``1-9 #``.
 * disable  : bool, optional  
     Whether to disable the entire progressbar wrapper
     [default: False].
@@ -284,7 +302,7 @@ Parameters
     International System of Units standard will be added
     (kilo, mega, etc.) [default: False].
 * dynamic_ncols  : bool, optional  
-    If set, constantly alters `ncols` to the environment (allowing
+    If set, constantly alters ``ncols`` to the environment (allowing
     for window resizes) [default: False].
 * smoothing  : float, optional  
     Exponential moving average smoothing factor for speed estimates
@@ -313,7 +331,9 @@ Extra CLI Options
     N.B.: on Windows systems, Python converts '\n' to '\r\n'.
 * buf_size  : int, optional  
     String buffer size in bytes [default: 256]
-    used when `delim` is specified.
+    used when ``delim`` is specified.
+* bytes  : bool, optional  
+    If true, will count bytes and ignore ``delim``.
 
 Returns
 ~~~~~~~
@@ -333,7 +353,7 @@ Returns
           ...    t.update(len(current_buffer))
           >>> t.close()
           The last line is highly recommended, but possibly not necessary if
-          `t.update()` will be called in such a way that `filesize` will be
+          ``t.update()`` will be called in such a way that ``filesize`` will be
           exactly reached and printed.
 
           Parameters
@@ -397,7 +417,7 @@ Examples and Advanced Usage
   folder;
 - import the module and run ``help()``, or
 - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__.
-    - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-Make-a-Great-Progressbar>`__ on how to make a **great** progressbar.
+    - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar.
 
 Nested progress bars
 ~~~~~~~~~~~~~~~~~~~~
@@ -622,6 +642,38 @@ A reusable canonical example is given below:
     # After the `with`, printing is restored
     print('Done!')
 
+Monitoring thread, intervals and miniters
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``tqdm`` implements a few tricks to to increase efficiency and reduce overhead.
+
+1. Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long
+   to wait between each refresh. ``tqdm`` always gets updated in the background,
+   but it will diplay only every ``mininterval``.
+2. Reduce number of calls to check system clock/time.
+3. ``mininterval`` is more intuitive to configure than ``miniters``.
+   A clever adjustment system ``dynamic_miniters`` will automatically adjust
+   ``miniters`` to the amount of iterations that fit into time ``mininterval``.
+   Essentially, ``tqdm`` will check if it's time to print without actually
+   checking time. This behavior can be still be bypassed by manually setting
+   ``miniters``.
+
+However, consider a case with a combination of fast and slow iterations.
+After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a
+large number. When interation rate subsequently slows, ``miniters`` will
+remain large and thus reduce display update frequency. To address this:
+
+4. ``maxinterval`` defines the maximum time between display refreshes.
+   A concurrent monitoring thread checks for overdue updates and forces one
+   where necessary.
+
+The monitoring thread should not have a noticeable overhead, and guarantees
+updates at least every 10 seconds by default.
+This value can be directly changed by setting the ``monitor_interval`` of
+any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).
+The monitor thread may be disabled application-wide by setting
+``tqdm.tqdm.monitor_interval = 0`` before instantiatiation of any ``tqdm`` bar.
+
 
 Contributions
 -------------
@@ -666,6 +718,8 @@ Ranked by contributions.
    :target: https://coveralls.io/r/tqdm/tqdm
 .. |Branch-Coverage-Status| image:: https://codecov.io/github/tqdm/tqdm/coverage.svg?branch=master
    :target: https://codecov.io/github/tqdm/tqdm?branch=master
+.. |Codacy-Grade| image:: https://api.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177
+   :target: https://www.codacy.com/app/tqdm/tqdm?utm_source=github.com&utm_medium=referral&utm_content=tqdm/tqdm&utm_campaign=Badge_Grade
 .. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=2592000
    :target: https://github.com/tqdm/tqdm/releases
 .. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg
@@ -678,6 +732,8 @@ Ranked by contributions.
    :target: https://pypi.python.org/pypi/tqdm
 .. |PyPI-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg
    :target: https://pypi.python.org/pypi/tqdm
+.. |Conda-Forge-Status| image:: https://anaconda.org/conda-forge/tqdm/badges/version.svg
+   :target: https://anaconda.org/conda-forge/tqdm
 .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg
    :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE
 .. |DOI-URI| image:: https://zenodo.org/badge/21637/tqdm/tqdm.svg
diff --git a/examples/include_no_requirements.py b/examples/include_no_requirements.py
index 874be0c..e7280d8 100644
--- a/examples/include_no_requirements.py
+++ b/examples/include_no_requirements.py
@@ -1,7 +1,7 @@
 # How to import tqdm without enforcing it as a dependency
 try:
     from tqdm import tqdm
-except:
+except ImportError:
     def tqdm(*args, **kwargs):
         if args:
             return args[0]
diff --git a/examples/pandas_progress_apply.py b/examples/pandas_progress_apply.py
index 9c84153..ae97287 100644
--- a/examples/pandas_progress_apply.py
+++ b/examples/pandas_progress_apply.py
@@ -15,7 +15,7 @@ df.progress_apply(lambda x: x**2)
 # df.groupby(0).progress_apply(lambda x: x**2)
 
 
-""" Source code for `tqdm_pandas` (really simple!) """
+# -- Source code for `tqdm_pandas` (really simple!)
 # def tqdm_pandas(t):
 #   from pandas.core.frame import DataFrame
 #   def inner(df, func, *args, **kwargs):
diff --git a/examples/simple_examples.py b/examples/simple_examples.py
index 8b29b06..62f4f22 100644
--- a/examples/simple_examples.py
+++ b/examples/simple_examples.py
@@ -28,8 +28,22 @@ for i in tqdm.tgrange(int(1e8)):
     pass
 
 # Comparison to https://code.google.com/p/python-progressbar/
-from progressbar.progressbar import ProgressBar
-for i in ProgressBar()(_range(int(1e8))):
+try:
+    from progressbar.progressbar import ProgressBar
+except ImportError:
+    pass
+else:
+    for i in ProgressBar()(_range(int(1e8))):
+        pass
+
+# Dynamic miniters benchmark
+from tqdm import trange
+for i in trange(int(1e8), miniters=None, mininterval=0.1, smoothing=0):
+    pass
+
+# Fixed miniters benchmark
+from tqdm import trange
+for i in trange(int(1e8), miniters=4500000, mininterval=0.1, smoothing=0):
     pass
 """
 
diff --git a/setup.py b/setup.py
index 3b880b2..8a77bb5 100755
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ except ImportError:
     from distutils.core import setup
 import sys
 from subprocess import check_call
-from io import open
+from io import open as io_open
 
 # For Makefile parsing
 import shlex
@@ -21,7 +21,7 @@ except ImportError:  # pragma: no cover
 import re
 
 
-""" Makefile auxiliary functions """
+# Makefile auxiliary functions #
 
 RE_MAKE_CMD = re.compile('^\t(@\+?)(make)?', flags=re.M)
 
@@ -37,7 +37,7 @@ def parse_makefile_aliases(filepath):
     # -- Parsing the Makefile using ConfigParser
     # Adding a fake section to make the Makefile a valid Ini file
     ini_str = '[root]\n'
-    with open(filepath, mode='r') as fd:
+    with io_open(filepath, mode='r') as fd:
         ini_str = ini_str + RE_MAKE_CMD.sub('\t', fd.read())
     ini_fp = StringIO.StringIO(ini_str)
     # Parse using ConfigParser
@@ -116,12 +116,12 @@ def execute_makefile_commands(commands, alias, verbose=False):
             check_call(parsed_cmd)
 
 
-""" Main setup.py config """
+# Main setup.py config #
 
 # Get version from tqdm/_version.py
 __version__ = None
 version_file = os.path.join(os.path.dirname(__file__), 'tqdm', '_version.py')
-with open(version_file, mode='r') as fd:
+with io_open(version_file, mode='r') as fd:
     exec(fd.read())
 
 # Executing makefile commands if specified
@@ -154,10 +154,10 @@ if sys.argv[1].lower().strip() == 'make':
     sys.exit(0)
 
 
-""" Python package config """
+# Python package config #
 
 README_rst = ''
-with open('README.rst', mode='r', encoding='utf-8') as fd:
+with io_open('README.rst', mode='r', encoding='utf-8') as fd:
     README_rst = fd.read()
 
 setup(
diff --git a/tox.ini b/tox.ini
index 97642fb..f515b48 100644
--- a/tox.ini
+++ b/tox.ini
@@ -15,15 +15,12 @@ deps =
     coveralls
 commands =
     nosetests --with-coverage --with-timer --cover-package=tqdm --ignore-files="tests_perf\.py" -d -v tqdm/
-    coveralls
+    - coveralls
 
 [testenv:flake8]
 deps = flake8
 commands =
-    flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/
-    flake8 --max-line-length=80 --count --statistics --exit-zero examples/
-    flake8 --max-line-length=80 --count --statistics --exit-zero .
-    flake8 --max-line-length=80 --count --statistics --exit-zero tqdm/tests/
+    flake8 --max-line-length=80 --count --statistics --exit-zero -j 8 --exclude .asv .
 
 [testenv:setup.py]
 deps =
diff --git a/tqdm.egg-info/PKG-INFO b/tqdm.egg-info/PKG-INFO
index 95caff0..33e1f38 100644
--- a/tqdm.egg-info/PKG-INFO
+++ b/tqdm.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tqdm
-Version: 4.8.4
+Version: 4.10.0
 Summary: A Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Author: tqdm developers
@@ -11,14 +11,15 @@ Description: |Logo|
         tqdm
         ====
         
-        |PyPI-Status| |PyPI-Versions|
+        |PyPI-Status| |PyPI-Versions| |Conda-Forge-Status|
         
-        |Build-Status| |Coverage-Status| |Branch-Coverage-Status|
+        |Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade|
         
         |DOI-URI| |LICENCE|
         
         
-        ``tqdm`` (read taqadum, تقدّم) means "progress" in arabic.
+        ``tqdm`` means "progress" in Arabic (taqadum, تقدّم)
+        and an abbreviation for "I love you so much" in Spanish (te quiero demasiado).
         
         Instantly make your loops show a smart progress meter - just wrap any
         iterable with ``tqdm(iterable)``, and you're done!
@@ -94,6 +95,15 @@ Description: |Logo|
         
             pip install -e git+https://github.com/tqdm/tqdm.git@master#egg=tqdm
         
+        Latest Conda release
+        ~~~~~~~~~~~~~~~~~~~~
+        
+        |Conda-Forge-Status|
+        
+        .. code:: sh
+        
+            conda install -c conda-forge tqdm
+        
         
         Changelog
         ---------
@@ -254,15 +264,15 @@ Description: |Logo|
             The number of expected iterations. If (default: None),
             len(iterable) is used if possible. As a last resort, only basic
             progress statistics are displayed (no ETA, no progressbar).
-            If `gui` is True and this parameter needs subsequent updating,
+            If ``gui`` is True and this parameter needs subsequent updating,
             specify an initial arbitrary large positive integer,
             e.g. int(9e9).
         * leave  : bool, optional  
             If [default: True], keeps all traces of the progressbar
             upon termination of iteration.
-        * file  : `io.TextIOWrapper` or `io.StringIO`, optional  
+        * file  : ``io.TextIOWrapper`` or ``io.StringIO``, optional  
             Specifies where to output the progress messages
-            [default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
+            [default: sys.stderr]. Uses ``file.write(str)`` and ``file.flush()``
             methods.
         * ncols  : int, optional  
             The width of the entire output message. If specified,
@@ -271,15 +281,23 @@ Description: |Logo|
             fallback is a meter width of 10 and no limit for the counter and
             statistics. If 0, will not print any meter (only stats).
         * mininterval  : float, optional  
-            Minimum progress update interval, in seconds [default: 0.1].
+            Minimum progress display update interval, in seconds [default: 0.1].
         * maxinterval  : float, optional  
-            Maximum progress update interval, in seconds [default: 10.0].
+            Maximum progress display update interval, in seconds [default: 10].
+            Automatically adjusts ``miniters`` to correspond to ``mininterval``
+            after long display update lag. Only works if ``dynamic_miniters``
+            or monitor thread is enabled.
         * miniters  : int, optional  
-            Minimum progress update interval, in iterations.
-            If specified, will set `mininterval` to 0.
+            Minimum progress display update interval, in iterations.
+            If 0 and ``dynamic_miniters``, will automatically adjust to equal
+            ``mininterval`` (more CPU efficient, good for tight loops).
+            If > 0, will skip display of specified number of iterations.
+            Tweak this and ``mininterval`` to get very efficient loops.
+            If your progress is erratic with both fast and slow iterations
+            (network, skipping items, etc) you should set miniters=1.
         * ascii  : bool, optional  
             If unspecified or False, use unicode (smooth blocks) to fill
-            the meter. The fallback is to use ASCII characters `1-9 #`.
+            the meter. The fallback is to use ASCII characters ``1-9 #``.
         * disable  : bool, optional  
             Whether to disable the entire progressbar wrapper
             [default: False].
@@ -292,7 +310,7 @@ Description: |Logo|
             International System of Units standard will be added
             (kilo, mega, etc.) [default: False].
         * dynamic_ncols  : bool, optional  
-            If set, constantly alters `ncols` to the environment (allowing
+            If set, constantly alters ``ncols`` to the environment (allowing
             for window resizes) [default: False].
         * smoothing  : float, optional  
             Exponential moving average smoothing factor for speed estimates
@@ -321,7 +339,9 @@ Description: |Logo|
             N.B.: on Windows systems, Python converts '\n' to '\r\n'.
         * buf_size  : int, optional  
             String buffer size in bytes [default: 256]
-            used when `delim` is specified.
+            used when ``delim`` is specified.
+        * bytes  : bool, optional  
+            If true, will count bytes and ignore ``delim``.
         
         Returns
         ~~~~~~~
@@ -341,7 +361,7 @@ Description: |Logo|
                   ...    t.update(len(current_buffer))
                   >>> t.close()
                   The last line is highly recommended, but possibly not necessary if
-                  `t.update()` will be called in such a way that `filesize` will be
+                  ``t.update()`` will be called in such a way that ``filesize`` will be
                   exactly reached and printed.
         
                   Parameters
@@ -405,7 +425,7 @@ Description: |Logo|
           folder;
         - import the module and run ``help()``, or
         - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__.
-            - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-Make-a-Great-Progressbar>`__ on how to make a **great** progressbar.
+            - this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar.
         
         Nested progress bars
         ~~~~~~~~~~~~~~~~~~~~
@@ -630,6 +650,38 @@ Description: |Logo|
             # After the `with`, printing is restored
             print('Done!')
         
+        Monitoring thread, intervals and miniters
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        ``tqdm`` implements a few tricks to to increase efficiency and reduce overhead.
+        
+        1. Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long
+           to wait between each refresh. ``tqdm`` always gets updated in the background,
+           but it will diplay only every ``mininterval``.
+        2. Reduce number of calls to check system clock/time.
+        3. ``mininterval`` is more intuitive to configure than ``miniters``.
+           A clever adjustment system ``dynamic_miniters`` will automatically adjust
+           ``miniters`` to the amount of iterations that fit into time ``mininterval``.
+           Essentially, ``tqdm`` will check if it's time to print without actually
+           checking time. This behavior can be still be bypassed by manually setting
+           ``miniters``.
+        
+        However, consider a case with a combination of fast and slow iterations.
+        After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a
+        large number. When interation rate subsequently slows, ``miniters`` will
+        remain large and thus reduce display update frequency. To address this:
+        
+        4. ``maxinterval`` defines the maximum time between display refreshes.
+           A concurrent monitoring thread checks for overdue updates and forces one
+           where necessary.
+        
+        The monitoring thread should not have a noticeable overhead, and guarantees
+        updates at least every 10 seconds by default.
+        This value can be directly changed by setting the ``monitor_interval`` of
+        any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).
+        The monitor thread may be disabled application-wide by setting
+        ``tqdm.tqdm.monitor_interval = 0`` before instantiatiation of any ``tqdm`` bar.
+        
         
         Contributions
         -------------
@@ -674,6 +726,8 @@ Description: |Logo|
            :target: https://coveralls.io/r/tqdm/tqdm
         .. |Branch-Coverage-Status| image:: https://codecov.io/github/tqdm/tqdm/coverage.svg?branch=master
            :target: https://codecov.io/github/tqdm/tqdm?branch=master
+        .. |Codacy-Grade| image:: https://api.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177
+           :target: https://www.codacy.com/app/tqdm/tqdm?utm_source=github.com&utm_medium=referral&utm_content=tqdm/tqdm&utm_campaign=Badge_Grade
         .. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=2592000
            :target: https://github.com/tqdm/tqdm/releases
         .. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg
@@ -686,6 +740,8 @@ Description: |Logo|
            :target: https://pypi.python.org/pypi/tqdm
         .. |PyPI-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg
            :target: https://pypi.python.org/pypi/tqdm
+        .. |Conda-Forge-Status| image:: https://anaconda.org/conda-forge/tqdm/badges/version.svg
+           :target: https://anaconda.org/conda-forge/tqdm
         .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg
            :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE
         .. |DOI-URI| image:: https://zenodo.org/badge/21637/tqdm/tqdm.svg
diff --git a/tqdm/_main.py b/tqdm/_main.py
index e1333f2..c9ae678 100644
--- a/tqdm/_main.py
+++ b/tqdm/_main.py
@@ -35,8 +35,21 @@ def posix_pipe(fin, fout, delim='\n', buf_size=256,
     """
     fp_write = fout.write
 
-    buf = ''
     tmp = ''
+    if not delim:
+        while True:
+            tmp = fin.read(buf_size)
+
+            # flush at EOF
+            if not tmp:
+                getattr(fout, 'flush', lambda: None)()  # pragma: no cover
+                return
+
+            fp_write(tmp)
+            callback(len(tmp))
+        return
+
+    buf = ''
     # n = 0
     while True:
         tmp = fin.read(buf_size)
@@ -80,10 +93,17 @@ CLI_EXTRA_DOC = r"""
         buf_size  : int, optional
             String buffer size in bytes [default: 256]
             used when `delim` is specified.
+        bytes  : bool, optional
+            If true, will count bytes and ignore `delim`.
 """
 
 
-def main():
+def main(fp=sys.stderr):
+    """
+    Paramters (internal use only)
+    ---------
+    fp  : file-like object for tqdm
+    """
     d = tqdm.__init__.__doc__ + CLI_EXTRA_DOC
 
     opt_types = dict(RE_OPTS.findall(d))
@@ -117,23 +137,28 @@ Options:
     argv = RE_SHLEX.split(' '.join(sys.argv))
     opts = dict(zip(argv[1::2], argv[2::2]))
 
-    tqdm_args = {}
+    tqdm_args = {'file': fp}
     try:
         for (o, v) in opts.items():
             try:
                 tqdm_args[o] = cast(v, opt_types[o])
             except KeyError as e:
                 raise TqdmKeyError(str(e))
-        # sys.stderr.write('\ndebug | args: ' + str(tqdm_args) + '\n')
+        # fp.write('\ndebug | args: ' + str(tqdm_args) + '\n')
     except:
-        sys.stderr.write('\nError:\nUsage:\n  tqdm [--help | options]\n')
+        fp.write('\nError:\nUsage:\n  tqdm [--help | options]\n')
         for i in sys.stdin:
             sys.stdout.write(i)
         raise
     else:
-        delim = tqdm_args.pop('delim', '\n')
         buf_size = tqdm_args.pop('buf_size', 256)
-        if delim == '\n':
+        delim = tqdm_args.pop('delim', '\n')
+        delim_per_char = tqdm_args.pop('bytes', False)
+        if delim_per_char:
+            with tqdm(**tqdm_args) as t:
+                posix_pipe(sys.stdin, sys.stdout,
+                           '', buf_size, t.update)
+        elif delim == '\n':
             for i in tqdm(sys.stdin, **tqdm_args):
                 sys.stdout.write(i)
         else:
diff --git a/tqdm/_tqdm.py b/tqdm/_tqdm.py
index a4bc583..a21180c 100644
--- a/tqdm/_tqdm.py
+++ b/tqdm/_tqdm.py
@@ -15,7 +15,9 @@ from __future__ import division
 from ._utils import _supports_unicode, _environ_cols_wrapper, _range, _unich, \
     _term_move_up, _unicode, WeakSet
 import sys
+from threading import Thread
 from time import time
+from time import sleep
 
 
 __author__ = {"github.com/": ["noamraph", "obiwanus", "kmike", "hadim",
@@ -41,12 +43,88 @@ class TqdmDeprecationWarning(Exception):
             super(TqdmDeprecationWarning, self).__init__(msg, *a, **k)
 
 
+class TMonitor(Thread):
+    """
+    Monitoring thread for tqdm bars.
+    Monitors if tqdm bars are taking too much time to display
+    and readjusts miniters automatically if necessary.
+
+    Parameters
+    ----------
+    tqdm_cls  : class
+        tqdm class to use (can be core tqdm or a submodule).
+    sleep_interval  : fload
+        Time to sleep between monitoring checks.
+    """
+
+    # internal vars for unit testing
+    _time = None
+    _sleep = None
+
+    def __init__(self, tqdm_cls, sleep_interval):
+        sys.setcheckinterval(100)
+        Thread.__init__(self)
+        self.daemon = True  # kill thread when main killed (KeyboardInterrupt)
+        self.was_killed = False
+        self.woken = 0  # last time woken up, to sync with monitor
+        self.tqdm_cls = tqdm_cls
+        self.sleep_interval = sleep_interval
+        if TMonitor._time is not None:
+            self._time = TMonitor._time
+        else:
+            self._time = time
+        if TMonitor._sleep is not None:
+            self._sleep = TMonitor._sleep
+        else:
+            self._sleep = sleep
+        self.start()
+
+    def exit(self):
+        self.was_killed = True
+        # self.join()  # DO NOT, blocking event, slows down tqdm at closing
+        return self.report()
+
+    def run(self):
+        cur_t = self._time()
+        while True:
+            # After processing and before sleeping, notify that we woke
+            # Need to be done just before sleeping
+            self.woken = cur_t
+            # Sleep some time...
+            self._sleep(self.sleep_interval)
+            # Quit if killed
+            # if self.exit_event.is_set():  # TODO: should work but does not...
+            if self.was_killed:
+                return
+            # Then monitor!
+            cur_t = self._time()
+            # Check for each tqdm instance if one is waiting too long to print
+            for instance in self.tqdm_cls._instances:
+                # Only if mininterval > 1 (else iterations are just slow)
+                # and last refresh was longer than maxinterval in this instance
+                if instance.miniters > 1 and \
+                  (cur_t - instance.last_print_t) >= instance.maxinterval:
+                    # We force bypassing miniters on next iteration
+                    # dynamic_miniters should adjust mininterval automatically
+                    instance.miniters = 1
+                    # Refresh now! (works only for manual tqdm)
+                    instance.refresh()
+
+    def report(self):
+        # return self.is_alive()  # TODO: does not work...
+        return not self.was_killed
+
+
 class tqdm(object):
     """
     Decorate an iterable object, returning an iterator which acts exactly
     like the original iterable, but prints a dynamically updating
     progressbar every time a value is requested.
     """
+
+    monitor_interval = 10  # set to 0 to disable the thread
+    monitor = None
+
     @staticmethod
     def format_sizeof(num, suffix=''):
         """
@@ -290,6 +368,10 @@ class tqdm(object):
         if "_instances" not in cls.__dict__:
             cls._instances = WeakSet()
         cls._instances.add(instance)
+        # Create the monitoring thread
+        if cls.monitor_interval and (cls.monitor is None or
+                                     not cls.monitor.report()):
+            cls.monitor = TMonitor(cls, cls.monitor_interval)
         # Return the instance
         return instance
 
@@ -315,6 +397,11 @@ class tqdm(object):
             for inst in cls._instances:
                 if inst.pos > instance.pos:
                     inst.pos -= 1
+            # Kill monitor if no instances are left
+            if not cls._instances and cls.monitor:
+                cls.monitor.exit()
+                del cls.monitor
+                cls.monitor = None
         except KeyError:
... 816 lines suppressed ...

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



More information about the Python-modules-commits mailing list