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