tqdm/tqdm

envwrap checks os.environ on import not on call

td-anne opened this issue · 0 comments

  • I have marked all applicable categories:
    • documentation request (i.e. "X is missing from the documentation." If instead I want to ask "how to use X?" I understand StackOverflow#tqdm is more appropriate)
    • new feature request
  • I have visited the source website, and in particular
    read the known issues
  • I have searched through the issue tracker for duplicates
  • I have mentioned version numbers, operating system and
    environment, where applicable:
    import tqdm, sys
    print(tqdm.__version__, sys.version, sys.platform)

If one wants to disable tqdm activity for an entire script, one can set the environment variableTQDM_DISABLE before running the script. This is implemented using the envwrap decorator, which allows environment variables to overwrite the defaults of functions it wraps. Unfortunately, if one wants to disable tqdm from inside the python script (possibly calling a library that has tqdm calls in it; the datasets library from Huggingface does this, for example), one must set TQDM_DISABLE before importing tqdm. If envwrap checked os.environ on call, one could selectively disable tqdm for some parts of a program (for example, these datasets process very quickly, but those other ones are so slow I need a progress bar; #1514). The code to do this would be relatively simple:

@contextlib.contextmanager
def disable_tqdm() -> Generator[None, Any, None]:
    """Disable tqdm progress bars."""
    old_env: str | None = os.environ.get("TQDM_DISABLE")
    try:
        os.environ["TQDM_DISABLE"] = "1"
        yield
    finally:
        if old_env is None:
            del os.environ["TQDM_DISABLE"]
        else:
            os.environ["TQDM_DISABLE"] = old_env

Sadly this does not work.

Implementing this would require changing envwrap so that instead of using functools.partial/functools.partialmethod it actually constructed a wrapper function that checked the environment variables at runtime. The business of figuring out the intended types could still happen on import, but the conversion from strings in os.environ would happen at call time. This would move the error reporting (if the environment variable's value cannot be converted to the required type) from import time to call time, which also seems like a benefit.