add tests and redirection example

This commit is contained in:
Casper da Costa-Luis 2017-05-29 01:19:46 +01:00
parent b931073be2
commit 204fc43d8e
No known key found for this signature in database
GPG Key ID: 986B408043AE090D
2 changed files with 106 additions and 0 deletions

View File

@ -0,0 +1,60 @@
"""Redirecting writing
If using a library that can print messages to the console, editing the library
by replacing `print()` with `tqdm.write()` may not be desirable.
In that case, redirecting `sys.stdout` to `tqdm.write()` is an option.
To redirect `sys.stdout`, create a file-like class that will write
any input string to `tqdm.write()`, and supply the arguments
`file=sys.stdout, dynamic_ncols=True`.
A reusable canonical example is given below:
"""
from __future__ import print_function
from time import sleep
import contextlib
import sys
from tqdm import tqdm
class DummyTqdmFile(object):
"""Dummy file-like that will write to tqdm"""
file = None
def __init__(self, file):
self.file = file
def write(self, x):
# Avoid print() second call (useless \n)
if len(x.rstrip()) > 0:
tqdm.write(x, file=self.file)
@contextlib.contextmanager
def stdout_redirect_to_tqdm():
save_stdout = sys.stdout
try:
sys.stdout = DummyTqdmFile(sys.stdout)
yield save_stdout
# Relay exceptions
except Exception as exc:
raise exc
# Always restore sys.stdout if necessary
finally:
sys.stdout = save_stdout
def blabla():
print("Foo blabla")
# Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)
with stdout_redirect_to_tqdm() as save_stdout:
# tqdm call need to specify sys.stdout, not sys.stderr (default)
# and dynamic_ncols=True to autodetect console width
for _ in tqdm(range(3), file=save_stdout, dynamic_ncols=True):
blabla()
sleep(.5)
# After the `with`, printing is restored
print('Done!')

View File

@ -11,6 +11,7 @@ from nose import with_setup
from nose.plugins.skip import SkipTest
from nose.tools import assert_raises
from time import sleep
from contextlib import contextmanager
from tqdm import tqdm
from tqdm import trange
@ -1549,3 +1550,48 @@ def test_postfix():
out3 = out3[1:-1].split(', ')[3:]
assert out3 == expected_order
class DummyTqdmFile(object):
"""Dummy file-like that will write to tqdm"""
file = None
def __init__(self, file):
self.file = file
def write(self, x):
# Avoid print() second call (useless \n)
if len(x.rstrip()) > 0:
tqdm.write(x, file=self.file)
@contextmanager
def stdout_stderr_redirect_to_tqdm(tqdm_file=sys.stderr):
save_stdout = sys.stdout
save_stderr = sys.stderr
try:
sys.stdout = DummyTqdmFile(tqdm_file)
sys.stderr = DummyTqdmFile(tqdm_file)
yield save_stdout, save_stderr
# Relay exceptions
except Exception as exc:
raise exc
# Always restore sys.stdout if necessary
finally:
sys.stdout = save_stdout
sys.stderr = save_stderr
@with_setup(pretest, posttest)
def test_file_redirection():
"""Test redirection of output"""
with closing(StringIO()) as our_file:
# Redirect stdout to tqdm.write()
with stdout_stderr_redirect_to_tqdm(tqdm_file=our_file):
# as (stdout, stderr)
for _ in trange(3):
print("Such fun")
res = our_file.getvalue()
assert res.count("Such fun\n") == 3
assert "0/3" in res
assert "3/3" in res