Hello community, here is the log from the commit of package python-tqdm for openSUSE:Factory checked in at 2019-08-27 10:11:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-tqdm (Old) and /work/SRC/openSUSE:Factory/.python-tqdm.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-tqdm" Tue Aug 27 10:11:16 2019 rev:22 rq:725979 version:4.35.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-tqdm/python-tqdm.changes 2019-08-13 13:11:29.701583374 +0200 +++ /work/SRC/openSUSE:Factory/.python-tqdm.new.7948/python-tqdm.changes 2019-08-27 10:11:28.587979169 +0200 @@ -1,0 +2,18 @@ +Sun Aug 25 17:53:16 UTC 2019 - Arun Persaud <[email protected]> + +- update to version 4.35.0: + * add {bar} format specifier (#623 -> #799) + [width][type] + * add tests and documentation + * update performance tests + +- changes from version 4.34.0: + * add leave=None convenience option for leave = position == 0 + * ensure nested completed bars respect leave=True (#230) + * ensure nested bars are cleared before being moved up (#795) + * support both and = syntax for CLI options (#761 -> #774) + * misc documentation updates (#778, #782) + * fix/update tests + * update GitHub docker package deployment + +------------------------------------------------------------------- Old: ---- tqdm-4.33.0.tar.gz New: ---- tqdm-4.35.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-tqdm.spec ++++++ --- /var/tmp/diff_new_pack.GkMkkn/_old 2019-08-27 10:11:30.975979010 +0200 +++ /var/tmp/diff_new_pack.GkMkkn/_new 2019-08-27 10:11:30.979979009 +0200 @@ -28,7 +28,7 @@ %bcond_with test %endif Name: python-tqdm%{suffix} -Version: 4.33.0 +Version: 4.35.0 Release: 0 Summary: An extensible progress meter License: MPL-2.0 AND MIT ++++++ tqdm-4.33.0.tar.gz -> tqdm-4.35.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/Makefile new/tqdm-4.35.0/Makefile --- old/tqdm-4.33.0/Makefile 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/Makefile 2019-08-25 00:56:47.000000000 +0200 @@ -43,8 +43,7 @@ @+make build flake8: - @+flake8 --max-line-length=80 --exclude .asv,.tox,.ipynb_checkpoints,build \ - --ignore=W503,W504 -j 8 --count --statistics --exit-zero . + @+flake8 -j 8 --count --statistics --exit-zero . test: tox --skip-missing-interpreters @@ -55,7 +54,7 @@ testsetup: @make README.rst @make tqdm/tqdm.1 - python setup.py check --restructuredtext --strict + python setup.py check --metadata --restructuredtext --strict python setup.py make none testcoverage: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/PKG-INFO new/tqdm-4.35.0/PKG-INFO --- old/tqdm-4.33.0/PKG-INFO 2019-08-08 18:01:40.000000000 +0200 +++ new/tqdm-4.35.0/PKG-INFO 2019-08-25 00:58:28.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tqdm -Version: 4.33.0 +Version: 4.35.0 Summary: Fast, Extensible Progress Meter Home-page: https://github.com/tqdm/tqdm Maintainer: tqdm developers @@ -251,25 +251,29 @@ - Consoles in general: require support for carriage return (``CR``, ``\r``). - Nested progress bars: - * Consoles in general: require support for moving cursors up to the - previous line. For example, - `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, - `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and - `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also - `here <https://github.com/tqdm/tqdm/issues/208>`__, - `here <https://github.com/tqdm/tqdm/issues/307>`__, and - `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) - lack full support. - * Windows: additionally may require the Python module ``colorama`` - to ensure nested bars stay within their respective lines. + + * Consoles in general: require support for moving cursors up to the + previous line. For example, + `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, + `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and + `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also + `here <https://github.com/tqdm/tqdm/issues/208>`__, + `here <https://github.com/tqdm/tqdm/issues/307>`__, and + `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) + lack full support. + * Windows: additionally may require the Python module ``colorama`` + to ensure nested bars stay within their respective lines. + - Unicode: - * Environments which report that they support unicode will have solid smooth - progressbars. The fallback is an ```ascii``-only bar. - * Windows consoles often only partially support unicode and thus - `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ - (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to - either normal-width unicode characters being incorrectly displayed as - "wide", or some unicode characters not rendering. + + * Environments which report that they support unicode will have solid smooth + progressbars. The fallback is an ```ascii``-only bar. + * Windows consoles often only partially support unicode and thus + `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ + (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to + either normal-width unicode characters being incorrectly displayed as + "wide", or some unicode characters not rendering. + - Wrapping enumerated iterables: use ``enumerate(tqdm(...))`` instead of ``tqdm(enumerate(...))``. The same applies to ``numpy.ndenumerate``. This is because enumerate functions tend to hide the length of iterables. @@ -323,6 +327,7 @@ * leave : bool, optional If [default: True], keeps all traces of the progressbar upon termination of iteration. + If ``None``, will leave only if ``position`` is ``0``. * file : ``io.TextIOWrapper`` or ``io.StringIO``, optional Specifies where to output the progress messages (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()`` @@ -540,9 +545,11 @@ folder; - import the module and run ``help()``; - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__; - - this has an + + * this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar; + - run the |notebook-demo| or |binder-demo|, or - check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__. @@ -607,6 +614,23 @@ 00:01 in total: 40%|000o | 4/10 [00:00<00:00, 9.96it/s] + Note that ``{bar}`` also supports a format specifier ``[width][type]``. + + - ``width`` + + * unspecified (default): automatic to fill ``ncols`` + * ``int >= 0``: fixed width overriding ``ncols`` logic + * ``int < 0``: subtract from the automatic default + + - ``type`` + + * ``a``: ascii (``ascii=True`` override) + * ``u``: unicode (``ascii=False`` override) + * ``b``: blank (``ascii=" "`` override) + + This means a fixed bar with right-justified text may be created by using: + ``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"`` + Nested progress bars ~~~~~~~~~~~~~~~~~~~~ @@ -970,7 +994,7 @@ Developers who have made significant contributions, ranked by *LoC* (surviving lines of code, - `git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|enc)$'``), + `git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC``), are: ==================== ================================================== ==== ================================ @@ -1051,7 +1075,7 @@ .. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif :target: https://www.openhub.net/p/tqdm?ref=Thin+badge .. |awesome-python| image:: https://awesome.re/mentioned-badge.svg - :target: https://github.com/vinta/awesome-python) + :target: https://github.com/vinta/awesome-python .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE .. |DOI| image:: https://img.shields.io/badge/DOI-10.21105/joss.01277-green.svg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/README.rst new/tqdm-4.35.0/README.rst --- old/tqdm-4.33.0/README.rst 2019-08-08 18:01:38.000000000 +0200 +++ new/tqdm-4.35.0/README.rst 2019-08-25 00:58:26.000000000 +0200 @@ -243,25 +243,29 @@ - Consoles in general: require support for carriage return (``CR``, ``\r``). - Nested progress bars: - * Consoles in general: require support for moving cursors up to the - previous line. For example, - `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, - `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and - `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also - `here <https://github.com/tqdm/tqdm/issues/208>`__, - `here <https://github.com/tqdm/tqdm/issues/307>`__, and - `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) - lack full support. - * Windows: additionally may require the Python module ``colorama`` - to ensure nested bars stay within their respective lines. + + * Consoles in general: require support for moving cursors up to the + previous line. For example, + `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, + `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and + `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also + `here <https://github.com/tqdm/tqdm/issues/208>`__, + `here <https://github.com/tqdm/tqdm/issues/307>`__, and + `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) + lack full support. + * Windows: additionally may require the Python module ``colorama`` + to ensure nested bars stay within their respective lines. + - Unicode: - * Environments which report that they support unicode will have solid smooth - progressbars. The fallback is an ```ascii``-only bar. - * Windows consoles often only partially support unicode and thus - `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ - (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to - either normal-width unicode characters being incorrectly displayed as - "wide", or some unicode characters not rendering. + + * Environments which report that they support unicode will have solid smooth + progressbars. The fallback is an ```ascii``-only bar. + * Windows consoles often only partially support unicode and thus + `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ + (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to + either normal-width unicode characters being incorrectly displayed as + "wide", or some unicode characters not rendering. + - Wrapping enumerated iterables: use ``enumerate(tqdm(...))`` instead of ``tqdm(enumerate(...))``. The same applies to ``numpy.ndenumerate``. This is because enumerate functions tend to hide the length of iterables. @@ -315,6 +319,7 @@ * leave : bool, optional If [default: True], keeps all traces of the progressbar upon termination of iteration. + If ``None``, will leave only if ``position`` is ``0``. * file : ``io.TextIOWrapper`` or ``io.StringIO``, optional Specifies where to output the progress messages (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()`` @@ -532,9 +537,11 @@ folder; - import the module and run ``help()``; - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__; - - this has an + + * this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar; + - run the |notebook-demo| or |binder-demo|, or - check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__. @@ -599,6 +606,23 @@ 00:01 in total: 40%|000o | 4/10 [00:00<00:00, 9.96it/s] +Note that ``{bar}`` also supports a format specifier ``[width][type]``. + +- ``width`` + + * unspecified (default): automatic to fill ``ncols`` + * ``int >= 0``: fixed width overriding ``ncols`` logic + * ``int < 0``: subtract from the automatic default + +- ``type`` + + * ``a``: ascii (``ascii=True`` override) + * ``u``: unicode (``ascii=False`` override) + * ``b``: blank (``ascii=" "`` override) + +This means a fixed bar with right-justified text may be created by using: +``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"`` + Nested progress bars ~~~~~~~~~~~~~~~~~~~~ @@ -962,7 +986,7 @@ Developers who have made significant contributions, ranked by *LoC* (surviving lines of code, -`git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|enc)$'``), +`git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC``), are: ==================== ================================================== ==== ================================ @@ -1043,7 +1067,7 @@ .. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif :target: https://www.openhub.net/p/tqdm?ref=Thin+badge .. |awesome-python| image:: https://awesome.re/mentioned-badge.svg - :target: https://github.com/vinta/awesome-python) + :target: https://github.com/vinta/awesome-python .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE .. |DOI| image:: https://img.shields.io/badge/DOI-10.21105/joss.01277-green.svg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/setup.cfg new/tqdm-4.35.0/setup.cfg --- old/tqdm-4.33.0/setup.cfg 2019-08-08 18:01:40.000000000 +0200 +++ new/tqdm-4.35.0/setup.cfg 2019-08-25 00:58:28.000000000 +0200 @@ -1,6 +1,11 @@ [bdist_wheel] universal = 1 +[flake8] +ignore = W503,W504 +max_line_length = 80 +exclude = .asv,.tox,.ipynb_checkpoints,build,dist,.git,__pycache__ + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tox.ini new/tqdm-4.35.0/tox.ini --- old/tqdm-4.33.0/tox.ini 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tox.ini 2019-08-25 00:56:47.000000000 +0200 @@ -77,8 +77,7 @@ [testenv:flake8] deps = flake8 commands = - flake8 --max-line-length=80 --exclude .asv,.tox,.ipynb_checkpoints,build \ - --ignore=W503,W504 -j 8 --count --statistics --exit-zero . + flake8 -j 8 --count --statistics --exit-zero . [testenv:setup.py] deps = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/_main.py new/tqdm-4.35.0/tqdm/_main.py --- old/tqdm-4.33.0/tqdm/_main.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/_main.py 2019-08-25 00:56:47.000000000 +0200 @@ -89,7 +89,7 @@ # ((opt, type), ... ) RE_OPTS = re.compile(r'\n {8}(\S+)\s{2,}:\s*([^,]+)') # better split method assuming no positional args -RE_SHLEX = re.compile(r'\s*(?<!\S)--?([^\s=]+)(?:\s*|=|$)') +RE_SHLEX = re.compile(r'\s*(?<!\S)--?([^\s=]+)(\s+|=|$)') # TODO: add custom support for some of the following? UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file') @@ -128,7 +128,12 @@ try: log = argv.index('--log') except ValueError: - logLevel = 'INFO' + for i in argv: + if i.startswith('--log='): + logLevel = i[len('--log='):] + break + else: + logLevel = 'INFO' else: # argv.pop(log) # logLevel = argv.pop(log) @@ -172,7 +177,7 @@ sys.exit(0) argv = RE_SHLEX.split(' '.join(["tqdm"] + argv)) - opts = dict(zip(argv[1::2], argv[2::2])) + opts = dict(zip(argv[1::3], argv[3::3])) log.debug(opts) opts.pop('log', True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/_tqdm.py new/tqdm-4.35.0/tqdm/_tqdm.py --- old/tqdm-4.33.0/tqdm/_tqdm.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/_tqdm.py 2019-08-25 00:56:47.000000000 +0200 @@ -13,7 +13,7 @@ # compatibility functions and utilities from ._utils import _supports_unicode, _environ_cols_wrapper, _range, _unich, \ _term_move_up, _unicode, WeakSet, _basestring, _OrderedDict, \ - Comparable, RE_ANSI, _is_ascii, SimpleTextIOWrapper + Comparable, RE_ANSI, _is_ascii, SimpleTextIOWrapper, FormatReplace from ._monitor import TMonitor # native libraries import sys @@ -125,8 +125,62 @@ # context and does not allow the user to use 'spawn' or 'forkserver' methods. TqdmDefaultWriteLock.create_th_lock() -ASCII_FMT = " 123456789#" -UTF_FMT = u" " + u''.join(map(_unich, range(0x258F, 0x2587, -1))) + +class Bar(object): + """ + `str.format`-able bar with format specifiers: `[width][type]` + + - `width` + + unspecified (default): use `self.default_len` + + `int >= 0`: overrides `self.default_len` + + `int < 0`: subtract from `self.default_len` + - `type` + + `a`: ascii (`charset=self.ASCII` override) + + `u`: unicode (`charset=self.UTF` override) + + `b`: blank (`charset=" "` override) + """ + ASCII = " 123456789#" + UTF = u" " + u''.join(map(_unich, range(0x258F, 0x2587, -1))) + BLANK = " " + + def __init__(self, frac, default_len=10, charset=UTF): + assert 0 <= frac <= 1 + assert default_len > 0 + self.frac = frac + self.default_len = default_len + self.charset = charset + + def __format__(self, format_spec): + if format_spec: + _type = format_spec[-1].lower() + try: + charset = dict(a=self.ASCII, u=self.UTF, b=self.BLANK)[_type] + except KeyError: + charset = self.charset + else: + format_spec = format_spec[:-1] + if format_spec: + N_BARS = int(format_spec) + if N_BARS < 0: + N_BARS += self.default_len + else: + N_BARS = self.default_len + else: + charset = self.charset + N_BARS = self.default_len + + nsyms = len(charset) - 1 + bar_length, frac_bar_length = divmod( + int(self.frac * N_BARS * nsyms), nsyms) + + bar = charset[-1] * bar_length + frac_bar = charset[frac_bar_length] + + # whitespace padding + if bar_length < N_BARS: + return bar + frac_bar + \ + charset[0] * (N_BARS - bar_length - 1) + return bar + charset[0] * (N_BARS - bar_length) class tqdm(Comparable): @@ -270,10 +324,9 @@ Number of seconds passed since start. ncols : int, optional The width of the entire output message. If specified, - dynamically resizes the progress meter to stay within this bound - [default: None]. The fallback meter width is 10 for the progress - bar + no limit for the iterations counter and statistics. If 0, - will not print any meter (only stats). + dynamically resizes `{bar}` to stay within this bound + [default: None]. If `0`, will not print any bar (only stats). + The fallback is `{bar:10}`. prefix : str, optional Prefix message (included in total width) [default: '']. Use as {desc} in bar_format string. @@ -399,53 +452,30 @@ if ncols == 0: return l_bar[:-1] + r_bar[1:] + format_dict.update(l_bar=l_bar) if bar_format: - format_dict.update(l_bar=l_bar, percentage=percentage) - # , bar=full_bar # replaced by procedure below + format_dict.update(percentage=percentage) # auto-remove colon for empty `desc` if not prefix: bar_format = bar_format.replace("{desc}: ", '') - - # Interpolate supplied bar format with the dict - if '{bar}' in bar_format: - # Format left/right sides of the bar, and format the bar - # later in the remaining space (avoid breaking display) - l_bar_user, r_bar_user = bar_format.split('{bar}') - l_bar = l_bar_user.format(**format_dict) - r_bar = r_bar_user.format(**format_dict) - else: - # Else no progress bar, we can just format and return - return bar_format.format(**format_dict) - - # Formatting progress bar space available for bar's display - if ncols: - N_BARS = max(1, ncols - len(RE_ANSI.sub('', l_bar + r_bar))) else: - N_BARS = 10 + bar_format = "{l_bar}{bar}{r_bar}" - # format bar depending on availability of unicode/ascii chars - if ascii is True: - ascii = ASCII_FMT - elif ascii is False: - ascii = UTF_FMT - nsyms = len(ascii) - 1 - bar_length, frac_bar_length = divmod( - int(frac * N_BARS * nsyms), nsyms) - - bar = ascii[-1] * bar_length - frac_bar = ascii[frac_bar_length] - - # whitespace padding - if bar_length < N_BARS: - full_bar = bar + frac_bar + \ - ascii[0] * (N_BARS - bar_length - 1) - else: - full_bar = bar + \ - ascii[0] * (N_BARS - bar_length) + full_bar = FormatReplace() + nobar = bar_format.format(bar=full_bar, **format_dict) + if not full_bar.format_called: + # no {bar}, we can just format and return + return nobar - # Piece together the bar parts - return l_bar + full_bar + r_bar + # Formatting progress bar space available for bar's display + full_bar = Bar( + frac, + max(1, ncols - len(RE_ANSI.sub('', nobar))) if ncols else 10, + charset=Bar.ASCII if ascii is True else ascii or Bar.UTF) + if not _is_ascii(full_bar.charset) and _is_ascii(bar_format): + bar_format = _unicode(bar_format) + return bar_format.format(bar=full_bar, **format_dict) elif bar_format: # user-specified bar_format but no total @@ -503,6 +533,7 @@ for inst in cls._instances: # negative `pos` means fixed if hasattr(inst, "pos") and inst.pos > abs(instance.pos): + inst.clear(nolock=True) inst.pos -= 1 # TODO: check this doesn't overwrite another fixed bar # Kill monitor if no instances are left @@ -743,6 +774,7 @@ leave : bool, optional If [default: True], keeps all traces of the progressbar upon termination of iteration. + If `None`, will leave only if `position` is `0`. file : `io.TextIOWrapper` or `io.StringIO`, optional Specifies where to output the progress messages (default: sys.stderr). Uses `file.write(str)` and `file.flush()` @@ -881,14 +913,10 @@ dynamic_ncols = _environ_cols_wrapper() if dynamic_ncols: ncols = dynamic_ncols(file) - # elif ncols is not None: - # ncols = 79 else: _dynamic_ncols = _environ_cols_wrapper() if _dynamic_ncols: ncols = _dynamic_ncols(file) - # else: - # ncols = 79 if miniters is None: miniters = 0 @@ -1188,16 +1216,14 @@ return raise # pragma: no cover + leave = pos == 0 if self.leave is None else self.leave + with self._lock: - if self.leave: - if self.last_print_n < self.n: - # stats for overall rate (no weighted average) - self.avg_time = None - self.display(pos=pos) - if not max([abs(getattr(i, "pos", 0)) - for i in self._instances] + [pos]): - # only if not nested (#477) - fp_write('\n') + if leave: + # stats for overall rate (no weighted average) + self.avg_time = None + self.display(pos=0) + fp_write('\n') else: self.display(msg='', pos=pos) if not pos: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/_utils.py new/tqdm-4.35.0/tqdm/_utils.py --- old/tqdm-4.33.0/tqdm/_utils.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/_utils.py 2019-08-25 00:56:47.000000000 +0200 @@ -121,6 +121,21 @@ return d +class FormatReplace(object): + """ + >>> a = FormatReplace('something') + >>> "{:5d}".format(a) + 'something' + """ + def __init__(self, replace=''): + self.replace = replace + self.format_called = 0 + + def __format__(self, _): + self.format_called += 1 + return self.replace + + class Comparable(object): """Assumes child has self._comparable attr/@property""" def __lt__(self, other): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/_version.py new/tqdm-4.35.0/tqdm/_version.py --- old/tqdm-4.33.0/tqdm/_version.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/_version.py 2019-08-25 00:56:47.000000000 +0200 @@ -5,7 +5,7 @@ __all__ = ["__version__"] # major, minor, patch, -extra -version_info = 4, 33, 0 +version_info = 4, 35, 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.33.0/tqdm/tests/tests_main.py new/tqdm-4.35.0/tqdm/tests/tests_main.py --- old/tqdm-4.33.0/tqdm/tests/tests_main.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/tests/tests_main.py 2019-08-25 00:56:47.000000000 +0200 @@ -61,7 +61,7 @@ IN_DATA = '\0'.join(IN_DATA_LIST) sys.stdin.write(IN_DATA) sys.stdin.seek(0) - sys.argv = ['', '--ascii', '--bytes', '--unit_scale', 'False'] + sys.argv = ['', '--ascii', '--bytes=True', '--unit_scale', 'False'] with closing(UnicodeIO()) as fp: main(fp=fp) assert str(len(IN_DATA)) in fp.getvalue() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/tests/tests_perf.py new/tqdm-4.35.0/tqdm/tests/tests_perf.py --- old/tqdm-4.33.0/tqdm/tests/tests_perf.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/tests/tests_perf.py 2019-08-25 00:56:47.000000000 +0200 @@ -159,6 +159,18 @@ return update_and_print +def assert_performance(thresh, name_left, time_left, name_right, time_right): + """raises if time_left > thresh * time_right""" + if time_left > thresh * time_right: + raise ValueError( + ('{name[0]}: {time[0]:f}, ' + '{name[1]}: {time[0]:f}, ' + 'ratio {ratio:f} > {thresh:f}').format( + name=(name_left, name_right), + time=(time_left, time_right), + ratio=time_left / time_right, thresh=thresh)) + + @with_setup(pretest, posttest) @retry_on_except() def test_iter_overhead(): @@ -180,10 +192,7 @@ a += i our_file.write(a) - # Compute relative overhead of tqdm against native range() - if time_tqdm() > 9 * time_bench(): - raise AssertionError('trange(%g): %f, range(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance(6, 'trange', time_tqdm(), 'range', time_bench()) @with_setup(pretest, posttest) @@ -207,10 +216,7 @@ a += i our_file.write(a) - # Compute relative overhead of tqdm against native range() - if time_tqdm() > 10 * time_bench(): - raise AssertionError('tqdm(%g): %f, range(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance(6, 'tqdm', time_tqdm(), 'range', time_bench()) @with_setup(pretest, posttest) @@ -235,12 +241,7 @@ a += i our_file.write(("%i" % a) * 40) - # Compute relative overhead of tqdm against native range() - try: - assert time_tqdm() < 60 * time_bench() - except AssertionError: - raise AssertionError('trange(%g): %f, range(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance(85, 'trange', time_tqdm(), 'range', time_bench()) @with_setup(pretest, posttest) @@ -265,12 +266,7 @@ a += i our_file.write(("%i" % a) * 40) - # Compute relative overhead of tqdm against native range() - try: - assert time_tqdm() < 100 * time_bench() - except AssertionError: - raise AssertionError('tqdm(%g): %f, range(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance(85, 'tqdm', time_tqdm(), 'range', time_bench()) @with_setup(pretest, posttest) @@ -296,12 +292,8 @@ for i in s: a += i - # Compute relative overhead of tqdm against native range() - try: - assert time_tqdm() < 3 * time_bench() - except AssertionError: - raise AssertionError('trange(%g): %f, simple_progress(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance( + 5, 'trange', time_tqdm(), 'simple_progress', time_bench()) @with_setup(pretest, posttest) @@ -321,16 +313,13 @@ t.update(10) simplebar_update = simple_progress( - total=total, file=our_file, leave=True, miniters=1, mininterval=0) + total=total * 10, file=our_file, leave=True, miniters=1, + mininterval=0) a = 0 with relative_timer() as time_bench: for i in _range(total): a += i simplebar_update(10) - # Compute relative overhead of tqdm against native range() - try: - assert time_tqdm() < 3 * time_bench() - except AssertionError: - raise AssertionError('tqdm(%g): %f, simple_progress(%g): %f' % - (total, time_tqdm(), total, time_bench())) + assert_performance( + 5, 'tqdm', time_tqdm(), 'simple_progress', time_bench()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/tests/tests_tqdm.py new/tqdm-4.35.0/tqdm/tests/tests_tqdm.py --- old/tqdm-4.33.0/tqdm/tests/tests_tqdm.py 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/tests/tests_tqdm.py 2019-08-25 00:56:47.000000000 +0200 @@ -13,6 +13,7 @@ from tqdm import tqdm from tqdm import trange from tqdm import TqdmDeprecationWarning +from tqdm._tqdm import Bar try: from StringIO import StringIO @@ -68,20 +69,26 @@ Return differences between two bar output lists. To be used with `RE_pos` """ - ln = len(res_list) - if ln < len(expected_list): - res = [(None, e) for e in expected_list[ln:]] - elif ln > len(expected_list): - res = [(r, None) for r in res_list[ln:]] res = [(r, e) for r, e in zip(res_list, expected_list) for pos in [len(e) - len(e.lstrip('\n'))] # bar position + if r != e # simple comparison if not r.startswith(e) # start matches - or not (r.endswith('\x1b[A' * pos) # move up at end - or r == '\n') # final bar - or r[(-1 - pos) * len('\x1b[A'):] == '\x1b[A'] # extra move up - if res and raise_nonempty: + or not ( + # move up at end (maybe less due to closing bars) + any(r.endswith(end + i * '\x1b[A') for i in range(pos + 1) + for end in [ + ']', # bar + ' ']) # cleared + or '100%' in r # completed bar + or r == '\n') # final bar + or r[(-1 - pos) * len('\x1b[A'):] == '\x1b[A'] # too many moves up + if raise_nonempty and (res or len(res_list) != len(expected_list)): + if len(res_list) < len(expected_list): + res.extend([(None, e) for e in expected_list[len(res_list):]]) + elif len(res_list) > len(expected_list): + res.extend([(r, None) for r in res_list[len(expected_list):]]) raise AssertionError( - "Got => Expected\n" + '\n'.join('"%r" => "%r"' % i for i in res)) + "Got => Expected\n" + '\n'.join('%r => %r' % i for i in res)) return res @@ -323,6 +330,15 @@ unit_scale=True) +def test_bar_formatspec(): + """Test Bar.__format__ spec""" + assert "{0:5a}".format(Bar(0.3)) == "#5 " + assert "{0:2}".format(Bar(0.5, charset=" .oO0")) == "0 " + assert "{0:2a}".format(Bar(0.5, charset=" .oO0")) == "# " + assert "{0:-6a}".format(Bar(0.5, 10)) == '## ' + assert "{0:2b}".format(Bar(0.5, 10)) == ' ' + + @with_setup(pretest, posttest) def test_all_defaults(): """Test default kwargs""" @@ -932,13 +948,17 @@ progressbar.update(3) res = our_file.getvalue() assert '| 3/3 ' in res # Should be blank + assert '\n' not in res # close() called assert len(tqdm._instances) == 0 - exres = res + '\n' - if exres != our_file.getvalue(): - raise AssertionError("\nExpected:\n{0}\nGot:{1}\n".format( - exres, our_file.getvalue())) + exres = res.rsplit(', ', 1)[0] + res = our_file.getvalue() + assert res[-1] == '\n' + if not res.startswith(exres): + raise AssertionError( + "\n<<< Expected:\n{0}\n>>> Got:\n{1}\n===".format( + exres + ', ...it/s]\n', our_file.getvalue())) # Closing after the output stream has closed with closing(StringIO()) as our_file: @@ -1176,21 +1196,28 @@ '\n\n\rpos2 bar: 0%', '\n\n\rpos2 bar: 50%', '\n\n\rpos2 bar: 100%', - '\n\rpos1 bar: 50%', + '\rpos2 bar: 100%', + '\n\n\rpos1 bar: 50%', '\n\n\rpos2 bar: 0%', '\n\n\rpos2 bar: 50%', '\n\n\rpos2 bar: 100%', - '\n\rpos1 bar: 100%', - '\rpos0 bar: 50%', + '\rpos2 bar: 100%', + '\n\n\rpos1 bar: 100%', + '\rpos1 bar: 100%', + '\n\rpos0 bar: 50%', '\n\rpos1 bar: 0%', '\n\n\rpos2 bar: 0%', '\n\n\rpos2 bar: 50%', '\n\n\rpos2 bar: 100%', - '\n\rpos1 bar: 50%', + '\rpos2 bar: 100%', + '\n\n\rpos1 bar: 50%', '\n\n\rpos2 bar: 0%', '\n\n\rpos2 bar: 50%', '\n\n\rpos2 bar: 100%', - '\n\rpos1 bar: 100%', + '\rpos2 bar: 100%', + '\n\n\rpos1 bar: 100%', + '\rpos1 bar: 100%', + '\n\rpos0 bar: 100%', '\rpos0 bar: 100%', '\n'] pos_line_diff(res, exres) @@ -1243,7 +1270,10 @@ exres = ['\rpos0 bar: 0%', '\n\rpos1 bar: 0%', '\n\n\rpos2 bar: 0%', - '\n\n\rpos3 bar: 0%', + '\n\n\r ', + '\r\x1b[A\x1b[A', + '\rpos1 bar: 0%', + '\n\n\n\rpos3 bar: 0%', '\rpos0 bar: 10%', '\n\rpos2 bar: 10%', '\n\n\rpos3 bar: 10%'] @@ -1489,10 +1519,10 @@ assert before_err == '\rpos0 bar: 0%|\rpos0 bar: 10%|' assert before_out == '' after_err_res = [m[0] for m in RE_pos.findall(after_err)] - exres = [u'\rpos0 bar: 0%', - u'\rpos0 bar: 10%', - u'\r ', - u'\r\rpos0 bar: 10%'] + exres = ['\rpos0 bar: 0%|', + '\rpos0 bar: 10%|', + '\r ', + '\r\rpos0 bar: 10%|'] pos_line_diff(after_err_res, exres) assert after_out == s + '\n' # Restore stdout and stderr diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm/tqdm.1 new/tqdm-4.35.0/tqdm/tqdm.1 --- old/tqdm-4.33.0/tqdm/tqdm.1 2019-08-08 17:59:56.000000000 +0200 +++ new/tqdm-4.35.0/tqdm/tqdm.1 2019-08-25 00:56:47.000000000 +0200 @@ -67,6 +67,7 @@ bool, optional. If [default: True], keeps all traces of the progressbar upon termination of iteration. +If \f[C]None\f[], will leave only if \f[C]position\f[] is \f[C]0\f[]. .RS .RE .TP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tqdm-4.33.0/tqdm.egg-info/PKG-INFO new/tqdm-4.35.0/tqdm.egg-info/PKG-INFO --- old/tqdm-4.33.0/tqdm.egg-info/PKG-INFO 2019-08-08 18:01:40.000000000 +0200 +++ new/tqdm-4.35.0/tqdm.egg-info/PKG-INFO 2019-08-25 00:58:28.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tqdm -Version: 4.33.0 +Version: 4.35.0 Summary: Fast, Extensible Progress Meter Home-page: https://github.com/tqdm/tqdm Maintainer: tqdm developers @@ -251,25 +251,29 @@ - Consoles in general: require support for carriage return (``CR``, ``\r``). - Nested progress bars: - * Consoles in general: require support for moving cursors up to the - previous line. For example, - `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, - `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and - `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also - `here <https://github.com/tqdm/tqdm/issues/208>`__, - `here <https://github.com/tqdm/tqdm/issues/307>`__, and - `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) - lack full support. - * Windows: additionally may require the Python module ``colorama`` - to ensure nested bars stay within their respective lines. + + * Consoles in general: require support for moving cursors up to the + previous line. For example, + `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, + `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and + `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also + `here <https://github.com/tqdm/tqdm/issues/208>`__, + `here <https://github.com/tqdm/tqdm/issues/307>`__, and + `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) + lack full support. + * Windows: additionally may require the Python module ``colorama`` + to ensure nested bars stay within their respective lines. + - Unicode: - * Environments which report that they support unicode will have solid smooth - progressbars. The fallback is an ```ascii``-only bar. - * Windows consoles often only partially support unicode and thus - `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ - (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to - either normal-width unicode characters being incorrectly displayed as - "wide", or some unicode characters not rendering. + + * Environments which report that they support unicode will have solid smooth + progressbars. The fallback is an ```ascii``-only bar. + * Windows consoles often only partially support unicode and thus + `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ + (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to + either normal-width unicode characters being incorrectly displayed as + "wide", or some unicode characters not rendering. + - Wrapping enumerated iterables: use ``enumerate(tqdm(...))`` instead of ``tqdm(enumerate(...))``. The same applies to ``numpy.ndenumerate``. This is because enumerate functions tend to hide the length of iterables. @@ -323,6 +327,7 @@ * leave : bool, optional If [default: True], keeps all traces of the progressbar upon termination of iteration. + If ``None``, will leave only if ``position`` is ``0``. * file : ``io.TextIOWrapper`` or ``io.StringIO``, optional Specifies where to output the progress messages (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()`` @@ -540,9 +545,11 @@ folder; - import the module and run ``help()``; - consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__; - - this has an + + * this has an `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ on how to make a **great** progressbar; + - run the |notebook-demo| or |binder-demo|, or - check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__. @@ -607,6 +614,23 @@ 00:01 in total: 40%|000o | 4/10 [00:00<00:00, 9.96it/s] + Note that ``{bar}`` also supports a format specifier ``[width][type]``. + + - ``width`` + + * unspecified (default): automatic to fill ``ncols`` + * ``int >= 0``: fixed width overriding ``ncols`` logic + * ``int < 0``: subtract from the automatic default + + - ``type`` + + * ``a``: ascii (``ascii=True`` override) + * ``u``: unicode (``ascii=False`` override) + * ``b``: blank (``ascii=" "`` override) + + This means a fixed bar with right-justified text may be created by using: + ``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"`` + Nested progress bars ~~~~~~~~~~~~~~~~~~~~ @@ -970,7 +994,7 @@ Developers who have made significant contributions, ranked by *LoC* (surviving lines of code, - `git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|enc)$'``), + `git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC``), are: ==================== ================================================== ==== ================================ @@ -1051,7 +1075,7 @@ .. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif :target: https://www.openhub.net/p/tqdm?ref=Thin+badge .. |awesome-python| image:: https://awesome.re/mentioned-badge.svg - :target: https://github.com/vinta/awesome-python) + :target: https://github.com/vinta/awesome-python .. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE .. |DOI| image:: https://img.shields.io/badge/DOI-10.21105/joss.01277-green.svg
