summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-09 08:15:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-09 08:15:46 +0000
commit9dfce4242afc2b5ac28ae2544ab8b8680c00d2f1 (patch)
tree43abf0767ec8581c4375aa63e02e778a9d1b2448
parentReleasing debian version 4.66.5-1. (diff)
downloadtqdm-9dfce4242afc2b5ac28ae2544ab8b8680c00d2f1.tar.xz
tqdm-9dfce4242afc2b5ac28ae2544ab8b8680c00d2f1.zip
Merging upstream version 4.67.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.pre-commit-config.yaml6
-rw-r--r--DEMO.ipynb2
-rw-r--r--Makefile4
-rw-r--r--README.rst4
-rw-r--r--examples/paper.bib2
-rw-r--r--pyproject.toml3
-rw-r--r--tox.ini2
-rw-r--r--tqdm/cli.py19
-rw-r--r--tqdm/contrib/discord.py83
9 files changed, 82 insertions, 43 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 34c8344..0eff569 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,7 +2,7 @@ default_language_version:
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.6.0
+ rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
@@ -37,9 +37,9 @@ repos:
- numpy
- pandas
- pytest-timeout
- - pytest-asyncio
+ - pytest-asyncio>0.21
- repo: https://github.com/PyCQA/flake8
- rev: 7.1.0
+ rev: 7.1.1
hooks:
- id: flake8
args: [-j8]
diff --git a/DEMO.ipynb b/DEMO.ipynb
index b9bebc4..73489bd 100644
--- a/DEMO.ipynb
+++ b/DEMO.ipynb
@@ -843,7 +843,7 @@
"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",
- "[![README-Hits](https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif)](https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social)|(Since 19 May 2016)\n",
+ "[![README-Hits](https://cgi.cdcl.ml/hits?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif)](https://cgi.cdcl.ml/hits?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social)|(Since 19 May 2016)\n",
"-|-"
]
},
diff --git a/Makefile b/Makefile
index ab2863c..e61571c 100644
--- a/Makefile
+++ b/Makefile
@@ -61,11 +61,11 @@ testsetup:
@make help
testnb:
- pytest tests_notebook.ipynb --cov=tqdm.notebook --cov-report=term -W=ignore --nbval --current-env --sanitize-with=.meta/nbval.ini
+ pytest tests_notebook.ipynb --cov=tqdm.notebook --cov-report=term -W=ignore --nbval --nbval-current-env --nbval-sanitize-with=.meta/nbval.ini
testcoverage:
@make coverclean
- pytest tests_notebook.ipynb --cov=tqdm --cov-report= -W=ignore --nbval --current-env --sanitize-with=.meta/nbval.ini
+ pytest tests_notebook.ipynb --cov=tqdm --cov-report= -W=ignore --nbval --nbval-current-env --nbval-sanitize-with=.meta/nbval.ini
pytest -k "not perf" --cov=tqdm --cov-report=xml --cov-report=term --cov-append --cov-fail-under=80
testperf:
diff --git a/README.rst b/README.rst
index a2b626d..307dac4 100644
--- a/README.rst
+++ b/README.rst
@@ -1505,5 +1505,5 @@ Citation information: |DOI|
.. |Screenshot-Jupyter1| image:: https://tqdm.github.io/img/jupyter-1.gif
.. |Screenshot-Jupyter2| image:: https://tqdm.github.io/img/jupyter-2.gif
.. |Screenshot-Jupyter3| image:: https://tqdm.github.io/img/jupyter-3.gif
-.. |README-Hits| image:: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif
- :target: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social
+.. |README-Hits| image:: https://cgi.cdcl.ml/hits?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif
+ :target: https://cgi.cdcl.ml/hits?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social
diff --git a/examples/paper.bib b/examples/paper.bib
index 13901e5..a30d136 100644
--- a/examples/paper.bib
+++ b/examples/paper.bib
@@ -126,7 +126,7 @@
@misc{hits,
year="2019",
title="{tqdm} hits",
- url="https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot",
+ url="https://cgi.cdcl.ml/hits?q=tqdm&a=plot",
author="Casper O. {da Costa-Luis}"
}
@book{miller,
diff --git a/pyproject.toml b/pyproject.toml
index ce05eed..5651e88 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,6 +24,7 @@ readme = "README.rst"
requires-python = ">=3.7"
keywords = ["progressbar", "progressmeter", "progress", "bar", "meter", "rate", "eta", "console", "terminal", "time"]
license = {text = "MPL-2.0 AND MIT"}
+# Trove classifiers (https://pypi.org/pypi?%3Aaction=list_classifiers)
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
@@ -84,6 +85,7 @@ dependencies = ['colorama; platform_system == "Windows"']
[project.optional-dependencies]
dev = ["pytest>=6", "pytest-cov", "pytest-timeout", "pytest-xdist"]
+discord = ["requests"]
slack = ["slack-sdk"]
telegram = ["requests"]
notebook = ["ipywidgets>=6"]
@@ -120,6 +122,7 @@ markers = ["asyncio", "slow"]
python_files = ["tests_*.py", "tests_*.ipynb"]
testpaths = ["tests"]
addopts = "-v --tb=short -rxs -W=error --durations=0 --durations-min=0.1 --asyncio-mode=strict"
+asyncio_default_fixture_loop_scope = "function"
[tool.coverage.run]
branch = true
diff --git a/tox.ini b/tox.ini
index 2fb9e08..35c3e6f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -49,7 +49,7 @@ deps=
tf: tensorflow!=2.5.0
keras: keras
commands=
- pytest --cov=tqdm --cov-report= -W=ignore tests_notebook.ipynb --nbval --current-env --sanitize-with=.meta/nbval.ini
+ pytest --cov=tqdm --cov-report= -W=ignore tests_notebook.ipynb --nbval --nbval-current-env --nbval-sanitize-with=.meta/nbval.ini
pytest --cov=tqdm --cov-report=xml --cov-report=term --cov-append -k "not perf"
{[core]commands}
allowlist_externals=codacy
diff --git a/tqdm/cli.py b/tqdm/cli.py
index d681b16..e54a7fc 100644
--- a/tqdm/cli.py
+++ b/tqdm/cli.py
@@ -258,22 +258,21 @@ Options:
stdout = getattr(stdout, 'buffer', stdout)
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
if manpath or comppath:
- from importlib import resources
- from os import path
- from shutil import copyfile
+ try: # py<3.9
+ import importlib_resources as resources
+ except ImportError:
+ from importlib import resources
+ from pathlib import Path
def cp(name, dst):
"""copy resource `name` to `dst`"""
- if hasattr(resources, 'files'):
- copyfile(str(resources.files('tqdm') / name), dst)
- else: # py<3.9
- with resources.path('tqdm', name) as src:
- copyfile(str(src), dst)
+ fi = resources.files('tqdm') / name
+ dst.write_bytes(fi.read_bytes())
log.info("written:%s", dst)
if manpath is not None:
- cp('tqdm.1', path.join(manpath, 'tqdm.1'))
+ cp('tqdm.1', Path(manpath) / 'tqdm.1')
if comppath is not None:
- cp('completion.sh', path.join(comppath, 'tqdm_completion.sh'))
+ cp('completion.sh', Path(comppath) / 'tqdm_completion.sh')
sys.exit(0)
if tee:
stdout_write = stdout.write
diff --git a/tqdm/contrib/discord.py b/tqdm/contrib/discord.py
index fd663f9..574baa8 100644
--- a/tqdm/contrib/discord.py
+++ b/tqdm/contrib/discord.py
@@ -8,49 +8,83 @@ Usage:
![screenshot](https://tqdm.github.io/img/screenshot-discord.png)
"""
-import logging
from os import getenv
+from warnings import warn
-try:
- from disco.client import Client, ClientConfig
-except ImportError:
- raise ImportError("Please `pip install disco-py`")
+from requests import Session
+from requests.utils import default_user_agent
from ..auto import tqdm as tqdm_auto
+from ..std import TqdmWarning
+from ..version import __version__
from .utils_worker import MonoWorker
-__author__ = {"github.com/": ["casperdcl"]}
+__author__ = {"github.com/": ["casperdcl", "guigoruiz1"]}
__all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange']
class DiscordIO(MonoWorker):
"""Non-blocking file-like IO using a Discord Bot."""
+ API = "https://discord.com/api/v10"
+ UA = f"tqdm (https://tqdm.github.io, {__version__}) {default_user_agent()}"
+
def __init__(self, token, channel_id):
"""Creates a new message in the given `channel_id`."""
super().__init__()
- config = ClientConfig()
- config.token = token
- client = Client(config)
+ self.token = token
+ self.channel_id = channel_id
+ self.session = Session()
self.text = self.__class__.__name__
+ self.message_id
+
+ @property
+ def message_id(self):
+ if hasattr(self, '_message_id'):
+ return self._message_id
try:
- self.message = client.api.channels_messages_create(channel_id, self.text)
+ res = self.session.post(
+ f'{self.API}/channels/{self.channel_id}/messages',
+ headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA},
+ json={'content': f"`{self.text}`"}).json()
except Exception as e:
tqdm_auto.write(str(e))
- self.message = None
+ else:
+ if res.get('error_code') == 429:
+ warn("Creation rate limit: try increasing `mininterval`.",
+ TqdmWarning, stacklevel=2)
+ else:
+ self._message_id = res['id']
+ return self._message_id
def write(self, s):
- """Replaces internal `message`'s text with `s`."""
+ """Replaces internal `message_id`'s text with `s`."""
if not s:
s = "..."
s = s.replace('\r', '').strip()
if s == self.text:
- return # skip duplicate message
- message = self.message
- if message is None:
+ return # avoid duplicate message Bot error
+ message_id = self.message_id
+ if message_id is None:
return
self.text = s
try:
- future = self.submit(message.edit, '`' + s + '`')
+ future = self.submit(
+ self.session.patch,
+ f'{self.API}/channels/{self.channel_id}/messages/{message_id}',
+ headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA},
+ json={'content': f"`{self.text}`"})
+ except Exception as e:
+ tqdm_auto.write(str(e))
+ else:
+ return future
+
+ def delete(self):
+ """Deletes internal `message_id`."""
+ try:
+ future = self.submit(
+ self.session.delete,
+ f'{self.API}/channels/{self.channel_id}/messages/{self.message_id}',
+ headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA})
except Exception as e:
tqdm_auto.write(str(e))
else:
@@ -75,22 +109,18 @@ class tqdm_discord(tqdm_auto):
"""
Parameters
----------
- token : str, required. Discord token
+ token : str, required. Discord bot 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.
"""
if not kwargs.get('disable'):
kwargs = kwargs.copy()
- logging.getLogger("HTTPClient").setLevel(logging.WARNING)
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))
+ kwargs.pop('token', getenv('TQDM_DISCORD_TOKEN')),
+ kwargs.pop('channel_id', getenv('TQDM_DISCORD_CHANNEL_ID')))
super().__init__(*args, **kwargs)
def display(self, **kwargs):
@@ -108,6 +138,13 @@ class tqdm_discord(tqdm_auto):
if not self.disable:
self.dio.write("")
+ def close(self):
+ if self.disable:
+ return
+ super().close()
+ if not (self.leave or (self.leave is None and self.pos == 0)):
+ self.dio.delete()
+
def tdrange(*args, **kwargs):
"""Shortcut for `tqdm.contrib.discord.tqdm(range(*args), **kwargs)`."""