Hello community,

here is the log from the commit of package python-tqdm for openSUSE:Factory 
checked in at 2018-07-14 20:26:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tqdm (Old)
 and      /work/SRC/openSUSE:Factory/.python-tqdm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tqdm"

Sat Jul 14 20:26:04 2018 rev:10 rq:622794 version:4.23.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tqdm/python-tqdm.changes  2018-05-18 
14:28:00.822126834 +0200
+++ /work/SRC/openSUSE:Factory/.python-tqdm.new/python-tqdm.changes     
2018-07-14 20:27:45.908578167 +0200
@@ -1,0 +2,14 @@
+Sat Jul 14 02:18:53 UTC 2018 - [email protected]
+
+- specfile:
+  * removed patch support_pandas_23_groupby.patch (included upstream)
+  * always run tests
+
+- update to version 4.23.4:
+  * Support pandas 0.23.0 core.groupby module layout (#555 -> #554)
+  * Add python_requires to help pip (#557)
+  * minor maintenance updates
+    + CI updates: drop travis py33 due to tox (tox-dev/tox#648)
+    + minor code tidy
+
+-------------------------------------------------------------------

Old:
----
  support_pandas_23_groupby.patch
  tqdm-4.23.3.tar.gz

New:
----
  tqdm-4.23.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tqdm.spec ++++++
--- /var/tmp/diff_new_pack.kbcjba/_old  2018-07-14 20:27:46.652580076 +0200
+++ /var/tmp/diff_new_pack.kbcjba/_new  2018-07-14 20:27:46.652580076 +0200
@@ -15,35 +15,30 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
+
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%bcond_without  test
 %define         oldpython python
 Name:           python-tqdm
-Version:        4.23.3
+Version:        4.23.4
 Release:        0
 Summary:        An extensible progress meter
 License:        MPL-2.0 AND MIT
 Group:          Development/Languages/Python
-Url:            https://github.com/tqdm/tqdm
+URL:            https://github.com/tqdm/tqdm
 Source:         
https://files.pythonhosted.org/packages/source/t/tqdm/tqdm-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM support_pandas_23_groupby.patch 
https://github.com/tqdm/tqdm/pull/554
-Patch0:         support_pandas_23_groupby.patch
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module rpm-macros}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
+Requires(post): update-alternatives
+Requires(postun): update-alternatives
+BuildArch:      noarch
 # SECTION test requirements
-%if %{with test}
 BuildRequires:  %{python_module nose}
 BuildRequires:  %{python_module numpy}
 BuildRequires:  %{python_module pandas}
-%endif
 # /SECTION
-Requires(post): update-alternatives
-Requires(postun): update-alternatives
-BuildArch:      noarch
-
 %python_subpackages
 
 %description
@@ -54,7 +49,6 @@
 
 %prep
 %setup -q -n tqdm-%{version}
-%patch0 -p1
 # fix installation directory for man pages
 sed -i 's#man/man1#share/man/man1#' setup.py
 
@@ -73,15 +67,12 @@
 %postun
 %python_uninstall_alternative tqdm
 
-%if %{with test}
 %check
 %{python_expand export PATH="$PATH:%{buildroot}%{_bindir}"
 nosetests-%{$python_bin_suffix} --ignore-files="tests_perf\.py" 
--ignore-files="tests_synchronisation\.py" tqdm/
 }
-%endif
 
 %files %{python_files}
-%defattr(-,root,root,-)
 %doc README.rst logo.png
 %doc examples/
 %license LICENCE

++++++ tqdm-4.23.3.tar.gz -> tqdm-4.23.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/Makefile new/tqdm-4.23.4/Makefile
--- old/tqdm-4.23.3/Makefile    2018-05-02 18:43:34.000000000 +0200
+++ new/tqdm-4.23.4/Makefile    2018-05-14 01:34:20.000000000 +0200
@@ -99,7 +99,7 @@
 prebuildclean:
        @+python -c "import shutil; shutil.rmtree('build', True)"
        @+python -c "import shutil; shutil.rmtree('dist', True)"
-       @#+python -c "import shutil; shutil.rmtree('tqdm.egg-info', True)"
+       @+python -c "import shutil; shutil.rmtree('tqdm.egg-info', True)"
 coverclean:
        @+python -c "import os; os.remove('.coverage') if 
os.path.exists('.coverage') else None"
        @+python -c "import shutil; shutil.rmtree('tqdm/__pycache__', True)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/PKG-INFO new/tqdm-4.23.4/PKG-INFO
--- old/tqdm-4.23.3/PKG-INFO    2018-05-08 15:50:02.000000000 +0200
+++ new/tqdm-4.23.4/PKG-INFO    2018-05-22 21:06:50.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: tqdm
-Version: 4.23.3
+Version: 4.23.4
 Summary: Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Author: Noam Yorav-Raphael
@@ -928,3 +928,4 @@
 Classifier: Topic :: System :: Shells
 Classifier: Topic :: Terminals
 Classifier: Topic :: Utilities
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/examples/progressbar/__init__.py 
new/tqdm-4.23.4/examples/progressbar/__init__.py
--- old/tqdm-4.23.3/examples/progressbar/__init__.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/tqdm-4.23.4/examples/progressbar/__init__.py    2015-12-28 
23:16:15.000000000 +0100
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# progressbar  - Text progress bar library for Python.
+# Copyright (c) 2005 Nilton Volpato
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+"""Text progress bar library for Python.
+
+A text progress bar is typically used to display the progress of a long
+running operation, providing a visual cue that processing is underway.
+
+The ProgressBar class manages the current progress, and the format of the line
+is given by a number of widgets. A widget is an object that may display
+differently depending on the state of the progress bar. There are three types
+of widgets:
+ - a string, which always shows itself
+
+ - a ProgressBarWidget, which may return a different value every time its
+   update method is called
+
+ - a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it
+   expands to fill the remaining width of the line.
+
+The progressbar module is very easy to use, yet very powerful. It will also
+automatically enable features like auto-resizing when the system supports it.
+"""
+
+__author__ = 'Nilton Volpato'
+__author_email__ = 'first-name dot last-name @ gmail.com'
+__date__ = '2011-05-14'
+__version__ = '2.3'
+
+from compat import *
+from widgets import *
+from progressbar import *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/examples/progressbar/compat.py 
new/tqdm-4.23.4/examples/progressbar/compat.py
--- old/tqdm-4.23.3/examples/progressbar/compat.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/tqdm-4.23.4/examples/progressbar/compat.py      2015-12-28 
23:16:15.000000000 +0100
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# progressbar  - Text progress bar library for Python.
+# Copyright (c) 2005 Nilton Volpato
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+"""Compatibility methods and classes for the progressbar module."""
+
+
+# Python 3.x (and backports) use a modified iterator syntax
+# This will allow 2.x to behave with 3.x iterators
+try:
+  next
+except NameError:
+    def next(iter):
+        try:
+            # Try new style iterators
+            return iter.__next__()
+        except AttributeError:
+            # Fallback in case of a "native" iterator
+            return iter.next()
+
+
+# Python < 2.5 does not have "any"
+try:
+  any
+except NameError:
+   def any(iterator):
+      for item in iterator:
+         if item: return True
+      return False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/examples/progressbar/progressbar.py 
new/tqdm-4.23.4/examples/progressbar/progressbar.py
--- old/tqdm-4.23.3/examples/progressbar/progressbar.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/tqdm-4.23.4/examples/progressbar/progressbar.py 2015-12-28 
23:16:15.000000000 +0100
@@ -0,0 +1,306 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# progressbar  - Text progress bar library for Python.
+# Copyright (c) 2005 Nilton Volpato
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+"""Main ProgressBar class."""
+
+from __future__ import division
+
+import math
+import os
+import signal
+import sys
+import time
+
+try:
+    from fcntl import ioctl
+    from array import array
+    import termios
+except ImportError:
+    pass
+
+from compat import *  # for: any, next
+import widgets
+
+
+class UnknownLength: pass
+
+
+class ProgressBar(object):
+    """The ProgressBar class which updates and prints the bar.
+
+    A common way of using it is like:
+    >>> pbar = ProgressBar().start()
+    >>> for i in range(100):
+    ...    # do something
+    ...    pbar.update(i+1)
+    ...
+    >>> pbar.finish()
+
+    You can also use a ProgressBar as an iterator:
+    >>> progress = ProgressBar()
+    >>> for i in progress(some_iterable):
+    ...    # do something
+    ...
+
+    Since the progress bar is incredibly customizable you can specify
+    different widgets of any type in any order. You can even write your own
+    widgets! However, since there are already a good number of widgets you
+    should probably play around with them before moving on to create your own
+    widgets.
+
+    The term_width parameter represents the current terminal width. If the
+    parameter is set to an integer then the progress bar will use that,
+    otherwise it will attempt to determine the terminal width falling back to
+    80 columns if the width cannot be determined.
+
+    When implementing a widget's update method you are passed a reference to
+    the current progress bar. As a result, you have access to the
+    ProgressBar's methods and attributes. Although there is nothing preventing
+    you from changing the ProgressBar you should treat it as read only.
+
+    Useful methods and attributes include (Public API):
+     - currval: current progress (0 <= currval <= maxval)
+     - maxval: maximum (and final) value
+     - finished: True if the bar has finished (reached 100%)
+     - start_time: the time when start() method of ProgressBar was called
+     - seconds_elapsed: seconds elapsed since start_time and last call to
+                        update
+     - percentage(): progress in percent [0..100]
+    """
+
+    __slots__ = ('currval', 'fd', 'finished', 'last_update_time',
+                 'left_justify', 'maxval', 'next_update', 'num_intervals',
+                 'poll', 'seconds_elapsed', 'signal_set', 'start_time',
+                 'term_width', 'update_interval', 'widgets', '_time_sensitive',
+                 '__iterable')
+
+    _DEFAULT_MAXVAL = 100
+    _DEFAULT_TERMSIZE = 80
+    _DEFAULT_WIDGETS = [widgets.Percentage(), ' ', widgets.Bar()]
+
+    def __init__(self, maxval=None, widgets=None, term_width=None, poll=1,
+                 left_justify=True, fd=sys.stderr):
+        """Initializes a progress bar with sane defaults."""
+
+        # Don't share a reference with any other progress bars
+        if widgets is None:
+            widgets = list(self._DEFAULT_WIDGETS)
+
+        self.maxval = maxval
+        self.widgets = widgets
+        self.fd = fd
+        self.left_justify = left_justify
+
+        self.signal_set = False
+        if term_width is not None:
+            self.term_width = term_width
+        else:
+            try:
+                self._handle_resize()
+                signal.signal(signal.SIGWINCH, self._handle_resize)
+                self.signal_set = True
+            except (SystemExit, KeyboardInterrupt): raise
+            except:
+                self.term_width = self._env_size()
+
+        self.__iterable = None
+        self._update_widgets()
+        self.currval = 0
+        self.finished = False
+        self.last_update_time = None
+        self.poll = poll
+        self.seconds_elapsed = 0
+        self.start_time = None
+        self.update_interval = 1
+        self.next_update = 0
+
+
+    def __call__(self, iterable):
+        """Use a ProgressBar to iterate through an iterable."""
+
+        try:
+            self.maxval = len(iterable)
+        except:
+            if self.maxval is None:
+                self.maxval = UnknownLength
+
+        self.__iterable = iter(iterable)
+        return self
+
+
+    def __iter__(self):
+        return self
+
+
+    def __next__(self):
+        try:
+            value = next(self.__iterable)
+            if self.start_time is None:
+                self.start()
+            else:
+                self.update(self.currval + 1)
+            return value
+        except StopIteration:
+            if self.start_time is None:
+                self.start()
+            self.finish()
+            raise
+
+
+    # Create an alias so that Python 2.x won't complain about not being
+    # an iterator.
+    next = __next__
+
+
+    def _env_size(self):
+        """Tries to find the term_width from the environment."""
+
+        return int(os.environ.get('COLUMNS', self._DEFAULT_TERMSIZE)) - 1
+
+
+    def _handle_resize(self, signum=None, frame=None):
+        """Tries to catch resize signals sent from the terminal."""
+
+        h, w = array('h', ioctl(self.fd, termios.TIOCGWINSZ, '\0' * 8))[:2]
+        self.term_width = w
+
+
+    def percentage(self):
+        """Returns the progress as a percentage."""
+        if self.currval >= self.maxval:
+            return 100.0
+        return self.currval * 100.0 / self.maxval
+
+    percent = property(percentage)
+
+
+    def _format_widgets(self):
+        result = []
+        expanding = []
+        width = self.term_width
+
+        for index, widget in enumerate(self.widgets):
+            if isinstance(widget, widgets.WidgetHFill):
+                result.append(widget)
+                expanding.insert(0, index)
+            else:
+                widget = widgets.format_updatable(widget, self)
+                result.append(widget)
+                width -= len(widget)
+
+        count = len(expanding)
+        while count:
+            portion = max(int(math.ceil(width * 1. / count)), 0)
+            index = expanding.pop()
+            count -= 1
+
+            widget = result[index].update(self, portion)
+            width -= len(widget)
+            result[index] = widget
+
+        return result
+
+
+    def _format_line(self):
+        """Joins the widgets and justifies the line."""
+
+        widgets = ''.join(self._format_widgets())
+
+        if self.left_justify: return widgets.ljust(self.term_width)
+        else: return widgets.rjust(self.term_width)
+
+
+    def _need_update(self):
+        """Returns whether the ProgressBar should redraw the line."""
+        if self.currval >= self.next_update or self.finished: return True
+
+        delta = time.time() - self.last_update_time
+        return self._time_sensitive and delta > self.poll
+
+
+    def _update_widgets(self):
+        """Checks all widgets for the time sensitive bit."""
+
+        self._time_sensitive = any(getattr(w, 'TIME_SENSITIVE', False)
+                                    for w in self.widgets)
+
+
+    def update(self, value=None):
+        """Updates the ProgressBar to a new value."""
+
+        if value is not None and value is not UnknownLength:
+            if (self.maxval is not UnknownLength
+                and not 0 <= value <= self.maxval):
+
+                raise ValueError('Value out of range')
+
+            self.currval = value
+
+
+        if not self._need_update(): return
+        if self.start_time is None:
+            raise RuntimeError('You must call "start" before calling "update"')
+
+        now = time.time()
+        self.seconds_elapsed = now - self.start_time
+        self.next_update = self.currval + self.update_interval
+        self.fd.write(self._format_line() + '\r')
+        self.last_update_time = now
+
+
+    def start(self):
+        """Starts measuring time, and prints the bar at 0%.
+
+        It returns self so you can use it like this:
+        >>> pbar = ProgressBar().start()
+        >>> for i in range(100):
+        ...    # do something
+        ...    pbar.update(i+1)
+        ...
+        >>> pbar.finish()
+        """
+
+        if self.maxval is None:
+            self.maxval = self._DEFAULT_MAXVAL
+
+        self.num_intervals = max(100, self.term_width)
+        self.next_update = 0
+
+        if self.maxval is not UnknownLength:
+            if self.maxval < 0: raise ValueError('Value out of range')
+            self.update_interval = self.maxval / self.num_intervals
+
+
+        self.start_time = self.last_update_time = time.time()
+        self.update(0)
+
+        return self
+
+
+    def finish(self):
+        """Puts the ProgressBar bar in the finished state."""
+
+        if self.finished:
+            return
+        self.finished = True
+        self.update(self.maxval)
+        self.fd.write('\n')
+        if self.signal_set:
+            signal.signal(signal.SIGWINCH, signal.SIG_DFL)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/examples/progressbar/widgets.py 
new/tqdm-4.23.4/examples/progressbar/widgets.py
--- old/tqdm-4.23.3/examples/progressbar/widgets.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/tqdm-4.23.4/examples/progressbar/widgets.py     2015-12-28 
23:16:15.000000000 +0100
@@ -0,0 +1,356 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# progressbar  - Text progress bar library for Python.
+# Copyright (c) 2005 Nilton Volpato
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+"""Default ProgressBar widgets."""
+
+from __future__ import division
+
+import datetime
+import math
+
+try:
+    from abc import ABCMeta, abstractmethod
+except ImportError:
+    AbstractWidget = object
+    abstractmethod = lambda fn: fn
+else:
+    AbstractWidget = ABCMeta('AbstractWidget', (object,), {})
+
+
+def format_updatable(updatable, pbar):
+    if hasattr(updatable, 'update'): return updatable.update(pbar)
+    else: return updatable
+
+
+class Widget(AbstractWidget):
+    """The base class for all widgets.
+
+    The ProgressBar will call the widget's update value when the widget should
+    be updated. The widget's size may change between calls, but the widget may
+    display incorrectly if the size changes drastically and repeatedly.
+
+    The boolean TIME_SENSITIVE informs the ProgressBar that it should be
+    updated more often because it is time sensitive.
+    """
+
+    TIME_SENSITIVE = False
+    __slots__ = ()
+
+    @abstractmethod
+    def update(self, pbar):
+        """Updates the widget.
+
+        pbar - a reference to the calling ProgressBar
+        """
+
+
+class WidgetHFill(Widget):
+    """The base class for all variable width widgets.
+
+    This widget is much like the \\hfill command in TeX, it will expand to
+    fill the line. You can use more than one in the same line, and they will
+    all have the same width, and together will fill the line.
+    """
+
+    @abstractmethod
+    def update(self, pbar, width):
+        """Updates the widget providing the total width the widget must fill.
+
+        pbar - a reference to the calling ProgressBar
+        width - The total width the widget must fill
+        """
+
+
+class Timer(Widget):
+    """Widget which displays the elapsed seconds."""
+
+    __slots__ = ('format_string',)
+    TIME_SENSITIVE = True
+
+    def __init__(self, format='Elapsed Time: %s'):
+        self.format_string = format
+
+    @staticmethod
+    def format_time(seconds):
+        """Formats time as the string "HH:MM:SS"."""
+
+        return str(datetime.timedelta(seconds=int(seconds)))
+
+
+    def update(self, pbar):
+        """Updates the widget to show the elapsed time."""
+
+        return self.format_string % self.format_time(pbar.seconds_elapsed)
+
+
+class ETA(Timer):
+    """Widget which attempts to estimate the time of arrival."""
+
+    TIME_SENSITIVE = True
+
+    def update(self, pbar):
+        """Updates the widget to show the ETA or total time when finished."""
+
+        if pbar.currval == 0:
+            return 'ETA:  --:--:--'
+        elif pbar.finished:
+            return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
+        else:
+            elapsed = pbar.seconds_elapsed
+            eta = elapsed * pbar.maxval / pbar.currval - elapsed
+            return 'ETA:  %s' % self.format_time(eta)
+
+
+class AdaptiveETA(Timer):
+    """Widget which attempts to estimate the time of arrival.
+
+    Uses a weighted average of two estimates:
+      1) ETA based on the total progress and time elapsed so far
+      2) ETA based on the progress as per tha last 10 update reports
+
+    The weight depends on the current progress so that to begin with the
+    total progress is used and at the end only the most recent progress is
+    used.
+    """
+
+    TIME_SENSITIVE = True
+    NUM_SAMPLES = 10
+
+    def _update_samples(self, currval, elapsed):
+        sample = (currval, elapsed)
+        if not hasattr(self, 'samples'):
+            self.samples = [sample] * (self.NUM_SAMPLES + 1)
+        else:
+            self.samples.append(sample)
+        return self.samples.pop(0)
+
+    def _eta(self, maxval, currval, elapsed):
+        return elapsed * maxval / float(currval) - elapsed
+
+    def update(self, pbar):
+        """Updates the widget to show the ETA or total time when finished."""
+        if pbar.currval == 0:
+            return 'ETA:  --:--:--'
+        elif pbar.finished:
+            return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
+        else:
+            elapsed = pbar.seconds_elapsed
+            currval1, elapsed1 = self._update_samples(pbar.currval, elapsed)
+            eta = self._eta(pbar.maxval, pbar.currval, elapsed)
+            if pbar.currval > currval1:
+                etasamp = self._eta(pbar.maxval - currval1,
+                                    pbar.currval - currval1,
+                                    elapsed - elapsed1)
+                weight = (pbar.currval / float(pbar.maxval)) ** 0.5
+                eta = (1 - weight) * eta + weight * etasamp
+            return 'ETA:  %s' % self.format_time(eta)
+
+
+class FileTransferSpeed(Widget):
+    """Widget for showing the transfer speed (useful for file transfers)."""
+
+    FORMAT = '%6.2f %s%s/s'
+    PREFIXES = ' kMGTPEZY'
+    __slots__ = ('unit',)
+
+    def __init__(self, unit='B'):
+        self.unit = unit
+
+    def update(self, pbar):
+        """Updates the widget with the current SI prefixed speed."""
+
+        if pbar.seconds_elapsed < 2e-6 or pbar.currval < 2e-6: # =~ 0
+            scaled = power = 0
+        else:
+            speed = pbar.currval / pbar.seconds_elapsed
+            power = int(math.log(speed, 1000))
+            scaled = speed / 1000.**power
+
+        return self.FORMAT % (scaled, self.PREFIXES[power], self.unit)
+
+
+class AnimatedMarker(Widget):
+    """An animated marker for the progress bar which defaults to appear as if
+    it were rotating.
+    """
+
+    __slots__ = ('markers', 'curmark')
+
+    def __init__(self, markers='|/-\\'):
+        self.markers = markers
+        self.curmark = -1
+
+    def update(self, pbar):
+        """Updates the widget to show the next marker or the first marker when
+        finished"""
+
+        if pbar.finished: return self.markers[0]
+
+        self.curmark = (self.curmark + 1) % len(self.markers)
+        return self.markers[self.curmark]
+
+# Alias for backwards compatibility
+RotatingMarker = AnimatedMarker
+
+
+class Counter(Widget):
+    """Displays the current count."""
+
+    __slots__ = ('format_string',)
+
+    def __init__(self, format='%d'):
+        self.format_string = format
+
+    def update(self, pbar):
+        return self.format_string % pbar.currval
+
+
+class Percentage(Widget):
+    """Displays the current percentage as a number with a percent sign."""
+
+    def update(self, pbar):
+        return '%3d%%' % pbar.percentage()
+
+
+class FormatLabel(Timer):
+    """Displays a formatted label."""
+
+    mapping = {
+        'elapsed': ('seconds_elapsed', Timer.format_time),
+        'finished': ('finished', None),
+        'last_update': ('last_update_time', None),
+        'max': ('maxval', None),
+        'seconds': ('seconds_elapsed', None),
+        'start': ('start_time', None),
+        'value': ('currval', None)
+    }
+
+    __slots__ = ('format_string',)
+    def __init__(self, format):
+        self.format_string = format
+
+    def update(self, pbar):
+        context = {}
+        for name, (key, transform) in self.mapping.items():
+            try:
+                value = getattr(pbar, key)
+
+                if transform is None:
+                   context[name] = value
+                else:
+                   context[name] = transform(value)
+            except: pass
+
+        return self.format_string % context
+
+
+class SimpleProgress(Widget):
+    """Returns progress as a count of the total (e.g.: "5 of 47")."""
+
+    __slots__ = ('sep',)
+
+    def __init__(self, sep=' of '):
+        self.sep = sep
+
+    def update(self, pbar):
+        return '%d%s%d' % (pbar.currval, self.sep, pbar.maxval)
+
+
+class Bar(WidgetHFill):
+    """A progress bar which stretches to fill the line."""
+
+    __slots__ = ('marker', 'left', 'right', 'fill', 'fill_left')
+
+    def __init__(self, marker='#', left='|', right='|', fill=' ',
+                 fill_left=True):
+        """Creates a customizable progress bar.
+
+        marker - string or updatable object to use as a marker
+        left - string or updatable object to use as a left border
+        right - string or updatable object to use as a right border
+        fill - character to use for the empty part of the progress bar
+        fill_left - whether to fill from the left or the right
+        """
+        self.marker = marker
+        self.left = left
+        self.right = right
+        self.fill = fill
+        self.fill_left = fill_left
+
+
+    def update(self, pbar, width):
+        """Updates the progress bar and its subcomponents."""
+
+        left, marked, right = (format_updatable(i, pbar) for i in
+                               (self.left, self.marker, self.right))
+
+        width -= len(left) + len(right)
+        # Marked must *always* have length of 1
+        if pbar.maxval:
+          marked *= int(pbar.currval / pbar.maxval * width)
+        else:
+          marked = ''
+
+        if self.fill_left:
+            return '%s%s%s' % (left, marked.ljust(width, self.fill), right)
+        else:
+            return '%s%s%s' % (left, marked.rjust(width, self.fill), right)
+
+
+class ReverseBar(Bar):
+    """A bar which has a marker which bounces from side to side."""
+
+    def __init__(self, marker='#', left='|', right='|', fill=' ',
+                 fill_left=False):
+        """Creates a customizable progress bar.
+
+        marker - string or updatable object to use as a marker
+        left - string or updatable object to use as a left border
+        right - string or updatable object to use as a right border
+        fill - character to use for the empty part of the progress bar
+        fill_left - whether to fill from the left or the right
+        """
+        self.marker = marker
+        self.left = left
+        self.right = right
+        self.fill = fill
+        self.fill_left = fill_left
+
+
+class BouncingBar(Bar):
+    def update(self, pbar, width):
+        """Updates the progress bar and its subcomponents."""
+
+        left, marker, right = (format_updatable(i, pbar) for i in
+                               (self.left, self.marker, self.right))
+
+        width -= len(left) + len(right)
+
+        if pbar.finished: return '%s%s%s' % (left, width * marker, right)
+
+        position = int(pbar.currval % (width * 2 - 1))
+        if position > width: position = width * 2 - position
+        lpad = self.fill * (position - 1)
+        rpad = self.fill * (width - len(marker) - len(lpad))
+
+        # Swap if we want to bounce the other way
+        if not self.fill_left: rpad, lpad = lpad, rpad
+
+        return '%s%s%s%s%s' % (left, lpad, marker, rpad, right)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/setup.py new/tqdm-4.23.4/setup.py
--- old/tqdm-4.23.3/setup.py    2018-03-09 23:49:27.000000000 +0100
+++ new/tqdm-4.23.4/setup.py    2018-05-22 21:02:36.000000000 +0200
@@ -179,6 +179,7 @@
     data_files=[('man/man1', ['tqdm.1'])],
     package_data={'': ['CONTRIBUTING.md', 'LICENCE', 'examples/*.py']},
     long_description=README_rst,
+    python_requires='>=2.6, !=3.0.*, !=3.1.*',
     classifiers=[
         # Trove classifiers
         # (https://pypi.python.org/pypi?%3Aaction=list_classifiers)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tox.ini new/tqdm-4.23.4/tox.ini
--- old/tqdm-4.23.3/tox.ini     2018-05-02 18:43:34.000000000 +0200
+++ new/tqdm-4.23.4/tox.ini     2018-05-14 01:34:20.000000000 +0200
@@ -28,7 +28,6 @@
 
 [testenv]
 # default tests (most things)
-basepython = /home/cc16/py2/envs/{envname}/bin/python
 passenv = CI TRAVIS TRAVIS_*
 deps =
     {[extra]deps}
@@ -44,7 +43,6 @@
 
 [testenv:py26]
 # no codecov and timer for py26
-setenv = LD_LIBRARY_PATH = /home/cc16/py2/envs/{envname}/lib
 deps = {[coverage]deps}
 commands = {[coverage]commands}
 
@@ -73,7 +71,6 @@
 commands = {[extra]commands}
 
 [testenv:perf]
-basepython = python
 deps =
     nose
     nose-timer
@@ -81,13 +78,11 @@
     nosetests --with-timer tqdm/tests/tests_perf.py -d -v
 
 [testenv:flake8]
-basepython = python
 deps = flake8
 commands =
     flake8 --max-line-length=80 -j 8 --count --statistics --exit-zero .
 
 [testenv:setup.py]
-basepython = python
 deps =
     docutils
     pygments
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/_tqdm.py 
new/tqdm-4.23.4/tqdm/_tqdm.py
--- old/tqdm-4.23.3/tqdm/_tqdm.py       2018-05-08 15:36:46.000000000 +0200
+++ new/tqdm-4.23.4/tqdm/_tqdm.py       2018-05-22 21:02:36.000000000 +0200
@@ -539,16 +539,19 @@
         """
         from pandas.core.frame import DataFrame
         from pandas.core.series import Series
-        from pandas.core.groupby import DataFrameGroupBy
-        from pandas.core.groupby import SeriesGroupBy
-        from pandas.core.groupby import GroupBy
-        from pandas.core.groupby import PanelGroupBy
         from pandas import Panel
         try:
             # pandas>=0.18.0
             from pandas.core.window import _Rolling_and_Expanding
         except ImportError:  # pragma: no cover
             _Rolling_and_Expanding = None
+        try:
+            # pandas>=0.23.0
+            from pandas.core.groupby.groupby import DataFrameGroupBy, \
+                SeriesGroupBy, GroupBy, PanelGroupBy
+        except ImportError:
+            from pandas.core.groupby import DataFrameGroupBy, \
+                SeriesGroupBy, GroupBy, PanelGroupBy
 
         deprecated_t = [tkwargs.pop('deprecated_t', None)]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/_utils.py 
new/tqdm-4.23.4/tqdm/_utils.py
--- old/tqdm-4.23.3/tqdm/_utils.py      2018-05-08 15:36:46.000000000 +0200
+++ new/tqdm-4.23.4/tqdm/_utils.py      2018-05-22 21:02:36.000000000 +0200
@@ -130,13 +130,13 @@
         return self._comparable == other._comparable
 
     def __ne__(self, other):
-        return not (self == other)
+        return not self == other
 
     def __gt__(self, other):
-        return not (self <= other)
+        return not self <= other
 
     def __ge__(self, other):
-        return not (self < other)
+        return not self < other
 
 
 def _is_utf(encoding):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/_version.py 
new/tqdm-4.23.4/tqdm/_version.py
--- old/tqdm-4.23.3/tqdm/_version.py    2018-05-08 15:41:11.000000000 +0200
+++ new/tqdm-4.23.4/tqdm/_version.py    2018-05-22 21:03:00.000000000 +0200
@@ -5,7 +5,7 @@
 __all__ = ["__version__"]
 
 # major, minor, patch, -extra
-version_info = 4, 23, 3
+version_info = 4, 23, 4
 
 # Nice string for the version
 __version__ = '.'.join(map(str, version_info))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/tests/tests_main.py 
new/tqdm-4.23.4/tqdm/tests/tests_main.py
--- old/tqdm-4.23.3/tqdm/tests/tests_main.py    2018-03-09 23:49:27.000000000 
+0100
+++ new/tqdm-4.23.4/tqdm/tests/tests_main.py    2018-05-22 21:02:36.000000000 
+0200
@@ -24,7 +24,7 @@
 
     # actual test:
 
-    assert (ls_out in res.replace('\r\n', '\n'))
+    assert ls_out in res.replace('\r\n', '\n')
 
     # semi-fake test which gets coverage:
     _SYS = sys.stdin, sys.argv
@@ -49,7 +49,7 @@
         sys.argv = ['', '--ascii', '--bytes', '--unit_scale', 'False']
         with closing(UnicodeIO()) as fp:
             main(fp=fp)
-            assert (str(len(IN_DATA)) in fp.getvalue())
+            assert str(len(IN_DATA)) in fp.getvalue()
 
     sys.stdin = IN_DATA_LIST
     sys.argv = ['', '-ascii', '--unit_scale', 'False',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/tests/tests_perf.py 
new/tqdm-4.23.4/tqdm/tests/tests_perf.py
--- old/tqdm-4.23.3/tqdm/tests/tests_perf.py    2018-03-09 23:49:27.000000000 
+0100
+++ new/tqdm-4.23.4/tqdm/tests/tests_perf.py    2018-05-22 21:02:36.000000000 
+0200
@@ -172,7 +172,7 @@
             with relative_timer() as time_tqdm:
                 for i in t:
                     a += i
-        assert (a == (total * total - total) / 2.0)
+        assert a == (total * total - total) / 2.0
 
         a = 0
         with relative_timer() as time_bench:
@@ -227,7 +227,7 @@
             with relative_timer() as time_tqdm:
                 for i in t:
                     a += i
-        assert (a == (total * total - total) / 2.0)
+        assert a == (total * total - total) / 2.0
 
         a = 0
         with relative_timer() as time_bench:
@@ -237,7 +237,7 @@
 
     # Compute relative overhead of tqdm against native range()
     try:
-        assert (time_tqdm() < 60 * time_bench())
+        assert time_tqdm() < 60 * time_bench()
     except AssertionError:
         raise AssertionError('trange(%g): %f, range(%g): %f' %
                              (total, time_tqdm(), total, time_bench()))
@@ -267,7 +267,7 @@
 
     # Compute relative overhead of tqdm against native range()
     try:
-        assert (time_tqdm() < 100 * time_bench())
+        assert time_tqdm() < 100 * time_bench()
     except AssertionError:
         raise AssertionError('tqdm(%g): %f, range(%g): %f' %
                              (total, time_tqdm(), total, time_bench()))
@@ -287,7 +287,7 @@
             with relative_timer() as time_tqdm:
                 for i in t:
                     a += i
-        assert (a == (total * total - total) / 2.0)
+        assert a == (total * total - total) / 2.0
 
         a = 0
         s = simple_progress(_range(total), file=our_file, leave=True,
@@ -298,7 +298,7 @@
 
     # Compute relative overhead of tqdm against native range()
     try:
-        assert (time_tqdm() < 2.5 * time_bench())
+        assert time_tqdm() < 2.5 * time_bench()
     except AssertionError:
         raise AssertionError('trange(%g): %f, simple_progress(%g): %f' %
                              (total, time_tqdm(), total, time_bench()))
@@ -330,7 +330,7 @@
 
     # Compute relative overhead of tqdm against native range()
     try:
-        assert (time_tqdm() < 2.5 * time_bench())
+        assert time_tqdm() < 2.5 * time_bench()
     except AssertionError:
         raise AssertionError('tqdm(%g): %f, simple_progress(%g): %f' %
                              (total, time_tqdm(), total, time_bench()))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm/tests/tests_synchronisation.py 
new/tqdm-4.23.4/tqdm/tests/tests_synchronisation.py
--- old/tqdm-4.23.3/tqdm/tests/tests_synchronisation.py 2018-04-16 
17:20:23.000000000 +0200
+++ new/tqdm-4.23.4/tqdm/tests/tests_synchronisation.py 2018-05-22 
21:02:36.000000000 +0200
@@ -109,7 +109,7 @@
             timer.sleep(maxinterval * 2)
             t.update(2)
             timeend = timer.time()
-            while not (t.monitor.woken >= timeend):
+            while t.monitor.woken < timeend:
                 timer.sleep(1)  # Force monitor to wake up if it woken too soon
                 sleep(0.000001)
             # Wait for the monitor to get out of sleep's loop and update tqdm..
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm.egg-info/PKG-INFO 
new/tqdm-4.23.4/tqdm.egg-info/PKG-INFO
--- old/tqdm-4.23.3/tqdm.egg-info/PKG-INFO      2018-05-08 15:50:02.000000000 
+0200
+++ new/tqdm-4.23.4/tqdm.egg-info/PKG-INFO      2018-05-22 21:06:50.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: tqdm
-Version: 4.23.3
+Version: 4.23.4
 Summary: Fast, Extensible Progress Meter
 Home-page: https://github.com/tqdm/tqdm
 Author: Noam Yorav-Raphael
@@ -928,3 +928,4 @@
 Classifier: Topic :: System :: Shells
 Classifier: Topic :: Terminals
 Classifier: Topic :: Utilities
+Requires-Python: >=2.6, !=3.0.*, !=3.1.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tqdm-4.23.3/tqdm.egg-info/SOURCES.txt 
new/tqdm-4.23.4/tqdm.egg-info/SOURCES.txt
--- old/tqdm-4.23.3/tqdm.egg-info/SOURCES.txt   2018-05-08 15:50:02.000000000 
+0200
+++ new/tqdm-4.23.4/tqdm.egg-info/SOURCES.txt   2018-05-22 21:06:50.000000000 
+0200
@@ -16,6 +16,10 @@
 examples/redirect_print.py
 examples/simple_examples.py
 examples/tqdm_wget.py
+examples/progressbar/__init__.py
+examples/progressbar/compat.py
+examples/progressbar/progressbar.py
+examples/progressbar/widgets.py
 tqdm/__init__.py
 tqdm/__main__.py
 tqdm/_main.py


Reply via email to