Hello community,

here is the log from the commit of package python-tqdm for openSUSE:Factory 
checked in at 2020-07-06 16:17:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tqdm (Old)
 and      /work/SRC/openSUSE:Factory/.python-tqdm.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tqdm"

Mon Jul  6 16:17:27 2020 rev:34 rq:818498 version:4.47.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tqdm/python-tqdm.changes  2020-04-15 
20:06:58.106124457 +0200
+++ /work/SRC/openSUSE:Factory/.python-tqdm.new.3060/python-tqdm.changes        
2020-07-06 16:18:49.413231928 +0200
@@ -1,0 +2,46 @@
+Fri Jul  3 03:09:31 UTC 2020 - Arun Persaud <a...@dhcp.lbl.gov>
+
+- specfile:
+  * fix location of bash completion
+
+- update to version 4.47.0:
+  * add contrib.discord (similar to contrib.telegram) (#976)
+  * add contrib.bells to auto-enable all extras
+  * add contrib.utils_worker for common slow tasks (e.g. web I/O)
+    + fix lazy large memory usage & discard unsent messages
+      (unprocessed tasks)
+  * fix slow notebook imports (#955 <- #709)
+  * fix gui TypeError on unknown len() (#971)
+  * misc documentation/error message updates
+    + more succinct ImportError on missing ipywidgets (#872)
+    + fix broken/deprecated link (#981)
+    + add inline usage for contrib.discord and contrib.telegram
+  * misc framework updates
+    + add official py3.8 support (#986)
+    + fix snap builds
+
+-------------------------------------------------------------------
+Sun Jun 28 18:50:24 UTC 2020 - Arun Persaud <a...@gmx.de>
+
+- update to version 4.46.1:
+  * fix missing sys.setcheckinterval in py3.9 (#978)
+  * fix keras.TqdmCallback compatibility with tensorflow==2.2.0 (#979)
+  * update documentation
+    + correct contrib.concurrent correct max_workers (#977)
+    + drop prominent mention of xrange (#965)
+  * minor linting
+
+-------------------------------------------------------------------
+Sat May  9 15:48:23 UTC 2020 - Arun Persaud <a...@gmx.de>
+
+- specfile:
+  * add bash completion script
+
+- update to version 4.46.0:
+  * add contrib.telegram #949 <- #948
+  * add bash tab completion and --comppath #946, #947 <- #858
+  * fix exception safety in external_write_mode #940
+  * add requests examples (#242)
+  * update documentation
+
+-------------------------------------------------------------------

Old:
----
  tqdm-4.45.0.tar.gz

New:
----
  tqdm-4.47.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tqdm.spec ++++++
--- /var/tmp/diff_new_pack.rpJJXL/_old  2020-07-06 16:18:53.149243406 +0200
+++ /var/tmp/diff_new_pack.rpJJXL/_new  2020-07-06 16:18:53.153243418 +0200
@@ -28,7 +28,7 @@
 %bcond_with test
 %endif
 Name:           python-tqdm%{pkg_suffix}
-Version:        4.45.0
+Version:        4.47.0
 Release:        0
 Summary:        An extensible progress meter
 License:        MPL-2.0 AND MIT
@@ -68,6 +68,7 @@
 %if !%{with test}
 %python_install
 %python_clone -a %{buildroot}%{_bindir}/tqdm
+install -m 644 -D tqdm/completion.sh 
%{buildroot}%{_datadir}/bash-completion/completions/tqdm
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 %endif
 
@@ -94,6 +95,7 @@
 %{python_sitelib}/tqdm/
 %{python_sitelib}/tqdm-%{version}-py*.egg-info
 %python_alternative %{_bindir}/tqdm
+%{_datadir}/bash-completion/completions/tqdm
 %endif
 
 %changelog

++++++ tqdm-4.45.0.tar.gz -> tqdm-4.47.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/.coveragerc new/tqdm-4.47.0/.coveragerc
--- old/tqdm-4.45.0/.coveragerc 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/.coveragerc 2020-06-29 00:38:16.000000000 +0200
@@ -2,5 +2,9 @@
 branch = True
 omit =
     tqdm/tests/*
+    tqdm/contrib/bells.py
+    tqdm/contrib/discord.py
+    tqdm/contrib/telegram.py
+    tqdm/contrib/utils_worker.py
 [report]
 show_missing = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/CONTRIBUTING.md 
new/tqdm-4.47.0/CONTRIBUTING.md
--- old/tqdm-4.45.0/CONTRIBUTING.md     2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/CONTRIBUTING.md     2020-06-29 00:38:16.000000000 +0200
@@ -46,7 +46,7 @@
     + should be appropriately commented
     + should have well-formatted docstrings for functions
         * under 76 chars (incl. initial spaces) to avoid linebreaks in 
terminal pagers
-        * use two spaces between variable name and colon
+        * use two spaces between variable name and colon, specify a type, and 
most likely state that it's optional: `VAR<space><space>:<space>TYPE[, 
optional]`
         * use [default: ...] for default values of keyword arguments
     + will not break backward compatibility unless there is a very good reason
         * e.g. breaking py26 compatibility purely in favour of readability 
(such as converting `dict(a=1)` to `{'a': 1}`) is not a good enough reason
@@ -56,11 +56,15 @@
     + submodules are likely single python files under the main [tqdm/](tqdm/) 
directory
         * large submodules requiring a sub-folder should be included in 
[`MANIFEST.in`](MANIFEST.in)
     + submodules extending `tqdm.std.tqdm` or any other module (e.g. 
[`tqdm.notebook.tqdm`](tqdm/notebook.py), [`tqdm.gui.tqdm`](tqdm/gui.py))
+    + CLI wrapper `tqdm.cli`
+        * if a newly added `tqdm.std.tqdm` option is not supported by the CLI, 
append to `tqdm.cli.UNSUPPORTED_OPTS`
     + can implement anything from experimental new features to support for 
third-party libraries such as `pandas`, `numpy`, etc.
     + submodule maturity
         * alpha: experimental; missing unit tests, comments, and/or feedback; 
raises `tqdm.TqdmExperimentalWarning`
         * beta: well-used; commented, perhaps still missing tests
         * stable: >10 users; commented, 80% coverage
+- `.meta/`
+    + A "hidden" folder containing helper utilities not strictly part of 
`tqdm` distribution itself
 
 
 ## TESTING
@@ -118,6 +122,12 @@
 `-r requirements-dev.txt` or `tqdm[dev]`.
 
 
+## Pre-commit Hook
+
+It's probably a good idea to add `[python setup.py] make pre-commit` to
+`.git/hooks/pre-commit` for convenient local sanity-checking.
+
+
 ## Semantic Versioning
 
 The tqdm repository managers should:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/DEMO.ipynb new/tqdm-4.47.0/DEMO.ipynb
--- old/tqdm-4.45.0/DEMO.ipynb  2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/DEMO.ipynb  2020-06-29 00:38:16.000000000 +0200
@@ -431,8 +431,6 @@
       "\n",
       "        Extra CLI Options\n",
       "        -----------------\n",
-      "        name  : type, optional\n",
-      "             TODO: find out why this is needed.\n",
       "        delim  : chr, optional\n",
       "            Delimiting character [default: '\\n']. Use '\\0' for 
null.\n",
       "            N.B.: on Windows systems, Python converts '\\n' to 
'\\r\\n'.\n",
@@ -444,6 +442,8 @@
       "            `unit_scale` to True, `unit_divisor` to 1024, and `unit` to 
'B'.\n",
       "        manpath  : str, optional\n",
       "            Directory in which to install tqdm man pages.\n",
+      "        comppath  : str, optional\n",
+      "            Directory in which to place tqdm completion.\n",
       "        log  : str, optional\n",
       "            CRITICAL|FATAL|ERROR|WARN(ING)|[default: 
'INFO']|DEBUG|NOTSET.\n",
       "\n"
@@ -706,7 +706,7 @@
     "        self.update(b * bsize - self.n)  # will also set self.n = b * 
bsize\n",
     "\n",
     "eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n";,
-    "with TqdmUpTo(unit='B', unit_scale=True, miniters=1,\n",
+    "with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, 
miniters=1,\n",
     "              desc=eg_link.split('/')[-1]) as t:  # all optional 
kwargs\n",
     "    urllib.urlretrieve(eg_link, filename=os.devnull,\n",
     "                       reporthook=t.update_to, data=None)\n",
@@ -774,6 +774,39 @@
     "        fout.write(chunk)"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The `requests` equivalent is nearly identical, albeit with a `total`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "matryoshka.zip: 254kB [00:00, 460kB/s] \n"
+     ]
+    }
+   ],
+   "source": [
+    "import requests, os\n",
+    "from tqdm import tqdm\n",
+    "\n",
+    "eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n";,
+    "response = requests.get(eg_link, stream=True)\n",
+    "with tqdm.wrapattr(open(os.devnull, \"wb\"), \"write\",\n",
+    "                   miniters=1, desc=eg_link.split('/')[-1],\n",
+    "                   total=int(response.headers.get('content-length', 0))) 
as fout:\n",
+    "    for chunk in response.iter_content(chunk_size=4096):\n",
+    "        fout.write(chunk)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/MANIFEST.in new/tqdm-4.47.0/MANIFEST.in
--- old/tqdm-4.45.0/MANIFEST.in 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/MANIFEST.in 2020-06-29 00:38:16.000000000 +0200
@@ -18,4 +18,5 @@
 recursive-include examples *.py
 include README.rst
 include tqdm/tqdm.1
+include tqdm/completion.sh
 include DEMO.ipynb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/Makefile new/tqdm-4.47.0/Makefile
--- old/tqdm-4.45.0/Makefile    2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/Makefile    2020-06-29 00:38:16.000000000 +0200
@@ -56,6 +56,7 @@
 testsetup:
        @make README.rst
        @make tqdm/tqdm.1
+       @make tqdm/completion.sh
        python setup.py check --metadata --restructuredtext --strict
        python setup.py make none
 
@@ -94,6 +95,9 @@
     cat "$<" - |\
     pandoc -o "$@" -s -t man
 
+tqdm/completion.sh: .meta/mkcompletion.py tqdm/std.py tqdm/cli.py
+       @python .meta/mkcompletion.py
+
 README.rst: .meta/.readme.rst tqdm/std.py tqdm/cli.py
        @python .meta/mkdocs.py
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/PKG-INFO new/tqdm-4.47.0/PKG-INFO
--- old/tqdm-4.45.0/PKG-INFO    2020-04-02 14:56:00.000000000 +0200
+++ new/tqdm-4.47.0/PKG-INFO    2020-06-29 00:38:32.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: tqdm
-Version: 4.45.0
+Version: 4.47.0
 Summary: Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Maintainer: tqdm developers
@@ -32,7 +32,7 @@
         ``76%|████████████████████████        | 7568/10000 [00:33<00:10, 
229.00it/s]``
         
         ``trange(N)`` can be also used as a convenient shortcut for
-        ``tqdm(xrange(N))``.
+        ``tqdm(range(N))``.
         
         |Screenshot|
             |Video| |Slides|
@@ -119,6 +119,9 @@
             snap install tqdm  --candidate  # master branch
             snap install tqdm  --edge  # devel branch
         
+        Note than ``snap`` binaries are purely for CLI use (not 
``import``-able), and
+        automatically set up ``bash`` tab-completion.
+        
         Latest Docker release
         ~~~~~~~~~~~~~~~~~~~~~
         
@@ -144,9 +147,8 @@
         
         The list of all changes is available either on GitHub's Releases:
         |GitHub-Status|, on the
-        `wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, on the
-        `website <https://tqdm.github.io/releases/>`__, or on crawlers such as
-        `allmychanges.com <https://allmychanges.com/p/python/tqdm/>`_.
+        `wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the
+        `website <https://tqdm.github.io/releases/>`__.
         
         
         Usage
@@ -469,6 +471,8 @@
             ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 
'B'.
         * manpath  : str, optional  
             Directory in which to install tqdm man pages.
+        * comppath  : str, optional  
+            Directory in which to place tqdm completion.
         * log  : str, optional  
             CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
         
@@ -613,10 +617,19 @@
             def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
                 """Equivalent of builtin `map`."""
         
+        ``contrib``
+        -----------
+        
         The ``tqdm.contrib`` package also contains experimental modules:
         
         - ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``
         - ``tqdm.contrib.concurrent``: Thin wrappers around 
``concurrent.futures``
+        - ``tqdm.contrib.bells``: Automagically enables all optional features
+        
+          * ``auto``, ``pandas``, ``discord``, ``telegram``
+        
+        - ``tqdm.contrib.discord``: Posts to `Discord 
<https://discord.com/>`__ bots
+        - ``tqdm.contrib.telegram``: Posts to `Telegram 
<https://telegram.org/>`__ bots
         
         Examples and Advanced Usage
         ---------------------------
@@ -815,7 +828,7 @@
                     self.update(b * bsize - self.n)  # will also set self.n = 
b * bsize
         
             eg_link = "https://caspersci.uk.to/matryoshka.zip";
-            with TqdmUpTo(unit='B', unit_scale=True, miniters=1,
+            with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, 
miniters=1,
                           desc=eg_link.split('/')[-1]) as t:  # all optional 
kwargs
                 urllib.urlretrieve(eg_link, filename=os.devnull,
                                    reporthook=t.update_to, data=None)
@@ -864,6 +877,21 @@
                 for chunk in urllib.urlopen(eg_link):
                     fout.write(chunk)
         
+        The ``requests`` equivalent is nearly identical, albeit with a 
``total``:
+        
+        .. code:: python
+        
+            import requests, os
+            from tqdm import tqdm
+        
+            eg_link = "https://caspersci.uk.to/matryoshka.zip";
+            response = requests.get(eg_link, stream=True)
+            with tqdm.wrapattr(open(os.devnull, "wb"), "write",
+                               miniters=1, desc=eg_link.split('/')[-1],
+                               
total=int(response.headers.get('content-length', 0))) as fout:
+                for chunk in response.iter_content(chunk_size=4096):
+                    fout.write(chunk)
+        
         Pandas Integration
         ~~~~~~~~~~~~~~~~~~
         
@@ -1338,6 +1366,7 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: Implementation
 Classifier: Programming Language :: Python :: Implementation :: IronPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/README.rst new/tqdm-4.47.0/README.rst
--- old/tqdm-4.45.0/README.rst  2020-04-02 14:55:59.000000000 +0200
+++ new/tqdm-4.47.0/README.rst  2020-06-29 00:38:30.000000000 +0200
@@ -24,7 +24,7 @@
 ``76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]``
 
 ``trange(N)`` can be also used as a convenient shortcut for
-``tqdm(xrange(N))``.
+``tqdm(range(N))``.
 
 |Screenshot|
     |Video| |Slides|
@@ -111,6 +111,9 @@
     snap install tqdm  --candidate  # master branch
     snap install tqdm  --edge  # devel branch
 
+Note than ``snap`` binaries are purely for CLI use (not ``import``-able), and
+automatically set up ``bash`` tab-completion.
+
 Latest Docker release
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -136,9 +139,8 @@
 
 The list of all changes is available either on GitHub's Releases:
 |GitHub-Status|, on the
-`wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, on the
-`website <https://tqdm.github.io/releases/>`__, or on crawlers such as
-`allmychanges.com <https://allmychanges.com/p/python/tqdm/>`_.
+`wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the
+`website <https://tqdm.github.io/releases/>`__.
 
 
 Usage
@@ -461,6 +463,8 @@
     ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'.
 * manpath  : str, optional  
     Directory in which to install tqdm man pages.
+* comppath  : str, optional  
+    Directory in which to place tqdm completion.
 * log  : str, optional  
     CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
 
@@ -605,10 +609,19 @@
     def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
         """Equivalent of builtin `map`."""
 
+``contrib``
+-----------
+
 The ``tqdm.contrib`` package also contains experimental modules:
 
 - ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``
 - ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures``
+- ``tqdm.contrib.bells``: Automagically enables all optional features
+
+  * ``auto``, ``pandas``, ``discord``, ``telegram``
+
+- ``tqdm.contrib.discord``: Posts to `Discord <https://discord.com/>`__ bots
+- ``tqdm.contrib.telegram``: Posts to `Telegram <https://telegram.org/>`__ bots
 
 Examples and Advanced Usage
 ---------------------------
@@ -807,7 +820,7 @@
             self.update(b * bsize - self.n)  # will also set self.n = b * bsize
 
     eg_link = "https://caspersci.uk.to/matryoshka.zip";
-    with TqdmUpTo(unit='B', unit_scale=True, miniters=1,
+    with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
                   desc=eg_link.split('/')[-1]) as t:  # all optional kwargs
         urllib.urlretrieve(eg_link, filename=os.devnull,
                            reporthook=t.update_to, data=None)
@@ -856,6 +869,21 @@
         for chunk in urllib.urlopen(eg_link):
             fout.write(chunk)
 
+The ``requests`` equivalent is nearly identical, albeit with a ``total``:
+
+.. code:: python
+
+    import requests, os
+    from tqdm import tqdm
+
+    eg_link = "https://caspersci.uk.to/matryoshka.zip";
+    response = requests.get(eg_link, stream=True)
+    with tqdm.wrapattr(open(os.devnull, "wb"), "write",
+                       miniters=1, desc=eg_link.split('/')[-1],
+                       total=int(response.headers.get('content-length', 0))) 
as fout:
+        for chunk in response.iter_content(chunk_size=4096):
+            fout.write(chunk)
+
 Pandas Integration
 ~~~~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/examples/tqdm_requests.py 
new/tqdm-4.47.0/examples/tqdm_requests.py
--- old/tqdm-4.45.0/examples/tqdm_requests.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/tqdm-4.47.0/examples/tqdm_requests.py   2020-06-29 00:38:16.000000000 
+0200
@@ -0,0 +1,49 @@
+"""An example of wrapping manual tqdm updates for `requests.get`.
+See also: tqdm_wget.py.
+
+Usage:
+    tqdm_requests.py [options]
+
+Options:
+-h, --help
+    Print this help message and exit
+-u URL, --url URL  : string, optional
+    The url to fetch.
+    [default: https://caspersci.uk.to/matryoshka.zip]
+-o FILE, --output FILE  : string, optional
+    The local file path in which to save the url [default: /dev/null].
+"""
+
+from os import devnull
+
+from docopt import docopt
+import requests
+from tqdm.auto import tqdm
+
+
+opts = docopt(__doc__)
+
+eg_link = opts['--url']
+eg_file = eg_link.replace('/', ' ').split()[-1]
+eg_out = opts['--output'].replace("/dev/null", devnull)
+
+response = requests.get(eg_link, stream=True)
+with open(eg_out, "wb") as fout:
+    with tqdm(
+        # all optional kwargs
+        unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
+        desc=eg_file, total=int(response.headers.get('content-length', 0))
+    ) as pbar:
+        for chunk in response.iter_content(chunk_size=4096):
+            fout.write(chunk)
+            pbar.update(len(chunk))
+
+# Even simpler progress by wrapping the output file's `write()`
+response = requests.get(eg_link, stream=True)
+with tqdm.wrapattr(
+    open(eg_out, "wb"), "write",
+    unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
+    desc=eg_file, total=int(response.headers.get('content-length', 0))
+) as fout:
+    for chunk in response.iter_content(chunk_size=4096):
+        fout.write(chunk)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/examples/tqdm_wget.py 
new/tqdm-4.47.0/examples/tqdm_wget.py
--- old/tqdm-4.45.0/examples/tqdm_wget.py       2020-04-02 14:55:43.000000000 
+0200
+++ new/tqdm-4.47.0/examples/tqdm_wget.py       2020-06-29 00:38:16.000000000 
+0200
@@ -1,6 +1,7 @@
-"""An example of wrapping manual tqdm updates for urllib reporthook.
+"""An example of wrapping manual tqdm updates for `urllib` reporthook.
+See also: tqdm_requests.py.
 
-# urllib.urlretrieve documentation
+# `urllib.urlretrieve` documentation
 > If present, the hook function will be called once
 > on establishment of the network connection and once after each block read
 > thereafter. The hook will be passed three arguments; a count of blocks
@@ -19,10 +20,11 @@
     The local file path in which to save the url [default: /dev/null].
 """
 
-import urllib
 from os import devnull
-from tqdm.auto import tqdm
+
 from docopt import docopt
+import urllib
+from tqdm.auto import tqdm
 
 
 def my_hook(t):
@@ -95,6 +97,7 @@
               desc=eg_file) as t:  # all optional kwargs
     urllib.urlretrieve(eg_link, filename=eg_out, reporthook=t.update_to,
                        data=None)
+    t.total = t.n
 
 # Even simpler progress by wrapping the output file's `write()`
 with tqdm.wrapattr(open(eg_out, "wb"), "write",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/setup.py new/tqdm-4.47.0/setup.py
--- old/tqdm-4.45.0/setup.py    2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/setup.py    2020-06-29 00:38:16.000000000 +0200
@@ -55,7 +55,7 @@
     extras_require=extras_require,
     entry_points={'console_scripts': ['tqdm=tqdm.cli:main'], },
     package_data={'tqdm': ['CONTRIBUTING.md', 'LICENCE', 'examples/*.py',
-                           'tqdm.1', 'requirements-dev.txt']},
+                           'tqdm.1', 'completion.sh', 'requirements-dev.txt']},
     python_requires='>=2.6, !=3.0.*, !=3.1.*',
     classifiers=[
         # Trove classifiers
@@ -97,6 +97,7 @@
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: Implementation',
         'Programming Language :: Python :: Implementation :: IronPython',
         'Programming Language :: Python :: Implementation :: PyPy',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tox.ini new/tqdm-4.47.0/tox.ini
--- old/tqdm-4.45.0/tox.ini     2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tox.ini     2020-06-29 00:38:16.000000000 +0200
@@ -5,7 +5,7 @@
 
 [tox]
 # deprecation warning: py{26,32,33,34}
-envlist = py{26,27,33,34,35,36,37,py,py3}, tf-no-keras, perf, flake8, setup.py
+envlist = py{26,27,33,34,35,36,37,38,py,py3}, tf-no-keras, perf, flake8, 
setup.py
 
 [coverage]
 deps =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/_version.py 
new/tqdm-4.47.0/tqdm/_version.py
--- old/tqdm-4.45.0/tqdm/_version.py    2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/_version.py    2020-06-29 00:38:16.000000000 +0200
@@ -5,7 +5,7 @@
 __all__ = ["__version__"]
 
 # major, minor, patch, -extra
-version_info = 4, 45, 0
+version_info = 4, 47, 0
 
 # Nice string for the version
 __version__ = '.'.join(map(str, version_info))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/autonotebook.py 
new/tqdm-4.47.0/tqdm/autonotebook.py
--- old/tqdm-4.45.0/tqdm/autonotebook.py        2020-04-02 14:55:43.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm/autonotebook.py        2020-06-29 00:38:16.000000000 
+0200
@@ -1,7 +1,8 @@
 import os
+import sys
 
 try:
-    from IPython import get_ipython
+    get_ipython = sys.modules['IPython'].get_ipython
     if 'IPKernelApp' not in get_ipython().config:  # pragma: no cover
         raise ImportError("console")
     if 'VSCODE_PID' in os.environ:  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/cli.py new/tqdm-4.47.0/tqdm/cli.py
--- old/tqdm-4.45.0/tqdm/cli.py 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/cli.py 2020-06-29 00:38:16.000000000 +0200
@@ -1,3 +1,6 @@
+"""
+Module version for monitoring CLI pipes (`... | python -m tqdm | ...`).
+"""
 from .std import tqdm, TqdmTypeError, TqdmKeyError
 from ._version import __version__  # NOQA
 import sys
@@ -111,6 +114,8 @@
             `unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.
         manpath  : str, optional
             Directory in which to install tqdm man pages.
+        comppath  : str, optional
+            Directory in which to place tqdm completion.
         log  : str, optional
             CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
 """
@@ -200,16 +205,25 @@
         delim = tqdm_args.pop('delim', '\n')
         delim_per_char = tqdm_args.pop('bytes', False)
         manpath = tqdm_args.pop('manpath', None)
+        comppath = tqdm_args.pop('comppath', None)
         stdin = getattr(sys.stdin, 'buffer', sys.stdin)
         stdout = getattr(sys.stdout, 'buffer', sys.stdout)
-        if manpath is not None:
+        if manpath or comppath:
             from os import path
             from shutil import copyfile
             from pkg_resources import resource_filename, Requirement
-            fi = resource_filename(Requirement.parse('tqdm'), 'tqdm/tqdm.1')
-            fo = path.join(manpath, 'tqdm.1')
-            copyfile(fi, fo)
-            log.info("written:" + fo)
+
+            def cp(src, dst):
+                """copies from src path to dst"""
+                copyfile(src, dst)
+                log.info("written:" + dst)
+            if manpath is not None:
+                cp(resource_filename(Requirement.parse('tqdm'), 'tqdm/tqdm.1'),
+                   path.join(manpath, 'tqdm.1'))
+            if comppath is not None:
+                cp(resource_filename(Requirement.parse('tqdm'),
+                                     'tqdm/completion.sh'),
+                   path.join(comppath, 'tqdm_completion.sh'))
             sys.exit(0)
         if delim_per_char:
             tqdm_args.setdefault('unit', 'B')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/completion.sh 
new/tqdm-4.47.0/tqdm/completion.sh
--- old/tqdm-4.45.0/tqdm/completion.sh  1970-01-01 01:00:00.000000000 +0100
+++ new/tqdm-4.47.0/tqdm/completion.sh  2020-06-29 00:38:16.000000000 +0200
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+_tqdm(){
+  local cur prv
+  cur="${COMP_WORDS[COMP_CWORD]}"
+  prv="${COMP_WORDS[COMP_CWORD - 1]}"
+
+  case ${prv} in
+  
--bar_format|--buf_size|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor)
+    # await user input
+    ;;
+  "--log")
+    COMPREPLY=($(compgen -W       'CRITICAL FATAL ERROR WARN WARNING INFO 
DEBUG NOTSET' -- ${cur}))
+    ;;
+  *)
+    COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes 
--comppath --delim --desc --disable --dynamic_ncols --help --initial --leave 
--lock_args --log --manpath --maxinterval --mininterval --miniters --ncols 
--nrows --position --postfix --smoothing --total --unit --unit_divisor 
--unit_scale --version --write_bytes -h -v' -- ${cur}))
+    ;;
+  esac
+}
+complete -F _tqdm tqdm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/contrib/bells.py 
new/tqdm-4.47.0/tqdm/contrib/bells.py
--- old/tqdm-4.45.0/tqdm/contrib/bells.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/tqdm-4.47.0/tqdm/contrib/bells.py       2020-06-29 00:38:16.000000000 
+0200
@@ -0,0 +1,25 @@
+"""
+All the bells & whistles:
+
+- tqdm.auto
+- tqdm.tqdm.pandas
+- tqdm.contrib.telegram
+    + uses ${TQDM_TELEGRAM_TOKEN} and ${TQDM_TELEGRAM_CHAT_ID}
+- tqdm.contrib.discord
+    + uses ${TQDM_DISCORD_TOKEN} and ${TQDM_DISCORD_CHANNEL_ID}
+"""
+__all__ = ['tqdm', 'trange']
+from os import getenv
+import warnings
+
+
+if getenv("TQDM_TELEGRAM_TOKEN") and getenv("TQDM_TELEGRAM_CHAT_ID"):
+    from tqdm.contrib.telegram import tqdm, trange
+elif getenv("TQDM_DISCORD_TOKEN") and getenv("TQDM_DISCORD_CHANNEL_ID"):
+    from tqdm.contrib.discord import tqdm, trange
+else:
+    from tqdm.auto import tqdm, trange
+
+with warnings.catch_warnings():
+    warnings.simplefilter("ignore", category=FutureWarning)
+    tqdm.pandas()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/contrib/concurrent.py 
new/tqdm-4.47.0/tqdm/contrib/concurrent.py
--- old/tqdm-4.45.0/tqdm/contrib/concurrent.py  2020-04-02 14:55:43.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm/contrib/concurrent.py  2020-06-29 00:38:16.000000000 
+0200
@@ -34,7 +34,7 @@
     Parameters
     ----------
     tqdm_class  : [default: tqdm.auto.tqdm].
-    max_workers  : [default: max(32, cpu_count() + 4)].
+    max_workers  : [default: min(32, cpu_count() + 4)].
     chunksize  : [default: 1].
     """
     kwargs = deepcopy(tqdm_kwargs)
@@ -87,7 +87,7 @@
     max_workers : int, optional
         Maximum number of workers to spawn; passed to
         `concurrent.futures.ProcessPoolExecutor.__init__`.
-        [default: max(32, cpu_count() + 4)].
+        [default: min(32, cpu_count() + 4)].
     chunksize : int, optional
         Size of chunks sent to worker processes; passed to
         `concurrent.futures.ProcessPoolExecutor.map`. [default: 1].
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/contrib/discord.py 
new/tqdm-4.47.0/tqdm/contrib/discord.py
--- old/tqdm-4.45.0/tqdm/contrib/discord.py     1970-01-01 01:00:00.000000000 
+0100
+++ new/tqdm-4.47.0/tqdm/contrib/discord.py     2020-06-29 00:38:16.000000000 
+0200
@@ -0,0 +1,127 @@
+"""
+Sends updates to a Discord bot.
+"""
+from __future__ import absolute_import
+from copy import deepcopy
+from os import getenv
+
+try:
+    from disco.client import Client, ClientConfig
+except ImportError:
+    raise ImportError("Please `pip install disco-py`")
+
+from tqdm.auto import tqdm as tqdm_auto
+from tqdm.utils import _range
+from .utils_worker import MonoWorker
+__author__ = {"github.com/": ["casperdcl"]}
+__all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange']
+
+
+class DiscordIO(MonoWorker):
+    """Non-blocking file-like IO using a Discord Bot."""
+    def __init__(self, token, channel_id):
+        """Creates a new message in the given `channel_id`."""
+        super(DiscordIO, self).__init__()
+        config = ClientConfig()
+        config.token = token
+        client = Client(config)
+        self.text = self.__class__.__name__
+        try:
+            self.message = client.api.channels_messages_create(
+                channel_id, self.text)
+        except Exception as e:
+            tqdm_auto.write(str(e))
+
+    def write(self, s):
+        """Replaces internal `message`'s text with `s`."""
+        if not s:
+            return
+        s = s.replace('\r', '').strip()
+        if s == self.text:
+            return  # skip duplicate message
+        self.text = s
+        try:
+            future = self.submit(self.message.edit, '`' + s + '`')
+        except Exception as e:
+            tqdm_auto.write(str(e))
+        else:
+            return future
+
+
+class tqdm_discord(tqdm_auto):
+    """
+    Standard `tqdm.auto.tqdm` but also sends updates to a Discord Bot.
+    May take a few seconds to create (`__init__`).
+
+    - create a discord bot (not public, no requirement of OAuth2 code
+      grant, only send message permissions) & invite it to a channel:
+      https://discordpy.readthedocs.io/en/latest/discord.html
+    - copy the bot `{token}` & `{channel_id}` and paste below
+
+    >>> from tqdm.contrib.discord import tqdm, trange
+    >>> for i in tqdm(iterable, token='{token}', channel_id='{channel_id}'):
+    ...     ...
+    """
+    def __init__(self, *args, **kwargs):
+        """
+        Parameters
+        ----------
+        token  : str, required. Discord token
+            [default: ${TQDM_DISCORD_TOKEN}].
+        channel_id  : int, required. Discord channel ID
+            [default: ${TQDM_DISCORD_CHANNEL_ID}].
+        mininterval  : float, optional.
+          Minimum of [default: 1.5] to avoid rate limit.
+
+        See `tqdm.auto.tqdm.__init__` for other parameters.
+        """
+        kwargs = deepcopy(kwargs)
+        self.dio = DiscordIO(
+            kwargs.pop('token', getenv("TQDM_DISCORD_TOKEN")),
+            kwargs.pop('channel_id', getenv("TQDM_DISCORD_CHANNEL_ID")))
+
+        kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
+        super(tqdm_discord, self).__init__(*args, **kwargs)
+
+    def display(self, **kwargs):
+        super(tqdm_discord, self).display(**kwargs)
+        fmt = self.format_dict
+        if 'bar_format' in fmt and fmt['bar_format']:
+            fmt['bar_format'] = fmt['bar_format'].replace('<bar/>', '{bar}')
+        else:
+            fmt['bar_format'] = '{l_bar}{bar}{r_bar}'
+        fmt['bar_format'] = fmt['bar_format'].replace('{bar}', '{bar:10u}')
+        self.dio.write(self.format_meter(**fmt))
+
+    def __new__(cls, *args, **kwargs):
+        """
+        Workaround for mixed-class same-stream nested progressbars.
+        See [#509](https://github.com/tqdm/tqdm/issues/509)
+        """
+        with cls.get_lock():
+            try:
+                cls._instances = tqdm_auto._instances
+            except AttributeError:
+                pass
+        instance = super(tqdm_discord, cls).__new__(cls, *args, **kwargs)
+        with cls.get_lock():
+            try:
+                # `tqdm_auto` may have been changed so update
+                cls._instances.update(tqdm_auto._instances)
+            except AttributeError:
+                pass
+            tqdm_auto._instances = cls._instances
+        return instance
+
+
+def tdrange(*args, **kwargs):
+    """
+    A shortcut for `tqdm.contrib.discord.tqdm(xrange(*args), **kwargs)`.
+    On Python3+, `range` is used instead of `xrange`.
+    """
+    return tqdm_discord(_range(*args), **kwargs)
+
+
+# Aliases
+tqdm = tqdm_discord
+trange = tdrange
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/contrib/telegram.py 
new/tqdm-4.47.0/tqdm/contrib/telegram.py
--- old/tqdm-4.45.0/tqdm/contrib/telegram.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/tqdm-4.47.0/tqdm/contrib/telegram.py    2020-06-29 00:38:16.000000000 
+0200
@@ -0,0 +1,133 @@
+"""
+Sends updates to a Telegram bot.
+"""
+from __future__ import absolute_import
+from copy import deepcopy
+from os import getenv
+
+from requests import Session
+
+from tqdm.auto import tqdm as tqdm_auto
+from tqdm.utils import _range
+from .utils_worker import MonoWorker
+__author__ = {"github.com/": ["casperdcl"]}
+__all__ = ['TelegramIO', 'tqdm_telegram', 'ttgrange', 'tqdm', 'trange']
+
+
+class TelegramIO(MonoWorker):
+    """Non-blocking file-like IO using a Telegram Bot."""
+    API = 'https://api.telegram.org/bot'
+
+    def __init__(self, token, chat_id):
+        """Creates a new message in the given `chat_id`."""
+        super(TelegramIO, self).__init__()
+        self.token = token
+        self.chat_id = chat_id
+        self.session = session = Session()
+        self.text = self.__class__.__name__
+        try:
+            res = session.post(
+                self.API + '%s/sendMessage' % self.token,
+                data=dict(text='`' + self.text + '`', chat_id=self.chat_id,
+                          parse_mode='MarkdownV2'))
+        except Exception as e:
+            tqdm_auto.write(str(e))
+        else:
+            self.message_id = res.json()['result']['message_id']
+
+    def write(self, s):
+        """Replaces internal `message_id`'s text with `s`."""
+        if not s:
+            return
+        s = s.replace('\r', '').strip()
+        if s == self.text:
+            return  # avoid duplicate message Bot error
+        self.text = s
+        try:
+            future = self.submit(
+                self.session.post,
+                self.API + '%s/editMessageText' % self.token,
+                data=dict(
+                    text='`' + s + '`', chat_id=self.chat_id,
+                    message_id=self.message_id, parse_mode='MarkdownV2'))
+        except Exception as e:
+            tqdm_auto.write(str(e))
+        else:
+            return future
+
+
+class tqdm_telegram(tqdm_auto):
+    """
+    Standard `tqdm.auto.tqdm` but also sends updates to a Telegram Bot.
+    May take a few seconds to create (`__init__`).
+
+    - create a bot https://core.telegram.org/bots#6-botfather
+    - copy its `{token}`
+    - add the bot to a chat and send it a message such as `/start`
+    - go to https://api.telegram.org/bot`{token}`/getUpdates to find out
+      the `{chat_id}`
+    - paste the `{token}` & `{chat_id}` below
+
+    >>> from tqdm.contrib.telegram import tqdm, trange
+    >>> for i in tqdm(iterable, token='{token}', chat_id='{chat_id}'):
+    ...     ...
+    """
+    def __init__(self, *args, **kwargs):
+        """
+        Parameters
+        ----------
+        token  : str, required. Telegram token
+            [default: ${TQDM_TELEGRAM_TOKEN}].
+        chat_id  : str, required. Telegram chat ID
+            [default: ${TQDM_TELEGRAM_CHAT_ID}].
+
+        See `tqdm.auto.tqdm.__init__` for other parameters.
+        """
+        kwargs = deepcopy(kwargs)
+        self.tgio = TelegramIO(
+            kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')),
+            kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID')))
+        super(tqdm_telegram, self).__init__(*args, **kwargs)
+
+    def display(self, **kwargs):
+        super(tqdm_telegram, self).display(**kwargs)
+        fmt = self.format_dict
+        if 'bar_format' in fmt and fmt['bar_format']:
+            fmt['bar_format'] = fmt['bar_format'].replace('<bar/>', '{bar}')
+        else:
+            fmt['bar_format'] = '{l_bar}{bar}{r_bar}'
+        fmt['bar_format'] = fmt['bar_format'].replace('{bar}', '{bar:10u}')
+        self.tgio.write(self.format_meter(**fmt))
+
+    def __new__(cls, *args, **kwargs):
+        """
+        Workaround for mixed-class same-stream nested progressbars.
+        See [#509](https://github.com/tqdm/tqdm/issues/509)
+        """
+        with cls.get_lock():
+            try:
+                cls._instances = tqdm_auto._instances
+            except AttributeError:
+                pass
+        instance = super(tqdm_telegram, cls).__new__(cls, *args, **kwargs)
+        with cls.get_lock():
+            try:
+                # `tqdm_auto` may have been changed so update
+                cls._instances.update(tqdm_auto._instances)
+            except AttributeError:
+                pass
+            tqdm_auto._instances = cls._instances
+        return instance
+
+
+def ttgrange(*args, **kwargs):
+    """
+    A shortcut for `tqdm.contrib.telegram.tqdm(xrange(*args), **kwargs)`.
+    On Python3+, `range` is used instead of `xrange`.
+    """
+    return tqdm_telegram(_range(*args), **kwargs)
+
+
+# Aliases
+tqdm = tqdm_telegram
+trange = ttgrange
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/contrib/utils_worker.py 
new/tqdm-4.47.0/tqdm/contrib/utils_worker.py
--- old/tqdm-4.45.0/tqdm/contrib/utils_worker.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/tqdm-4.47.0/tqdm/contrib/utils_worker.py        2020-06-29 
00:38:16.000000000 +0200
@@ -0,0 +1,39 @@
+"""
+IO/concurrency helpers for `tqdm.contrib`.
+"""
+from __future__ import absolute_import
+
+from concurrent.futures import ThreadPoolExecutor
+from collections import deque
+
+from tqdm.auto import tqdm as tqdm_auto
+__author__ = {"github.com/": ["casperdcl"]}
+__all__ = ['MonoWorker']
+
+
+class MonoWorker(object):
+    """
+    Supports one running task and one waiting task.
+    The waiting task is the most recent submitted (others are discarded).
+    """
+    def __init__(self):
+        self.pool = ThreadPoolExecutor(max_workers=1)
+        self.futures = deque([], 2)
+
+    def submit(self, func, *args, **kwargs):
+        """`func(*args, **kwargs)` may replace currently waiting task."""
+        futures = self.futures
+        if len(futures) == futures.maxlen:
+            running = futures.popleft()
+            if not running.done():
+                if len(futures):  # clear waiting
+                    waiting = futures.pop()
+                    waiting.cancel()
+                futures.appendleft(running)  # re-insert running
+        try:
+            waiting = self.pool.submit(func, *args, **kwargs)
+        except Exception as e:
+            tqdm_auto.write(str(e))
+        else:
+            futures.append(waiting)
+            return waiting
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/gui.py new/tqdm-4.47.0/tqdm/gui.py
--- old/tqdm-4.45.0/tqdm/gui.py 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/gui.py 2020-06-29 00:38:16.000000000 +0200
@@ -53,7 +53,7 @@
         self.mininterval = max(self.mininterval, 0.5)
         self.fig, ax = plt.subplots(figsize=(9, 2.2))
         # self.fig.subplots_adjust(bottom=0.2)
-        total = len(self)
+        total = self.__len__()  # avoids TypeError on None #971
         if total is not None:
             self.xdata = []
             self.ydata = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/keras.py 
new/tqdm-4.47.0/tqdm/keras.py
--- old/tqdm-4.45.0/tqdm/keras.py       2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/keras.py       2020-06-29 00:38:16.000000000 +0200
@@ -91,3 +91,15 @@
         if self.verbose:
             self.batch_bar.close()
         self.epoch_bar.close()
+
+    @staticmethod
+    def _implements_train_batch_hooks():
+        return True
+
+    @staticmethod
+    def _implements_test_batch_hooks():
+        return True
+
+    @staticmethod
+    def _implements_predict_batch_hooks():
+        return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/notebook.py 
new/tqdm-4.47.0/tqdm/notebook.py
--- old/tqdm-4.45.0/tqdm/notebook.py    2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/notebook.py    2020-06-29 00:38:16.000000000 +0200
@@ -56,6 +56,7 @@
             IPY = 2
         except ImportError:
             IPY = 0
+            IProgress = None
 
     try:
         from IPython.display import display  # , clear_output
@@ -91,19 +92,17 @@
         # fp = file
 
         # Prepare IPython progress bar
-        try:
-            if total:
-                pbar = IProgress(min=0, max=total)
-            else:  # No total? Show info style bar with no progress tqdm status
-                pbar = IProgress(min=0, max=1)
-                pbar.value = 1
-                pbar.bar_style = 'info'
-        except NameError:
-            # #187 #451 #558
+        if IProgress is None:  # #187 #451 #558 #872
             raise ImportError(
-                "FloatProgress not found. Please update jupyter and 
ipywidgets."
+                "IProgress not found. Please update jupyter and ipywidgets."
                 " See https://ipywidgets.readthedocs.io/en/stable";
                 "/user_install.html")
+        if total:
+            pbar = IProgress(min=0, max=total)
+        else:  # No total? Show info style bar with no progress tqdm status
+            pbar = IProgress(min=0, max=1)
+            pbar.value = 1
+            pbar.bar_style = 'info'
 
         if desc:
             pbar.description = desc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/std.py new/tqdm-4.47.0/tqdm/std.py
--- old/tqdm-4.45.0/tqdm/std.py 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/std.py 2020-06-29 00:38:16.000000000 +0200
@@ -594,24 +594,26 @@
         """
         fp = file if file is not None else sys.stdout
 
-        if not nolock:
-            cls.get_lock().acquire()
-        # Clear all bars
-        inst_cleared = []
-        for inst in getattr(cls, '_instances', []):
-            # Clear instance if in the target output file
-            # or if write output + tqdm output are both either
-            # sys.stdout or sys.stderr (because both are mixed in terminal)
-            if hasattr(inst, "start_t") and (inst.fp == fp or all(
-                    f in (sys.stdout, sys.stderr) for f in (fp, inst.fp))):
-                inst.clear(nolock=True)
-                inst_cleared.append(inst)
-        yield
-        # Force refresh display of bars we cleared
-        for inst in inst_cleared:
-            inst.refresh(nolock=True)
-        if not nolock:
-            cls._lock.release()
+        try:
+            if not nolock:
+                cls.get_lock().acquire()
+            # Clear all bars
+            inst_cleared = []
+            for inst in getattr(cls, '_instances', []):
+                # Clear instance if in the target output file
+                # or if write output + tqdm output are both either
+                # sys.stdout or sys.stderr (because both are mixed in terminal)
+                if hasattr(inst, "start_t") and (inst.fp == fp or all(
+                        f in (sys.stdout, sys.stderr) for f in (fp, inst.fp))):
+                    inst.clear(nolock=True)
+                    inst_cleared.append(inst)
+            yield
+            # Force refresh display of bars we cleared
+            for inst in inst_cleared:
+                inst.refresh(nolock=True)
+        finally:
+            if not nolock:
+                cls._lock.release()
 
     @classmethod
     def set_lock(cls, lock):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/tests/tests_main.py 
new/tqdm-4.47.0/tqdm/tests/tests_main.py
--- old/tqdm-4.45.0/tqdm/tests/tests_main.py    2020-04-02 14:55:43.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm/tests/tests_main.py    2020-06-29 00:38:16.000000000 
+0200
@@ -5,6 +5,7 @@
 from tempfile import mkdtemp
 from tqdm.cli import main, TqdmKeyError, TqdmTypeError
 from tqdm.utils import IS_WIN
+from io import open as io_open
 
 from tests_tqdm import with_setup, pretest, posttest, _range, closing, \
     UnicodeIO, StringIO, SkipTest
@@ -98,6 +99,33 @@
     rmtree(tmp, True)
 
 
+def test_comppath():
+    """Test CLI --comppath"""
+    if IS_WIN:
+        raise SkipTest
+    tmp = mkdtemp()
+    man = path.join(tmp, "tqdm_completion.sh")
+    assert not path.exists(man)
+    try:
+        main(argv=['--comppath', tmp], fp=NULL)
+    except SystemExit:
+        pass
+    else:
+        raise SystemExit("Expected system exit")
+    assert path.exists(man)
+
+    # check most important options appear
+    with io_open(man, mode='r', encoding='utf-8') as fd:
+        script = fd.read()
+    opts = set([
+        '--help', '--desc', '--total', '--leave', '--ncols', '--ascii',
+        '--dynamic_ncols', '--position', '--bytes', '--nrows', '--delim',
+        '--manpath', '--comppath'
+    ])
+    assert all(args in script for args in opts)
+    rmtree(tmp, True)
+
+
 def test_exceptions():
     """Test CLI Exceptions"""
     _SYS = sys.stdin, sys.argv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/tests/tests_tqdm.py 
new/tqdm-4.47.0/tqdm/tests/tests_tqdm.py
--- old/tqdm-4.45.0/tqdm/tests/tests_tqdm.py    2020-04-02 14:55:43.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm/tests/tests_tqdm.py    2020-06-29 00:38:16.000000000 
+0200
@@ -123,7 +123,10 @@
 
 def pretest():
     # setcheckinterval is deprecated
-    getattr(sys, 'setswitchinterval', getattr(sys, 'setcheckinterval'))(100)
+    try:
+        sys.setswitchinterval(1)
+    except AttributeError:
+        sys.setcheckinterval(100)
 
     if getattr(tqdm, "_instances", False):
         n = len(tqdm._instances)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/tqdm.1 new/tqdm-4.47.0/tqdm/tqdm.1
--- old/tqdm-4.45.0/tqdm/tqdm.1 2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/tqdm.1 2020-06-29 00:38:16.000000000 +0200
@@ -257,6 +257,12 @@
 .RS
 .RE
 .TP
+.B \-\-comppath=\f[I]comppath\f[]
+str, optional.
+Directory in which to place tqdm completion.
+.RS
+.RE
+.TP
 .B \-\-log=\f[I]log\f[]
 str, optional.
 CRITICAL|FATAL|ERROR|WARN(ING)|[default: \[aq]INFO\[aq]]|DEBUG|NOTSET.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm/utils.py 
new/tqdm-4.47.0/tqdm/utils.py
--- old/tqdm-4.45.0/tqdm/utils.py       2020-04-02 14:55:43.000000000 +0200
+++ new/tqdm-4.47.0/tqdm/utils.py       2020-06-29 00:38:16.000000000 +0200
@@ -1,3 +1,6 @@
+"""
+General helpers required for `tqdm.std`.
+"""
 from functools import wraps
 import os
 from platform import system as _curos
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm.egg-info/PKG-INFO 
new/tqdm-4.47.0/tqdm.egg-info/PKG-INFO
--- old/tqdm-4.45.0/tqdm.egg-info/PKG-INFO      2020-04-02 14:56:00.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm.egg-info/PKG-INFO      2020-06-29 00:38:32.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: tqdm
-Version: 4.45.0
+Version: 4.47.0
 Summary: Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Maintainer: tqdm developers
@@ -32,7 +32,7 @@
         ``76%|████████████████████████        | 7568/10000 [00:33<00:10, 
229.00it/s]``
         
         ``trange(N)`` can be also used as a convenient shortcut for
-        ``tqdm(xrange(N))``.
+        ``tqdm(range(N))``.
         
         |Screenshot|
             |Video| |Slides|
@@ -119,6 +119,9 @@
             snap install tqdm  --candidate  # master branch
             snap install tqdm  --edge  # devel branch
         
+        Note than ``snap`` binaries are purely for CLI use (not 
``import``-able), and
+        automatically set up ``bash`` tab-completion.
+        
         Latest Docker release
         ~~~~~~~~~~~~~~~~~~~~~
         
@@ -144,9 +147,8 @@
         
         The list of all changes is available either on GitHub's Releases:
         |GitHub-Status|, on the
-        `wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, on the
-        `website <https://tqdm.github.io/releases/>`__, or on crawlers such as
-        `allmychanges.com <https://allmychanges.com/p/python/tqdm/>`_.
+        `wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the
+        `website <https://tqdm.github.io/releases/>`__.
         
         
         Usage
@@ -469,6 +471,8 @@
             ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 
'B'.
         * manpath  : str, optional  
             Directory in which to install tqdm man pages.
+        * comppath  : str, optional  
+            Directory in which to place tqdm completion.
         * log  : str, optional  
             CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
         
@@ -613,10 +617,19 @@
             def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):
                 """Equivalent of builtin `map`."""
         
+        ``contrib``
+        -----------
+        
         The ``tqdm.contrib`` package also contains experimental modules:
         
         - ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``
         - ``tqdm.contrib.concurrent``: Thin wrappers around 
``concurrent.futures``
+        - ``tqdm.contrib.bells``: Automagically enables all optional features
+        
+          * ``auto``, ``pandas``, ``discord``, ``telegram``
+        
+        - ``tqdm.contrib.discord``: Posts to `Discord 
<https://discord.com/>`__ bots
+        - ``tqdm.contrib.telegram``: Posts to `Telegram 
<https://telegram.org/>`__ bots
         
         Examples and Advanced Usage
         ---------------------------
@@ -815,7 +828,7 @@
                     self.update(b * bsize - self.n)  # will also set self.n = 
b * bsize
         
             eg_link = "https://caspersci.uk.to/matryoshka.zip";
-            with TqdmUpTo(unit='B', unit_scale=True, miniters=1,
+            with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, 
miniters=1,
                           desc=eg_link.split('/')[-1]) as t:  # all optional 
kwargs
                 urllib.urlretrieve(eg_link, filename=os.devnull,
                                    reporthook=t.update_to, data=None)
@@ -864,6 +877,21 @@
                 for chunk in urllib.urlopen(eg_link):
                     fout.write(chunk)
         
+        The ``requests`` equivalent is nearly identical, albeit with a 
``total``:
+        
+        .. code:: python
+        
+            import requests, os
+            from tqdm import tqdm
+        
+            eg_link = "https://caspersci.uk.to/matryoshka.zip";
+            response = requests.get(eg_link, stream=True)
+            with tqdm.wrapattr(open(os.devnull, "wb"), "write",
+                               miniters=1, desc=eg_link.split('/')[-1],
+                               
total=int(response.headers.get('content-length', 0))) as fout:
+                for chunk in response.iter_content(chunk_size=4096):
+                    fout.write(chunk)
+        
         Pandas Integration
         ~~~~~~~~~~~~~~~~~~
         
@@ -1338,6 +1366,7 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: Implementation
 Classifier: Programming Language :: Python :: Implementation :: IronPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.45.0/tqdm.egg-info/SOURCES.txt 
new/tqdm-4.47.0/tqdm.egg-info/SOURCES.txt
--- old/tqdm-4.45.0/tqdm.egg-info/SOURCES.txt   2020-04-02 14:56:00.000000000 
+0200
+++ new/tqdm-4.47.0/tqdm.egg-info/SOURCES.txt   2020-06-29 00:38:32.000000000 
+0200
@@ -16,6 +16,7 @@
 examples/parallel_bars.py
 examples/redirect_print.py
 examples/simple_examples.py
+examples/tqdm_requests.py
 examples/tqdm_wget.py
 examples/wrapping_generators.py
 tqdm/__init__.py
@@ -31,6 +32,7 @@
 tqdm/auto.py
 tqdm/autonotebook.py
 tqdm/cli.py
+tqdm/completion.sh
 tqdm/gui.py
 tqdm/keras.py
 tqdm/notebook.py
@@ -44,8 +46,12 @@
 tqdm.egg-info/requires.txt
 tqdm.egg-info/top_level.txt
 tqdm/contrib/__init__.py
+tqdm/contrib/bells.py
 tqdm/contrib/concurrent.py
+tqdm/contrib/discord.py
 tqdm/contrib/itertools.py
+tqdm/contrib/telegram.py
+tqdm/contrib/utils_worker.py
 tqdm/tests/tests_concurrent.py
 tqdm/tests/tests_contrib.py
 tqdm/tests/tests_itertools.py


Reply via email to