Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix reversed(tqdm(..)) #1485

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/tests_tqdm.py
Expand Up @@ -1963,8 +1963,8 @@ def test_closed():

def test_reversed(capsys):
"""Test reversed()"""
for _ in reversed(tqdm(range(9))):
pass
reverse = list(reversed(tqdm(range(9))))
assert reverse == list(reversed(range(9)))
out, err = capsys.readouterr()
assert not out
assert ' 0%' in err
Expand Down
65 changes: 36 additions & 29 deletions tqdm/std.py
Expand Up @@ -1160,37 +1160,44 @@ def __iter__(self):
# Inlining instance variables as locals (speed optimisation)
iterable = self.iterable

# If the bar is disabled, then just walk the iterable
# (note: keep this check outside the loop for performance)
if self.disable:
for obj in iterable:
yield obj
return
# Wrap yielding code, so `__iter__` itself isn't a generator and `iterable` is set at the time
# `__iter__` is called, rather than when the first element is required. This is needed because
# `__reversed__` swaps the iterator with a reversed one, stores the generator returned by
# `__iter__()`, then swaps the old iterator back.
def generator():
# If the bar is disabled, then just walk the iterable
# (note: keep this check outside the loop for performance)
if self.disable:
for obj in iterable:
yield obj
return

mininterval = self.mininterval
last_print_t = self.last_print_t
last_print_n = self.last_print_n
min_start_t = self.start_t + self.delay
n = self.n
time = self._time
mininterval = self.mininterval
last_print_t = self.last_print_t
last_print_n = self.last_print_n
min_start_t = self.start_t + self.delay
n = self.n
time = self._time

try:
for obj in iterable:
yield obj
# Update and possibly print the progressbar.
# Note: does not call self.update(1) for speed optimisation.
n += 1

if n - last_print_n >= self.miniters:
cur_t = time()
dt = cur_t - last_print_t
if dt >= mininterval and cur_t >= min_start_t:
self.update(n - last_print_n)
last_print_n = self.last_print_n
last_print_t = self.last_print_t
finally:
self.n = n
self.close()
try:
for obj in iterable:
yield obj
# Update and possibly print the progressbar.
# Note: does not call self.update(1) for speed optimisation.
n += 1

if n - last_print_n >= self.miniters:
cur_t = time()
dt = cur_t - last_print_t
if dt >= mininterval and cur_t >= min_start_t:
self.update(n - last_print_n)
last_print_n = self.last_print_n
last_print_t = self.last_print_t
finally:
self.n = n
self.close()

return generator()

def update(self, n=1):
"""
Expand Down