summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 15:59:57 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 16:00:04 +0000
commit44291a7469de49e5e1c73449c9928e7e54ff8d67 (patch)
treef14d7afb233fb6622b728301430b18fbb0020050
parentReleasing debian version 4.66.2-3. (diff)
downloadtqdm-44291a7469de49e5e1c73449c9928e7e54ff8d67.tar.xz
tqdm-44291a7469de49e5e1c73449c9928e7e54ff8d67.zip
Merging upstream version 4.66.4:
- any optional non-boolean CLI arguments are passed through python's eval, allowing arbitrary code execution [CVE-2024-34062] (Closes: #1070372). Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--DEMO.ipynb2
-rw-r--r--README.rst4
-rw-r--r--tests/tests_tqdm.py6
-rw-r--r--tqdm/asyncio.py2
-rw-r--r--tqdm/cli.py33
-rw-r--r--tqdm/contrib/__init__.py2
-rw-r--r--tqdm/contrib/discord.py8
-rw-r--r--tqdm/contrib/logging.py2
-rw-r--r--tqdm/contrib/slack.py8
-rw-r--r--tqdm/contrib/telegram.py10
-rw-r--r--tqdm/dask.py2
-rw-r--r--tqdm/gui.py2
-rw-r--r--tqdm/notebook.py14
-rw-r--r--tqdm/rich.py7
-rw-r--r--tqdm/std.py2
-rw-r--r--tqdm/tk.py4
-rw-r--r--tqdm/utils.py6
18 files changed, 64 insertions, 52 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4de1025..5eb5e3c 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.5.0
+ rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
diff --git a/DEMO.ipynb b/DEMO.ipynb
index 8048cbc..b9bebc4 100644
--- a/DEMO.ipynb
+++ b/DEMO.ipynb
@@ -413,7 +413,7 @@
" \"\"\"Provides a `total_time` format parameter\"\"\"\n",
" @property\n",
" def format_dict(self):\n",
- " d = super(TqdmExtraFormat, self).format_dict\n",
+ " d = super().format_dict\n",
" total_time = d[\"elapsed\"] * (d[\"total\"] or 0) / max(d[\"n\"], 1)\n",
" d.update(total_time=self.format_interval(total_time) + \" in total\")\n",
" return d\n",
diff --git a/README.rst b/README.rst
index a148cb1..a2b626d 100644
--- a/README.rst
+++ b/README.rst
@@ -766,7 +766,7 @@ Additional ``bar_format`` parameters may also be defined by overriding
"""Provides a `total_time` format parameter"""
@property
def format_dict(self):
- d = super(TqdmExtraFormat, self).format_dict
+ d = super().format_dict
total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
d.update(total_time=self.format_interval(total_time) + " in total")
return d
@@ -982,7 +982,7 @@ custom callback take advantage of this, simply use the return value of
class TqdmExt(std_tqdm):
def update(self, n=1):
- displayed = super(TqdmExt, self).update(n)
+ displayed = super().update(n)
if displayed:
external_callback(**self.format_dict)
return displayed
diff --git a/tests/tests_tqdm.py b/tests/tests_tqdm.py
index d0ba14f..25644aa 100644
--- a/tests/tests_tqdm.py
+++ b/tests/tests_tqdm.py
@@ -107,7 +107,7 @@ def cpu_timify(t, timer=None):
class UnicodeIO(IOBase):
"""Unicode version of StringIO"""
def __init__(self, *args, **kwargs):
- super(UnicodeIO, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.encoding = 'U8' # io.StringIO supports unicode, but no encoding
self.text = ''
self.cursor = 0
@@ -342,7 +342,7 @@ def test_all_defaults():
class WriteTypeChecker(BytesIO):
"""File-like to assert the expected type is written"""
def __init__(self, expected_type):
- super(WriteTypeChecker, self).__init__()
+ super().__init__()
self.expected_type = expected_type
def write(self, s):
@@ -1095,7 +1095,7 @@ def test_custom_format():
"""Provides a `total_time` format parameter"""
@property
def format_dict(self):
- d = super(TqdmExtraFormat, self).format_dict
+ d = super().format_dict
total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1)
d.update(total_time=self.format_interval(total_time) + " in total")
return d
diff --git a/tqdm/asyncio.py b/tqdm/asyncio.py
index ddc89b8..2d00a0a 100644
--- a/tqdm/asyncio.py
+++ b/tqdm/asyncio.py
@@ -21,7 +21,7 @@ class tqdm_asyncio(std_tqdm):
Asynchronous-friendly version of tqdm.
"""
def __init__(self, iterable=None, *args, **kwargs):
- super(tqdm_asyncio, self).__init__(iterable, *args, **kwargs)
+ super().__init__(iterable, *args, **kwargs)
self.iterable_awaitable = False
if iterable is not None:
if hasattr(iterable, "__anext__"):
diff --git a/tqdm/cli.py b/tqdm/cli.py
index 1223d49..7284f28 100644
--- a/tqdm/cli.py
+++ b/tqdm/cli.py
@@ -21,23 +21,34 @@ def cast(val, typ):
return cast(val, t)
except TqdmTypeError:
pass
- raise TqdmTypeError(val + ' : ' + typ)
+ raise TqdmTypeError(f"{val} : {typ}")
# sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n')
if typ == 'bool':
if (val == 'True') or (val == ''):
return True
- elif val == 'False':
+ if val == 'False':
return False
- else:
- raise TqdmTypeError(val + ' : ' + typ)
- try:
- return eval(typ + '("' + val + '")')
- except Exception:
- if typ == 'chr':
- return chr(ord(eval('"' + val + '"'))).encode()
- else:
- raise TqdmTypeError(val + ' : ' + typ)
+ raise TqdmTypeError(val + ' : ' + typ)
+ if typ == 'chr':
+ if len(val) == 1:
+ return val.encode()
+ if re.match(r"^\\\w+$", val):
+ return eval(f'"{val}"').encode()
+ raise TqdmTypeError(f"{val} : {typ}")
+ if typ == 'str':
+ return val
+ if typ == 'int':
+ try:
+ return int(val)
+ except ValueError as exc:
+ raise TqdmTypeError(f"{val} : {typ}") from exc
+ if typ == 'float':
+ try:
+ return float(val)
+ except ValueError as exc:
+ raise TqdmTypeError(f"{val} : {typ}") from exc
+ raise TqdmTypeError(f"{val} : {typ}")
def posix_pipe(fin, fout, delim=b'\\n', buf_size=256,
diff --git a/tqdm/contrib/__init__.py b/tqdm/contrib/__init__.py
index 7338c96..d059461 100644
--- a/tqdm/contrib/__init__.py
+++ b/tqdm/contrib/__init__.py
@@ -17,7 +17,7 @@ class DummyTqdmFile(ObjectWrapper):
"""Dummy file-like that will write to tqdm"""
def __init__(self, wrapped):
- super(DummyTqdmFile, self).__init__(wrapped)
+ super().__init__(wrapped)
self._buf = []
def write(self, x, nolock=False):
diff --git a/tqdm/contrib/discord.py b/tqdm/contrib/discord.py
index 1e41308..fd663f9 100644
--- a/tqdm/contrib/discord.py
+++ b/tqdm/contrib/discord.py
@@ -27,7 +27,7 @@ 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__()
+ super().__init__()
config = ClientConfig()
config.token = token
client = Client(config)
@@ -91,10 +91,10 @@ class tqdm_discord(tqdm_auto):
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)
+ super().__init__(*args, **kwargs)
def display(self, **kwargs):
- super(tqdm_discord, self).display(**kwargs)
+ super().display(**kwargs)
fmt = self.format_dict
if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace(
@@ -104,7 +104,7 @@ class tqdm_discord(tqdm_auto):
self.dio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs):
- super(tqdm_discord, self).clear(*args, **kwargs)
+ super().clear(*args, **kwargs)
if not self.disable:
self.dio.write("")
diff --git a/tqdm/contrib/logging.py b/tqdm/contrib/logging.py
index b8eaec5..e06febe 100644
--- a/tqdm/contrib/logging.py
+++ b/tqdm/contrib/logging.py
@@ -18,7 +18,7 @@ class _TqdmLoggingHandler(logging.StreamHandler):
self,
tqdm_class=std_tqdm # type: Type[std_tqdm]
):
- super(_TqdmLoggingHandler, self).__init__()
+ super().__init__()
self.tqdm_class = tqdm_class
def emit(self, record):
diff --git a/tqdm/contrib/slack.py b/tqdm/contrib/slack.py
index d4c850c..9bca8ee 100644
--- a/tqdm/contrib/slack.py
+++ b/tqdm/contrib/slack.py
@@ -27,7 +27,7 @@ class SlackIO(MonoWorker):
"""Non-blocking file-like IO using a Slack app."""
def __init__(self, token, channel):
"""Creates a new message in the given `channel`."""
- super(SlackIO, self).__init__()
+ super().__init__()
self.client = WebClient(token=token)
self.text = self.__class__.__name__
try:
@@ -88,10 +88,10 @@ class tqdm_slack(tqdm_auto):
kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")),
kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL")))
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
- super(tqdm_slack, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def display(self, **kwargs):
- super(tqdm_slack, self).display(**kwargs)
+ super().display(**kwargs)
fmt = self.format_dict
if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace(
@@ -105,7 +105,7 @@ class tqdm_slack(tqdm_auto):
self.sio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs):
- super(tqdm_slack, self).clear(*args, **kwargs)
+ super().clear(*args, **kwargs)
if not self.disable:
self.sio.write("")
diff --git a/tqdm/contrib/telegram.py b/tqdm/contrib/telegram.py
index cbeadf2..0191518 100644
--- a/tqdm/contrib/telegram.py
+++ b/tqdm/contrib/telegram.py
@@ -27,7 +27,7 @@ class TelegramIO(MonoWorker):
def __init__(self, token, chat_id):
"""Creates a new message in the given `chat_id`."""
- super(TelegramIO, self).__init__()
+ super().__init__()
self.token = token
self.chat_id = chat_id
self.session = Session()
@@ -118,10 +118,10 @@ class tqdm_telegram(tqdm_auto):
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)
+ super().__init__(*args, **kwargs)
def display(self, **kwargs):
- super(tqdm_telegram, self).display(**kwargs)
+ super().display(**kwargs)
fmt = self.format_dict
if fmt.get('bar_format', None):
fmt['bar_format'] = fmt['bar_format'].replace(
@@ -131,14 +131,14 @@ class tqdm_telegram(tqdm_auto):
self.tgio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs):
- super(tqdm_telegram, self).clear(*args, **kwargs)
+ super().clear(*args, **kwargs)
if not self.disable:
self.tgio.write("")
def close(self):
if self.disable:
return
- super(tqdm_telegram, self).close()
+ super().close()
if not (self.leave or (self.leave is None and self.pos == 0)):
self.tgio.delete()
diff --git a/tqdm/dask.py b/tqdm/dask.py
index af9926a..57f1b66 100644
--- a/tqdm/dask.py
+++ b/tqdm/dask.py
@@ -20,7 +20,7 @@ class TqdmCallback(Callback):
tqdm_kwargs : optional
Any other arguments used for all bars.
"""
- super(TqdmCallback, self).__init__(start=start, pretask=pretask)
+ super().__init__(start=start, pretask=pretask)
if tqdm_kwargs:
tqdm_class = partial(tqdm_class, **tqdm_kwargs)
self.tqdm_class = tqdm_class
diff --git a/tqdm/gui.py b/tqdm/gui.py
index 8bab6ac..1a80681 100644
--- a/tqdm/gui.py
+++ b/tqdm/gui.py
@@ -32,7 +32,7 @@ class tqdm_gui(std_tqdm): # pragma: no cover
kwargs = kwargs.copy()
kwargs['gui'] = True
colour = kwargs.pop('colour', 'g')
- super(tqdm_gui, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if self.disable:
return
diff --git a/tqdm/notebook.py b/tqdm/notebook.py
index 6ee43a6..77b91bd 100644
--- a/tqdm/notebook.py
+++ b/tqdm/notebook.py
@@ -80,7 +80,7 @@ class TqdmHBox(HBox):
def __repr__(self, pretty=False):
pbar = getattr(self, 'pbar', None)
if pbar is None:
- return super(TqdmHBox, self).__repr__()
+ return super().__repr__()
return pbar.format_meter(**self._json_(pretty))
def _repr_pretty_(self, pp, *_, **__):
@@ -220,7 +220,7 @@ class tqdm_notebook(std_tqdm):
kwargs['disable'] = bool(kwargs.get('disable', False))
colour = kwargs.pop('colour', None)
display_here = kwargs.pop('display', True)
- super(tqdm_notebook, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if self.disable or not kwargs['gui']:
self.disp = lambda *_, **__: None
return
@@ -246,7 +246,7 @@ class tqdm_notebook(std_tqdm):
def __iter__(self):
try:
- it = super(tqdm_notebook, self).__iter__()
+ it = super().__iter__()
for obj in it:
# return super(tqdm...) will not catch exception
yield obj
@@ -259,7 +259,7 @@ class tqdm_notebook(std_tqdm):
def update(self, n=1):
try:
- return super(tqdm_notebook, self).update(n=n)
+ return super().update(n=n)
# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt
except: # NOQA
# cannot catch KeyboardInterrupt when using manual tqdm
@@ -272,7 +272,7 @@ class tqdm_notebook(std_tqdm):
def close(self):
if self.disable:
return
- super(tqdm_notebook, self).close()
+ super().close()
# Try to detect if there was an error or KeyboardInterrupt
# in manual mode: if n < total, things probably got wrong
if self.total and self.n < self.total:
@@ -297,14 +297,14 @@ class tqdm_notebook(std_tqdm):
total : int or float, optional. Total to use for the new bar.
"""
if self.disable:
- return super(tqdm_notebook, self).reset(total=total)
+ return super().reset(total=total)
_, pbar, _ = self.container.children
pbar.bar_style = ''
if total is not None:
pbar.max = total
if not self.total and self.ncols is None: # no longer unknown total
pbar.layout.width = None # reset width
- return super(tqdm_notebook, self).reset(total=total)
+ return super().reset(total=total)
def tnrange(*args, **kwargs):
diff --git a/tqdm/rich.py b/tqdm/rich.py
index 00e1ddf..3d392ed 100644
--- a/tqdm/rich.py
+++ b/tqdm/rich.py
@@ -90,7 +90,7 @@ class tqdm_rich(std_tqdm): # pragma: no cover
kwargs['disable'] = bool(kwargs.get('disable', False))
progress = kwargs.pop('progress', None)
options = kwargs.pop('options', {}).copy()
- super(tqdm_rich, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if self.disable:
return
@@ -116,7 +116,8 @@ class tqdm_rich(std_tqdm): # pragma: no cover
def close(self):
if self.disable:
return
- super(tqdm_rich, self).close()
+ self.display() # print 100%, vis #1306
+ super().close()
self._prog.__exit__(None, None, None)
def clear(self, *_, **__):
@@ -137,7 +138,7 @@ class tqdm_rich(std_tqdm): # pragma: no cover
"""
if hasattr(self, '_prog'):
self._prog.reset(total=total)
- super(tqdm_rich, self).reset(total=total)
+ super().reset(total=total)
def trrange(*args, **kwargs):
diff --git a/tqdm/std.py b/tqdm/std.py
index e58fdca..e91ad30 100644
--- a/tqdm/std.py
+++ b/tqdm/std.py
@@ -46,7 +46,7 @@ class TqdmWarning(Warning):
if fp_write is not None:
fp_write("\n" + self.__class__.__name__ + ": " + str(msg).rstrip() + '\n')
else:
- super(TqdmWarning, self).__init__(msg, *a, **k)
+ super().__init__(msg, *a, **k)
class TqdmExperimentalWarning(TqdmWarning, FutureWarning):
diff --git a/tqdm/tk.py b/tqdm/tk.py
index dfebf5c..788303c 100644
--- a/tqdm/tk.py
+++ b/tqdm/tk.py
@@ -53,7 +53,7 @@ class tqdm_tk(std_tqdm): # pragma: no cover
grab = kwargs.pop('grab', False)
tk_parent = kwargs.pop('tk_parent', None)
self._cancel_callback = kwargs.pop('cancel_callback', None)
- super(tqdm_tk, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if self.disable:
return
@@ -172,7 +172,7 @@ class tqdm_tk(std_tqdm): # pragma: no cover
self._tk_pbar.configure(maximum=100, mode="indeterminate")
else:
self._tk_pbar.configure(maximum=total, mode="determinate")
- super(tqdm_tk, self).reset(total=total)
+ super().reset(total=total)
@staticmethod
def _tk_dispatching_helper():
diff --git a/tqdm/utils.py b/tqdm/utils.py
index 9883fda..f7060be 100644
--- a/tqdm/utils.py
+++ b/tqdm/utils.py
@@ -167,7 +167,7 @@ class SimpleTextIOWrapper(ObjectWrapper):
"""
# pylint: disable=too-few-public-methods
def __init__(self, wrapped, encoding):
- super(SimpleTextIOWrapper, self).__init__(wrapped)
+ super().__init__(wrapped)
self.wrapper_setattr('encoding', encoding)
def write(self, s):
@@ -211,7 +211,7 @@ class DisableOnWriteError(ObjectWrapper):
return inner
def __init__(self, wrapped, tqdm_instance):
- super(DisableOnWriteError, self).__init__(wrapped)
+ super().__init__(wrapped)
if hasattr(wrapped, 'write'):
self.wrapper_setattr(
'write', self.disable_on_exception(tqdm_instance, wrapped.write))
@@ -229,7 +229,7 @@ class CallbackIOWrapper(ObjectWrapper):
Wrap a given `file`-like object's `read()` or `write()` to report
lengths to the given `callback`
"""
- super(CallbackIOWrapper, self).__init__(stream)
+ super().__init__(stream)
func = getattr(stream, method)
if method == "write":
@wraps(func)