diff --git a/README.rst b/README.rst index 3d031b1f2..4ef00b259 100644 --- a/README.rst +++ b/README.rst @@ -407,15 +407,6 @@ Parameters * disable : bool, optional Whether to disable the entire progressbar wrapper [default: False]. If set to None, disable on non-TTY. -* unit : str, optional - String that will be used to define the unit of each iteration - [default: it]. -* unit_scale : bool or int or float, optional - If 1 or True, the number of iterations will be reduced/scaled - automatically and a metric prefix following the - International System of Units standard will be added - (kilo, mega, etc.) [default: False]. If any other non-zero - number, will scale ``total`` and ``n``. * dynamic_ncols : bool, optional If set, constantly alters ``ncols`` and ``nrows`` to the environment (allowing for window resizes) [default: False]. @@ -447,8 +438,24 @@ Parameters * postfix : dict or ``*``, optional Specify additional stats to display at the end of the bar. Calls ``set_postfix(**postfix)`` if possible (dict). +* unit : str, optional + String that will be used to define the unit of each iteration + [default: it]. +* unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be reduced/scaled + automatically and a metric prefix following the + International System of Units standard will be added + (kilo, mega, etc.) [default: False]. If any other non-zero + number, will scale ``total`` and ``n``. * unit_divisor : float, optional [default: 1000], ignored unless ``unit_scale`` is True. +* unit_pre : str, optional + Pre-prefix [default: '']. +* unit_prefixes : list or str, optional + Prefixes (default: [''] + list('kMGTPEZY')). + Use ``"IEEE1541"`` or ``"bytes"`` as a shortcut to override: + unit='B', unit_scale=True, unit_divisor=1024, unit_pre=' ', + unit_prefixes=[''] + [i + 'i' for i in 'KMGTPEZY']. * write_bytes : bool, optional If (default: None) and ``file`` is unspecified, bytes will be written in Python 2. If ``True`` will also write @@ -474,7 +481,7 @@ Extra CLI Options used when ``delim`` is specified. * bytes : bool, optional If true, will count bytes, ignore ``delim``, and default - ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'. + ``unit_prefixes`` to ``"IEEE1541"``. * tee : bool, optional If true, passes ``stdin`` to both ``stderr`` and ``stdout``. * update : bool, optional diff --git a/setup.cfg b/setup.cfg index 46d3a553b..8c1dd48a9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,8 +2,8 @@ universal = 1 [flake8] -ignore = W503,W504,E722 -max_line_length = 80 +ignore = W503,W504,E203,E722 +max_line_length = 88 exclude = .asv,.tox,.ipynb_checkpoints,build,dist,.git,__pycache__ [tool:pytest] diff --git a/tqdm/cli.py b/tqdm/cli.py index 0f1ae981f..387f1e8e0 100644 --- a/tqdm/cli.py +++ b/tqdm/cli.py @@ -139,7 +139,7 @@ def posix_pipe(fin, fout, delim=b'\\n', buf_size=256, used when `delim` is specified. bytes : bool, optional If true, will count bytes, ignore `delim`, and default - `unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'. + `unit_prefixes` to `"IEEE1541"`. tee : bool, optional If true, passes `stdin` to both `stderr` and `stdout`. update : bool, optional @@ -289,9 +289,7 @@ def write(x): fp_write(x) stdout_write(x) if delim_per_char: - tqdm_args.setdefault('unit', 'B') - tqdm_args.setdefault('unit_scale', True) - tqdm_args.setdefault('unit_divisor', 1024) + tqdm_args.setdefault('unit_prefixes', 'IEEE1541') log.debug(tqdm_args) with tqdm(**tqdm_args) as t: posix_pipe(stdin, stdout, '', buf_size, t.update) diff --git a/tqdm/completion.sh b/tqdm/completion.sh index 788549cae..f249e78f3 100755 --- a/tqdm/completion.sh +++ b/tqdm/completion.sh @@ -5,14 +5,14 @@ _tqdm(){ prv="${COMP_WORDS[COMP_CWORD - 1]}" case ${prv} in - --bar_format|--buf_size|--colour|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor) + --bar_format|--buf_size|--colour|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor|--unit_pre) # 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 --colour --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur})) + COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_pre --unit_prefixes --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur})) ;; esac } diff --git a/tqdm/std.py b/tqdm/std.py index 804dfe1d4..1ff898a29 100644 --- a/tqdm/std.py +++ b/tqdm/std.py @@ -17,6 +17,7 @@ # native libraries from contextlib import contextmanager from datetime import datetime, timedelta +from functools import partial from numbers import Number from time import time from warnings import warn @@ -226,7 +227,7 @@ class tqdm(Comparable): monitor = None @staticmethod - def format_sizeof(num, suffix='', divisor=1000): + def format_sizeof(num, divisor=1000, pre='', prefixes=None): """ Formats a number (greater than unity) with SI Order of Magnitude prefixes. @@ -235,25 +236,30 @@ def format_sizeof(num, suffix='', divisor=1000): ---------- num : float Number ( >= 1) to format. - suffix : str, optional - Post-postfix [default: '']. divisor : float, optional - Divisor between prefixes [default: 1000]. + Divisor between postfixes [default: 1000]. + pre : str, optional + Pre-prefix [default: '']. + prefixes : list, optional + Prefixes (default: [''] + list('kMGTPEZY')). Returns ------- out : str Number with Order of Magnitude SI unit postfix. """ - for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']: + prefixes = prefixes or [''] + list('kMGTPEZY') + p = '' + for unit in prefixes[:-1]: if abs(num) < 999.5: if abs(num) < 99.95: if abs(num) < 9.995: - return '{0:1.2f}'.format(num) + unit + suffix - return '{0:2.1f}'.format(num) + unit + suffix - return '{0:3.0f}'.format(num) + unit + suffix + return '{0:1.2f}'.format(num) + p + unit + return '{0:2.1f}'.format(num) + p + unit + return '{0:3.0f}'.format(num) + p + unit num /= divisor - return '{0:3.1f}Y'.format(num) + suffix + p = pre + return '{0:3.1f}'.format(num) + pre + prefixes[-1] @staticmethod def format_interval(t): @@ -342,6 +348,7 @@ def print_status(s): def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, unit='it', unit_scale=False, rate=None, bar_format=None, postfix=None, unit_divisor=1000, initial=0, colour=None, + unit_pre='', unit_prefixes=None, **extra_kwargs): """ Return a string-based progress bar given some parameters @@ -367,13 +374,6 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, If not set, use unicode (smooth blocks) to fill the meter [default: False]. The fallback is to use ASCII characters " 123456789#". - unit : str, optional - The iteration unit [default: 'it']. - unit_scale : bool or int or float, optional - If 1 or True, the number of iterations will be printed with an - appropriate SI metric prefix (k = 10^3, M = 10^6, etc.) - [default: False]. If any other non-zero number, will scale - `total` and `n`. rate : float, optional Manual override for iteration rate. If [default: None], uses n/elapsed. @@ -396,12 +396,23 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, Note: postfix is usually a string (not a dict) for this method, and will if possible be set to postfix = ', ' + postfix. However other types are supported (#382). - unit_divisor : float, optional - [default: 1000], ignored unless `unit_scale` is True. initial : int or float, optional The initial counter value [default: 0]. colour : str, optional Bar colour (e.g. 'green', '#00ff00'). + unit : str, optional + The iteration unit [default: 'it']. + unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be printed with an + appropriate SI metric prefix (k = 10^3, M = 10^6, etc.) + [default: False]. If any other non-zero number, will scale + `total` and `n`. + unit_divisor : float, optional + [default: 1000], ignored unless `unit_scale` is True. + unit_pre : str, optional + Pre-prefix [default: '']. + unit_prefixes : list, optional + Prefixes (default: [''] + list('kMGTPEZY')). Returns ------- @@ -428,7 +439,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, if rate is None and elapsed: rate = (n - initial) / elapsed inv_rate = 1 / rate if rate else None - format_sizeof = tqdm.format_sizeof + format_sizeof = partial(tqdm.format_sizeof, divisor=unit_divisor, + pre=unit_pre, prefixes=unit_prefixes) rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else '{0:5.2f}'.format(rate)) if rate else '?') + unit + '/s' @@ -438,9 +450,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, rate_fmt = rate_inv_fmt if inv_rate and inv_rate > 1 else rate_noinv_fmt if unit_scale: - n_fmt = format_sizeof(n, divisor=unit_divisor) - total_fmt = format_sizeof(total, divisor=unit_divisor) \ - if total is not None else '?' + n_fmt = format_sizeof(n) + total_fmt = format_sizeof(total) if total is not None else '?' else: n_fmt = str(n) total_fmt = str(total) if total is not None else '?' @@ -475,7 +486,7 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, # slight extension of self.format_dict n=n, n_fmt=n_fmt, total=total, total_fmt=total_fmt, elapsed=elapsed_str, elapsed_s=elapsed, - ncols=ncols, desc=prefix or '', unit=unit, + ncols=ncols, desc=prefix or '', unit=unit, unit_pre=unit_pre, rate=inv_rate if inv_rate and inv_rate > 1 else rate, rate_fmt=rate_fmt, rate_noinv=rate, rate_noinv_fmt=rate_noinv_fmt, rate_inv=inv_rate, @@ -835,7 +846,7 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, unit_scale=False, dynamic_ncols=False, smoothing=0.3, bar_format=None, initial=0, position=None, postfix=None, unit_divisor=1000, write_bytes=None, lock_args=None, - nrows=None, colour=None, + nrows=None, colour=None, unit_pre='', unit_prefixes=None, gui=False, **kwargs): """ Parameters @@ -888,15 +899,6 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, disable : bool, optional Whether to disable the entire progressbar wrapper [default: False]. If set to None, disable on non-TTY. - unit : str, optional - String that will be used to define the unit of each iteration - [default: it]. - unit_scale : bool or int or float, optional - If 1 or True, the number of iterations will be reduced/scaled - automatically and a metric prefix following the - International System of Units standard will be added - (kilo, mega, etc.) [default: False]. If any other non-zero - number, will scale `total` and `n`. dynamic_ncols : bool, optional If set, constantly alters `ncols` and `nrows` to the environment (allowing for window resizes) [default: False]. @@ -928,8 +930,24 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, postfix : dict or *, optional Specify additional stats to display at the end of the bar. Calls `set_postfix(**postfix)` if possible (dict). + unit : str, optional + String that will be used to define the unit of each iteration + [default: it]. + unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be reduced/scaled + automatically and a metric prefix following the + International System of Units standard will be added + (kilo, mega, etc.) [default: False]. If any other non-zero + number, will scale `total` and `n`. unit_divisor : float, optional [default: 1000], ignored unless `unit_scale` is True. + unit_pre : str, optional + Pre-prefix [default: '']. + unit_prefixes : list or str, optional + Prefixes (default: [''] + list('kMGTPEZY')). + Use `"IEEE1541"` or `"bytes"` as a shortcut to override: + unit='B', unit_scale=True, unit_divisor=1024, unit_pre=' ', + unit_prefixes=[''] + [i + 'i' for i in 'KMGTPEZY']. write_bytes : bool, optional If (default: None) and `file` is unspecified, bytes will be written in Python 2. If `True` will also write @@ -1055,9 +1073,19 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, self.dynamic_miniters = dynamic_miniters self.ascii = ascii self.disable = disable - self.unit = unit - self.unit_scale = unit_scale - self.unit_divisor = unit_divisor + if hasattr(unit_prefixes, "upper") and unit_prefixes.upper() in \ + ["BYTES", "IEEE1541"]: + self.unit = 'B' + self.unit_scale = True + self.unit_divisor = 1024 + self.unit_pre = ' ' + self.unit_prefixes = [''] + [i + 'i' for i in 'KMGTPEZY'] + else: + self.unit = unit + self.unit_scale = unit_scale + self.unit_divisor = unit_divisor + self.unit_pre = unit_pre + self.unit_prefixes = unit_prefixes self.initial = initial self.lock_args = lock_args self.gui = gui @@ -1486,7 +1514,8 @@ def format_dict(self): if hasattr(self, 'start_t') else 0, ncols=ncols, nrows=nrows, prefix=self.desc, ascii=self.ascii, unit=self.unit, - unit_scale=self.unit_scale, + unit_scale=self.unit_scale, unit_pre=self.unit_pre, + unit_prefixes=self.unit_prefixes, rate=1 / self.avg_time if self.avg_time else None, bar_format=self.bar_format, postfix=self.postfix, unit_divisor=self.unit_divisor, initial=self.initial, diff --git a/tqdm/tqdm.1 b/tqdm/tqdm.1 index da9e690bb..c7cd77fcc 100644 --- a/tqdm/tqdm.1 +++ b/tqdm/tqdm.1 @@ -124,22 +124,6 @@ If set to None, disable on non\-TTY. .RS .RE .TP -.B \-\-unit=\f[I]unit\f[] -str, optional. -String that will be used to define the unit of each iteration [default: -it]. -.RS -.RE -.TP -.B \-\-unit\-scale=\f[I]unit_scale\f[] -bool or int or float, optional. -If 1 or True, the number of iterations will be reduced/scaled -automatically and a metric prefix following the International System of -Units standard will be added (kilo, mega, etc.) [default: False]. -If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[]. -.RS -.RE -.TP .B \-\-dynamic\-ncols bool, optional. If set, constantly alters \f[C]ncols\f[] and \f[C]nrows\f[] to the @@ -196,12 +180,44 @@ Calls \f[C]set_postfix(**postfix)\f[] if possible (dict). .RS .RE .TP +.B \-\-unit=\f[I]unit\f[] +str, optional. +String that will be used to define the unit of each iteration [default: +it]. +.RS +.RE +.TP +.B \-\-unit\-scale=\f[I]unit_scale\f[] +bool or int or float, optional. +If 1 or True, the number of iterations will be reduced/scaled +automatically and a metric prefix following the International System of +Units standard will be added (kilo, mega, etc.) [default: False]. +If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[]. +.RS +.RE +.TP .B \-\-unit\-divisor=\f[I]unit_divisor\f[] float, optional. [default: 1000], ignored unless \f[C]unit_scale\f[] is True. .RS .RE .TP +.B \-\-unit\-pre=\f[I]unit_pre\f[] +str, optional. +Pre\-prefix [default: \[aq]\[aq]]. +.RS +.RE +.TP +.B \-\-unit\-prefixes=\f[I]unit_prefixes\f[] +list or str, optional. +Prefixes (default: [\[aq]\[aq]] + list(\[aq]kMGTPEZY\[aq])). +Use \f[C]"IEEE1541"\f[] or \f[C]"bytes"\f[] as a shortcut to override: +unit=\[aq]B\[aq], unit_scale=True, unit_divisor=1024, unit_pre=\[aq] +\[aq], unit_prefixes=[\[aq]\[aq]] + [i + \[aq]i\[aq] for i in +\[aq]KMGTPEZY\[aq]]. +.RS +.RE +.TP .B \-\-write\-bytes bool, optional. If (default: None) and \f[C]file\f[] is unspecified, bytes will be @@ -253,8 +269,7 @@ specified. .B \-\-bytes bool, optional. If true, will count bytes, ignore \f[C]delim\f[], and default -\f[C]unit_scale\f[] to True, \f[C]unit_divisor\f[] to 1024, and -\f[C]unit\f[] to \[aq]B\[aq]. +\f[C]unit_prefixes\f[] to \f[C]"IEEE1541"\f[]. .RS .RE .TP