81

I'm using tqdm to display progress bars while some long-running Django management commands complete. It works great (so easy to use!), but...

When I run unit tests over my code, I want to stop the progress bars from outputting. And if I run those commands in the background using cron or some other means, I'd also want the progress bars not to be in the output.

I can't see an easy way to do these two things, but perhaps I've missed something?

Phil Gyford
  • 13,432
  • 14
  • 81
  • 143

5 Answers5

79

Example using the 'disable' parameter:

from tqdm import tqdm
import time

for i in tqdm(range(10), disable=True):
    time.sleep(1)
cannin
  • 2,735
  • 2
  • 25
  • 32
62

There is a disable argument which you can set to True to silence any tqdm output (and in fact it will totally skip the progress bar calculations too, not just the display).

To dynamically switch it, you can just add a commandline argument to your script that will define if disable is set or not. This should work for both unit testing and cron.

gaborous
  • 15,832
  • 10
  • 83
  • 102
  • 1
    How can you disable display while maintaining calculations? – Austin Apr 09 '21 at 06:25
  • 1
    @Austin You mean the calculations of the progress bar? There is no way, but what would be the point since you are not displaying it? As soon as you resume the display by disabling the `disable` argument, the progress bar calculations will resume. But in any case, the calculations of your app are not affected in any way, it's only the progress bar calculations for display that are disabled. – gaborous Sep 18 '21 at 12:52
59

This is a very common use case when you need to globally disable all tqdm's output, desirably without changing the code in all places where it is used and which you probably do not control.

Starting version 4.66.0

Set environment variable TQDM_DISABLE=1. Note that exact value of the variable does not matter, it just should be a non-empty string.

Older versions

Users need to patch tqdm in order to stop polluting logs. One of the shortest ways I found is probably this:

from tqdm import tqdm
from functools import partialmethod

tqdm.__init__ = partialmethod(tqdm.__init__, disable=True)

The idea is defaulting the already supported (but not sufficient) parameter of the initializer. It is not sufficient because you need to add it in each place where tqdm is instantiated, which you don't want, that's why we modify __init__ to make such a default.

The patch works independently of the order of imports and will affect all subsequently created tqdm objects.

greatvovan
  • 2,439
  • 23
  • 43
  • 2
    I just tried this, it works on imported packages using tqdm without touching or rewriting the code at all. – Lars Ericson Oct 11 '21 at 17:28
  • 1
    This is wonderful for dealing with external dependencies with tqdm statements that you don't want filling up logs that you are trying to monitor – colby-ham Dec 21 '21 at 21:08
  • 1
    That is a perfect answer. You neither need to change the existing code nor need to add any boolean flag that will be passed all around. I just added this to the beginning of my testing_main.py, and it disabled all tqdm outputs for the testing environment. – Berkay Berabi Jan 28 '22 at 09:54
  • 1
    This is perfect, add it to `tests/__init__.py` and you can move on with your day. – David258 Sep 22 '22 at 15:23
  • If this is not working for you, make sure you're using it on `from tqdm import tqdm` instead of just on `import tqdm` ;) – Cnly Jan 07 '23 at 17:18
  • Also, if this is not working for you, check if the respective module is actually using `from tqdm import tqdm`, it can also be `from tqdm.auto import tqdm`. – Eloy Pérez Torres Mar 16 '23 at 16:21
9

Use mock.patch to replace tqdm in the code that's using it with something like this:

def notqdm(iterable, *args, **kwargs):
    """
    replacement for tqdm that just passes back the iterable
    useful to silence `tqdm` in tests
    """
    return iterable

and in the test:

import mock

...

    @mock.patch('tested_code_module.tqdm', notqdm)
    def test_method(self):
    ...
shade of blue
  • 299
  • 2
  • 4
0

Since version 4.66.0, the default tqdm arguments can be overridden using environment variables with the TQDM_-prefix followed by the parameter name. This means you can disable tqdm's output by setting the TQDM_DISABLE environment variable to 1 before importing tqdm or any modules that use it:

import os

os.environ["TQDM_DISABLE"] = "1"

# import tqdm and/or modules that use it here
Jonathan Feenstra
  • 2,534
  • 1
  • 15
  • 22