I\'m using tqdm in Python to display console-progressbars in our scripts.
However, I have to call functions which print messages to the console as
OP's solution is almost correct. The test in tqdm library that messes up your output is this one (https://github.com/tqdm/tqdm/blob/master/tqdm/_tqdm.py#L546-L549):
if hasattr(inst, "start_t") and (inst.fp == fp or all(
f in (sys.stdout, sys.stderr) for f in (fp, inst.
inst.clear(nolock=True)
inst_cleared.append(inst)
tqdm.write is testing the file you provided to see if there is risk of collision between the text to print and potential tqdm bars. In your case stdout and stderr get mixed in the terminal so there is a collision. To counter this, when the test passes, tqdm clears the bars, prints the text and draws the bars back after.
Here, the test fp == sys.stdout fails because sys.stdout became DummyFile, and fp is the real sys.stdout, so the cleaning behavior is not enabled. A simple equality operator in DummyFile fixes everything.
class DummyFile(object):
def __init__(self, file):
self.file = file
def write(self, x):
tqdm.write(x, end="", file=self.file)
def __eq__(self, other):
return other is self.file
Also, since print passes a newline to sys.stdout (or not depending on the user choice), you don't want tqdm to add another one on its own, so it's better to set the option end='' than performing strip on the content.
With gaborous's answer, tqdm(..., file=sys.stdout) pollutes your output stream with pieces of bar. By keeping file=sys.stdout (default), you keep your streams separated.
With Conchylicultor and user493630's answers, you only patch print. However other systems such as logging directly stream to sys.stdout, so they don't go through tqdm.write.