Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions tqdm_3/tqdm/_tqdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,17 +947,6 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
# NB: Avoid race conditions by setting start_t at the very end of init
self.start_t = self.last_print_t

def __bool__(self):
if self.total is not None:
return self.total > 0
if self.iterable is None:
raise TypeError('Boolean cast is undefined'
' for tqdm objects that have no iterable or total')
return bool(self.iterable)

def __nonzero__(self):
return self.__bool__()

Comment on lines -950 to -960
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Warning 🐛 Bug

Calling bool(tqdm_instance) on a generator-based tqdm raises a TypeError.

Issue Explanation
  • The tqdm class no longer defines __bool__/__nonzero__.
  • Python falls back to __len__ for truth-value testing.
  • The __len__ method calls len(self.iterable).
  • len(generator) raises TypeError when the iterable has no __len__.
  • bool(tqdm(generator)) now triggers this TypeError, breaking code that previously returned True.

Reply if you have any questions or let me know if I missed something.
Don't forget to react with a 👍 or 👎 to the comments made by Blar to help us improve.

def __len__(self):
return self.total if self.iterable is None else \
(self.iterable.shape[0] if hasattr(self.iterable, "shape")
Expand Down
37 changes: 16 additions & 21 deletions tqdm_3/tqdm/tests/tests_tqdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1710,32 +1710,27 @@ def test_threading():
@with_setup(pretest, posttest)
def test_bool():
"""Test boolean cast"""

def internal(our_file, disable):
with tqdm(total=10, file=our_file, disable=disable) as t:
assert t
with tqdm(total=0, file=our_file, disable=disable) as t:
assert not t
with trange(10, file=our_file, disable=disable) as t:
assert t
with trange(0, file=our_file, disable=disable) as t:
assert not t

def get_bool_for_tqdm(*args, **kwargs):
kwargs['file'] = our_file
kwargs['disable'] = disable
with tqdm(*args, **kwargs) as t:
return bool(t)

assert get_bool_for_tqdm(total=10)
assert not get_bool_for_tqdm(total=0)
assert not get_bool_for_tqdm([])
assert get_bool_for_tqdm([0])
assert get_bool_for_tqdm((x for x in []))
assert get_bool_for_tqdm((x for x in [1,2,3]))
try:
get_bool_for_tqdm()
except TypeError:
pass
else:
raise TypeError(
"Expected tqdm() with neither total nor iterable to fail")
with tqdm([], file=our_file, disable=disable) as t:
assert not t
with tqdm([0], file=our_file, disable=disable) as t:
assert t
with tqdm(file=our_file, disable=disable) as t:
try:
print(bool(t))
except TypeError:
pass
else:
raise TypeError(
"Expected tqdm() with neither total nor iterable to fail")

# test with and without disable
with closing(StringIO()) as our_file:
Expand Down