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

stdout redirection issues #588

Open
henryiii opened this issue Aug 9, 2018 · 2 comments
Open

stdout redirection issues #588

henryiii opened this issue Aug 9, 2018 · 2 comments
Assignees
Labels
p3-enhancement 🔥 Much new such feature question/docs ‽ Documentation clarification candidate to-review 🔍 Awaiting final confirmation

Comments

@henryiii
Copy link

henryiii commented Aug 9, 2018

There are several issues with the example of the DummyTqdmFile in the readme:

  1. file = None in the class makes it a class level variable, rather than object level. It should be removed or changed to __slots__ = ("file",).
  2. The catch exception line is useless, all it does is rethrow. You can leave it out safely. (finally does the job)
  3. Mentioning redirect_stdout (Python 3.4+) and redirect_stderr (Python 3.5+) in contextlib might be nice for people using those versions of Python.
  4. tdqm.write does not behave like a normal .write, it adds a \n. This causes lots of issues with this overwrite, especially inside nested progress bars. I worked on this a while, and could not get the redirect to work and produce the correct override.
  5. This would be a great utility to have in the library. You could add a parameter for the progress bar so that it could be general to notebook progress bars too (if needed)

EDIT: I forget to add file=sys.stdout, dynamic_ncols=True, that solved 4.

Here's an example of the updated example with fixes for several of the points above:

from contextlib import contextmanager, redirect_stdout, redirect_stderr
import sys

class DummyTqdmFile(object):
    """Dummy file-like that will write to tqdm"""
    __slots__ = ("file", "progress")
    
    def __init__(self, file, progress):
        self.file = file
        self.progress = progress

    def write(self, x):
        # Avoid print() second call (useless \n)
        if len(x.rstrip()) > 0:
            self.progress.write(x.strip(), file=self.file)

    def flush(self):
        return getattr(self.file, "flush", lambda: None)()

# All Python versions:
def tqdm_redirect(progress):
    orig_out_err = sys.stdout, sys.stderr
    try:
        sys.stdout = DummyTqdmFile(sys.stdout, progress)
        sys.stderr = DummyTqdmFile(sys.stderr, progress)
        yield orig_out_err[0]
    # Always restore sys.stdout/err if necessary
    finally:
        sys.stdout, sys.stderr = orig_out_err

# Python 3.5+ version:
@contextmanager
def tqdm_redirect(progress):
    orig_out = sys.stdout
    with redirect_stdout(DummyTqdmFile(sys.stdout, progress)), redirect_stderr(DummyTqdmFile(sys.stderr, progress)):
        yield orig_out

Note that the final progress bar covers up the prompt if leave is not set to False.

@casperdcl
Copy link
Sponsor Member

casperdcl commented Aug 23, 2018

technically shouldn't strip() either since write() commands in general don't

@chengs chengs mentioned this issue Nov 13, 2018
9 tasks
@casperdcl casperdcl self-assigned this Mar 30, 2019
@casperdcl casperdcl added p3-enhancement 🔥 Much new such feature question/docs ‽ Documentation clarification candidate to-review 🔍 Awaiting final confirmation labels Mar 30, 2019
@casperdcl
Copy link
Sponsor Member

is (5) solved by from tqdm.auto import tqdm?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p3-enhancement 🔥 Much new such feature question/docs ‽ Documentation clarification candidate to-review 🔍 Awaiting final confirmation
Projects
None yet
Development

No branches or pull requests

2 participants