NiltonVolpato / python-progressbar

Text progress bar library for Python
Other
412 stars 105 forks source link

Using ProgressBar as iterator from empty iterable causes traceback #36

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
progressbar==2.3
Ubuntu 13.04

So this works:

for n in progressbar.ProgressBar()([1]):
    print n

It will print 1 and all the progress information as expected.

But

for n in progressbar.ProgressBar()([]):
    print n

gives traceback as follows:

AttributeError                            Traceback (most recent call last)
<ipython-input-4-bf738fc09ad4> in <module>()
----> 1 for n in progressbar.ProgressBar()([]):
      2     print n
      3 

/home/tcorbettclark/.virtualenvs/ice/local/lib/python2.7/site-packages/progressb
ar/__init__.pyc in __next__(self)
    182             return value
    183         except StopIteration:
--> 184             self.finish()
    185             raise
    186 

/home/tcorbettclark/.virtualenvs/ice/local/lib/python2.7/site-packages/progressb
ar/__init__.pyc in finish(self)
    318 
    319         self.finished = True
--> 320         self.update(self.maxval)
    321         self.fd.write('\n')
    322         if self.signal_set:

/home/tcorbettclark/.virtualenvs/ice/local/lib/python2.7/site-packages/progressb
ar/__init__.pyc in update(self, value)
    274 
    275 
--> 276         if not self._need_update(): return
    277         if self.start_time is None:
    278             raise RuntimeError('You must call "start" before calling "update"')

/home/tcorbettclark/.virtualenvs/ice/local/lib/python2.7/site-packages/progressb
ar/__init__.pyc in _need_update(self)
    249     def _need_update(self):
    250         'Returns whether the ProgressBar should redraw the line.'
--> 251         if self.currval >= self.next_update or self.finished: return 
True
    252 
    253         delta = time.time() - self.last_update_time

AttributeError: next_update

Original issue reported on code.google.com by timothy....@gmail.com on 13 Apr 2014 at 11:41

GoogleCodeExporter commented 8 years ago
Occurs because __next__ on empty list immediately throws a StopIteration 
exception

Can be fixed by:

    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() # !!! this line added
            self.finish()
            raise

Original comment by taras...@gmail.com on 28 May 2014 at 1:54

frost-nzcr4 commented 8 years ago

Run start() manually to initiate the next_update property:

progress = ProgressBar(maxval=my.objects.count() or None).start()
for item in progress(my.objects.iterator()):
    pass