Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next release v4.57.0 #1127

Merged
merged 13 commits into from Feb 18, 2021
11 changes: 0 additions & 11 deletions .coveragerc

This file was deleted.

1 change: 0 additions & 1 deletion .gitattributes
Expand Up @@ -7,4 +7,3 @@
images/ export-ignore
benchmarks/ export-ignore
asv.conf.json export-ignore
.tqdm.1.md export-ignore
31 changes: 22 additions & 9 deletions .github/workflows/test.yml
Expand Up @@ -66,7 +66,11 @@ jobs:
shell: bash
env:
PYVER: ${{ matrix.python }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
COVERALLS_FLAG_NAME: py${{ matrix.python }}-${{ matrix.os }}
COVERALLS_PARALLEL: true
COVERALLS_SERVICE_NAME: github
# coveralls needs explicit token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
test:
if: github.event_name != 'pull_request' || github.head_ref != 'devel'
Expand Down Expand Up @@ -102,23 +106,32 @@ jobs:
fi
env:
PYVER: ${{ matrix.python }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
COVERALLS_FLAG_NAME: py${{ matrix.python }}
COVERALLS_PARALLEL: true
COVERALLS_SERVICE_NAME: github
# coveralls needs explicit token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
- name: Coveralls Parallel
uses: AndreMiras/coveralls-python-action@develop
with:
parallel: true
finish:
if: github.event_name != 'pull_request' || github.head_ref != 'devel'
name: pytest cov
continue-on-error: ${{ github.event_name != 'push' }}
needs: [test, test-os]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v2
- name: Coveralls Finished
uses: AndreMiras/coveralls-python-action@develop
with:
parallel-finished: true
run: |
pip install -U coveralls
coveralls --finish || :
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Codacy Finished
run: |
curl -sfL https://coverage.codacy.com/get.sh > codacy
bash codacy final || :
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
deploy:
if: github.event_name != 'pull_request' || github.head_ref != 'devel'
needs: [check, test, test-os]
Expand Down
9 changes: 6 additions & 3 deletions .meta/.readme.rst
Expand Up @@ -658,6 +658,7 @@ Here's an example with ``urllib``:

import urllib, os
from tqdm import tqdm
urllib = getattr(urllib, 'request', urllib)

class TqdmUpTo(tqdm):
"""Provides `update_to(n)` which uses `tqdm.update(delta_n)`."""
Expand Down Expand Up @@ -719,12 +720,14 @@ down to:
from tqdm import tqdm

eg_link = "https://caspersci.uk.to/matryoshka.zip"
response = getattr(urllib, 'request', urllib).urlopen(eg_link)
with tqdm.wrapattr(open(os.devnull, "wb"), "write",
miniters=1, desc=eg_link.split('/')[-1]) as fout:
for chunk in urllib.urlopen(eg_link):
miniters=1, desc=eg_link.split('/')[-1],
total=getattr(response, 'length', None)) as fout:
for chunk in response:
fout.write(chunk)

The ``requests`` equivalent is nearly identical, albeit with a ``total``:
The ``requests`` equivalent is nearly identical:

.. code:: python

Expand Down
4 changes: 2 additions & 2 deletions .meta/mksnap.py
Expand Up @@ -5,7 +5,7 @@
import sys
from io import open as io_open
from os import path
from subprocess import check_output
from subprocess import check_output # nosec

sys.path.insert(1, path.dirname(path.dirname(__file__)))
import tqdm # NOQA
Expand Down Expand Up @@ -65,7 +65,7 @@
command: bin/tqdm
completer: completion.sh
""".format(version=tqdm.__version__, commit=check_output([
'git', 'describe', '--always']).decode('U8').strip())
'git', 'describe', '--always']).decode('U8').strip()) # nosec
fname = path.join(path.dirname(src_dir), 'snapcraft.yaml')

if __name__ == "__main__":
Expand Down
56 changes: 36 additions & 20 deletions DEMO.ipynb
Expand Up @@ -10,10 +10,10 @@
"[![Py-Versions](https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white)](https://pypi.org/project/tqdm)|[![Versions](https://img.shields.io/pypi/v/tqdm.svg)](https://tqdm.github.io/releases)|[![Conda-Forge-Status](https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge)](https://anaconda.org/conda-forge/tqdm)|[![Docker](https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/tqdm/tqdm)|[![Snapcraft](https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft)](https://snapcraft.io/tqdm)\n",
"-|-|-|-|-\n",
"\n",
"[![Build-Status](https://img.shields.io/github/workflow/status/tqdm/tqdm/Test/master?logo=GitHub)](https://github.com/tqdm/tqdm/actions?query=workflow%3ATest)|[![Coverage-Status](https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls)](https://coveralls.io/github/tqdm/tqdm)|[![Branch-Coverage-Status](https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg)](https://codecov.io/gh/tqdm/tqdm)|[![Codacy-Grade](https://api.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177)](https://www.codacy.com/app/tqdm/tqdm/dashboard)|[![Libraries-Rank](https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white)](https://libraries.io/pypi/tqdm)|[![PyPI-Downloads](https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white)](https://pypi.org/project/tqdm)\n",
"[![Build-Status](https://img.shields.io/github/workflow/status/tqdm/tqdm/Test/master?logo=GitHub)](https://github.com/tqdm/tqdm/actions?query=workflow%3ATest)|[![Coverage-Status](https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls)](https://coveralls.io/github/tqdm/tqdm)|[![Branch-Coverage-Status](https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg)](https://codecov.io/gh/tqdm/tqdm)|[![Codacy-Grade](https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177)](https://www.codacy.com/gh/tqdm/tqdm/dashboard)|[![Libraries-Rank](https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white)](https://libraries.io/pypi/tqdm)|[![PyPI-Downloads](https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white)](https://pypi.org/project/tqdm)\n",
"-|-|-|-|-|-\n",
"\n",
"[![DOI](https://img.shields.io/badge/DOI-10.21105/joss.01277-green.svg)](https://doi.org/10.21105/joss.01277)|[![LICENCE](https://img.shields.io/pypi/l/tqdm.svg)](https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE)|[![OpenHub-Status](https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif)](https://www.openhub.net/p/tqdm?ref=Thin+badge)|[![binder-demo](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb)|[![awesome-python](https://awesome.re/mentioned-badge.svg)](https://github.com/vinta/awesome-python)\n",
"[![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg)](https://doi.org/10.5281/zenodo.595120)|[![LICENCE](https://img.shields.io/pypi/l/tqdm.svg)](https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE)|[![OpenHub-Status](https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif)](https://www.openhub.net/p/tqdm?ref=Thin+badge)|[![binder-demo](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb)|[![awesome-python](https://awesome.re/mentioned-badge.svg)](https://github.com/vinta/awesome-python)\n",
"-|-|-|-|-\n",
"\n",
"`tqdm` derives from the Arabic word *taqaddum* (تقدّم) which can mean\n",
Expand Down Expand Up @@ -428,7 +428,6 @@
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" Extra CLI Options\n",
" -----------------\n",
" delim : chr, optional\n",
Expand All @@ -440,13 +439,24 @@
" bytes : bool, optional\n",
" If true, will count bytes, ignore `delim`, and default\n",
" `unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.\n",
" tee : bool, optional\n",
" If true, passes `stdin` to both `stderr` and `stdout`.\n",
" update : bool, optional\n",
" If true, will treat input as newly elapsed iterations,\n",
" i.e. numbers to pass to `update()`. Note that this is slow\n",
" (~2e5 it/s) since every input must be decoded as a number.\n",
" update_to : bool, optional\n",
" If true, will treat input as total elapsed iterations,\n",
" i.e. numbers to assign to `self.n`. Note that this is slow\n",
" (~2e5 it/s) since every input must be decoded as a number.\n",
" null : bool, optional\n",
" If true, will discard input (no stdout).\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"
" CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.\n"
]
}
],
Expand Down Expand Up @@ -533,7 +543,15 @@
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"00:00 in total: 44%|0000. | 4/9 [00:00<00:00, 29799.67it/s]\n"
]
}
],
"source": [
"from tqdm import tqdm\n",
"from time import sleep\n",
Expand Down Expand Up @@ -690,6 +708,7 @@
"source": [
"import urllib, os\n",
"from tqdm import tqdm\n",
"urllib = getattr(urllib, 'request', urllib)\n",
"\n",
"class TqdmUpTo(tqdm):\n",
" \"\"\"Provides `update_to(n)` which uses `tqdm.update(delta_n)`.\"\"\"\n",
Expand Down Expand Up @@ -760,7 +779,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
"matryoshka.zip: 254kB [00:00, 334kB/s] \n"
"matryoshka.zip: 100%|██████████| 254k/254k [00:00<00:00, 602kB/s] \n"
]
}
],
Expand All @@ -769,17 +788,19 @@
"from tqdm import tqdm\n",
"\n",
"eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n",
"response = getattr(urllib, 'request', urllib).urlopen(eg_link)\n",
"with tqdm.wrapattr(open(os.devnull, \"wb\"), \"write\",\n",
" miniters=1, desc=eg_link.split('/')[-1]) as fout:\n",
" for chunk in urllib.urlopen(eg_link):\n",
" miniters=1, desc=eg_link.split('/')[-1],\n",
" total=getattr(response, 'length', None)) as fout:\n",
" for chunk in response:\n",
" fout.write(chunk)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `requests` equivalent is nearly identical, albeit with a `total`:"
"The `requests` equivalent is nearly identical:"
]
},
{
Expand Down Expand Up @@ -1659,11 +1680,6 @@
"specify any file-like object using the `file` argument. For example,\n",
"this can be used to redirect the messages writing to a log file or class.\n",
"\n",
"---\n",
"\n",
"[![sourcerer-0](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/0)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/0)|[![sourcerer-1](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/1)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/1)|[![sourcerer-2](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/2)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/2)|[![sourcerer-3](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/3)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/3)|[![sourcerer-4](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/4)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/4)|[![sourcerer-5](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/5)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/5)|[![sourcerer-7](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/images/7)](https://sourcerer.io/fame/casperdcl/tqdm/tqdm/links/7)\n",
"-|-|-|-|-|-|-\n",
"\n",
"[![README-Hits](https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://caspersci.uk.to/images/tqdm.png&f=https://raw.githubusercontent.com/tqdm/tqdm/master/images/logo.gif)](https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://caspersci.uk.to/images/tqdm.png&f=https://raw.githubusercontent.com/tqdm/tqdm/master/images/logo.gif&style=social)|(Since 19 May 2016)\n",
"-|-"
]
Expand Down Expand Up @@ -1692,21 +1708,21 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"display_name": "Python 3",
"language": "python",
"name": "python2"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.15"
"pygments_lexer": "ipython3",
"version": "3.7.8"
}
},
"nbformat": 4,
Expand Down
6 changes: 3 additions & 3 deletions examples/7zx.py
Expand Up @@ -25,7 +25,7 @@
import os
import pty
import re
import subprocess
import subprocess # nosec

from argopt import argopt

Expand All @@ -51,7 +51,7 @@ def main():
# Get compressed sizes
zips = {}
for fn in args.zipfiles:
info = subprocess.check_output(["7z", "l", fn]).strip()
info = subprocess.check_output(["7z", "l", fn]).strip() # nosec
finfo = RE_SCN.findall(info) # size|compressed|name

# builtin test: last line should be total sizes
Expand Down Expand Up @@ -81,7 +81,7 @@ def main():
cmd7zx + [fn],
bufsize=1,
stdout=md, # subprocess.PIPE,
stderr=subprocess.STDOUT)
stderr=subprocess.STDOUT) # nosec
os.close(sd)
with io.open(md, mode="rU", buffering=1) as m:
with tqdm(total=sum(fcomp.values()), disable=len(zips) < 2,
Expand Down
2 changes: 1 addition & 1 deletion examples/parallel_bars.py
Expand Up @@ -16,7 +16,7 @@


def progresser(n, auto_position=True, write_safe=False, blocking=True, progress=False):
interval = random() * 0.002 / (NUM_SUBITERS - n + 2)
interval = random() * 0.002 / (NUM_SUBITERS - n + 2) # nosec
total = 5000
text = "#{0}, est. {1:<04.2}s".format(n, interval * total)
for _ in trange(total, desc=text, disable=not progress,
Expand Down
15 changes: 10 additions & 5 deletions examples/tqdm_wget.py
Expand Up @@ -20,7 +20,10 @@
The local file path in which to save the url [default: /dev/null].
"""

import urllib
try:
from urllib import request as urllib
except ImportError: # py2
import urllib
from os import devnull

from docopt import docopt
Expand Down Expand Up @@ -97,12 +100,14 @@ def update_to(self, b=1, bsize=1, tsize=None):
# reporthook=my_hook(t), data=None)
with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
desc=eg_file) as t: # all optional kwargs
urllib.urlretrieve(eg_link, filename=eg_out, reporthook=t.update_to,
data=None)
urllib.urlretrieve( # nosec
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()`
response = urllib.urlopen(eg_link) # nosec
with tqdm.wrapattr(open(eg_out, "wb"), "write",
miniters=1, desc=eg_file) as fout:
for chunk in urllib.urlopen(eg_link):
miniters=1, desc=eg_file,
total=getattr(response, 'length', None)) as fout:
for chunk in response:
fout.write(chunk)
12 changes: 12 additions & 0 deletions setup.cfg
Expand Up @@ -118,3 +118,15 @@ markers=
python_files=tests_*.py
testpaths=tests
addopts=-v --tb=short -rxs -W=error --durations=0 --durations-min=0.1

[coverage:run]
branch=True
include=tqdm/*
omit=
tqdm/contrib/bells.py
tqdm/contrib/discord.py
tqdm/contrib/telegram.py
tqdm/contrib/utils_worker.py
relative_files=True
[coverage:report]
show_missing=True
6 changes: 3 additions & 3 deletions setup.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
from os import path

from setuptools import setup

src_dir = os.path.abspath(os.path.dirname(__file__))
src_dir = path.abspath(path.dirname(__file__))
if sys.argv[1].lower().strip() == 'make': # exec Makefile commands
import pymake
fpath = os.path.join(src_dir, 'Makefile')
fpath = path.join(src_dir, 'Makefile')
pymake.main(['-f', fpath] + sys.argv[2:])
# Stop to avoid setup.py raising non-standard command error
sys.exit(0)
Expand Down
8 changes: 4 additions & 4 deletions tests/tests_main.py
@@ -1,6 +1,6 @@
"""Test CLI usage."""
import logging
import subprocess
import subprocess # nosec
import sys
from functools import wraps
from os import linesep
Expand Down Expand Up @@ -34,11 +34,11 @@ def norm(bytestr):
@mark.slow
def test_pipes():
"""Test command line pipes"""
ls_out = subprocess.check_output(['ls'])
ls = subprocess.Popen(['ls'], stdout=subprocess.PIPE)
ls_out = subprocess.check_output(['ls']) # nosec
ls = subprocess.Popen(['ls'], stdout=subprocess.PIPE) # nosec
res = subprocess.Popen(
[sys.executable, '-c', 'from tqdm.cli import main; main()'],
stdin=ls.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdin=ls.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # nosec
out, err = res.communicate()
assert ls.poll() == 0

Expand Down