Added proper support for non-terminal output thanks to @paulo-raca · Djailla/python-progressbar@dbca8aa · GitHub
Skip to content

Commit dbca8aa

Browse files
committed
Added proper support for non-terminal output thanks to @paulo-raca
1 parent 17e15b3 commit dbca8aa

9 files changed

Lines changed: 190 additions & 110 deletions

File tree

examples.py

Lines changed: 1 addition & 1 deletion

progressbar/bar.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,25 @@ def __init__(self, fd=sys.stderr, is_terminal=None, line_breaks=None, enable_col
6969
# Check if this is an interactive terminal
7070
if is_terminal is None:
7171
is_terminal = utils.env_flag('PROGRESSBAR_IS_TERMINAL', None)
72-
if is_terminal is None:
72+
if is_terminal is None: # pragma: no cover
7373
try:
7474
is_terminal = fd.isatty()
75-
except:
75+
except Exception:
7676
is_terminal = False
7777
self.is_terminal = is_terminal
7878

79-
# Check if it should overwrite the current line (suitable for iteractive terminals)
80-
# or write line breaks (suitable for log files)
79+
# Check if it should overwrite the current line (suitable for
80+
# iteractive terminals) or write line breaks (suitable for log files)
8181
if line_breaks is None:
82-
line_breaks = utils.env_flag('PROGRESSBAR_LINE_BREAKS', not is_terminal)
82+
line_breaks = utils.env_flag('PROGRESSBAR_LINE_BREAKS', not
83+
is_terminal)
8384
self.line_breaks = line_breaks
8485

85-
# Check if ANSI escape characters are enabled (suitable for iteractive terminals),
86-
# or should be stripped off (suitable for log files)
86+
# Check if ANSI escape characters are enabled (suitable for iteractive
87+
# terminals), or should be stripped off (suitable for log files)
8788
if enable_colors is None:
88-
enable_colors = utils.env_flag('PROGRESSBAR_ENABLE_COLORS', is_terminal)
89+
enable_colors = utils.env_flag('PROGRESSBAR_ENABLE_COLORS',
90+
is_terminal)
8991
self.enable_colors = enable_colors
9092

9193
ProgressBarMixinBase.__init__(self, **kwargs)

progressbar/utils.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,14 @@ def len_color(value):
5858

5959
def env_flag(name, default=None):
6060
'''
61-
Accepts environt variables formatted as y/n, yes/no, 1/0, true/false, on/off, and returns it as a boolean
61+
Accepts environt variables formatted as y/n, yes/no, 1/0, true/false,
62+
on/off, and returns it as a boolean
6263
63-
If the environt variable is not defined, or has an unknown value, returns `default`
64+
If the environt variable is not defined, or has an unknown value, returns
65+
`default`
6466
'''
6567
try:
66-
return bool(distutils.util.strtobool(os.environ.get(name, "")))
68+
return bool(distutils.util.strtobool(os.environ.get(name, '')))
6769
except ValueError:
6870
return default
6971

pytest.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ norecursedirs =
2222

2323
filterwarnings =
2424
ignore::DeprecationWarning
25+
26+
markers =
27+
no_freezegun: Disable automatic freezegun wrapping

tests/conftest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ def small_interval(monkeypatch):
2929

3030
@pytest.fixture(autouse=True)
3131
def sleep_faster(monkeypatch):
32-
with freezegun.freeze_time() as fake_time:
32+
freeze_time = freezegun.freeze_time()
33+
with freeze_time as fake_time:
3334
monkeypatch.setattr('time.sleep', fake_time.tick)
3435
monkeypatch.setattr('timeit.default_timer', time.time)
35-
yield
36+
yield freeze_time

tests/test_custom_widgets.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def test_crazy_file_transfer_speed_widget():
3434
p.finish()
3535

3636

37-
def test_dynamic_message_widget():
37+
def test_variable_widget_widget():
3838
widgets = [
3939
' [', progressbar.Timer(), '] ',
4040
progressbar.Bar(),
@@ -49,6 +49,7 @@ def test_dynamic_message_widget():
4949
p = progressbar.ProgressBar(widgets=widgets, max_value=1000,
5050
variables=dict(predefined='predefined'))
5151
p.start()
52+
print('time', time, time.sleep)
5253
for i in range(0, 200, 5):
5354
time.sleep(0.1)
5455
p.update(i + 1, loss=.5, text='spam', error=1)

tests/test_monitor_progress.py

Lines changed: 127 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,54 @@
33
pytest_plugins = 'pytester'
44

55

6+
SCRIPT = '''
7+
import time
8+
import timeit
9+
import freezegun
10+
import progressbar
11+
12+
13+
with freezegun.freeze_time() as fake_time:
14+
timeit.default_timer = time.time
15+
with progressbar.ProgressBar(widgets={widgets}, **{kwargs!r}) as bar:
16+
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
17+
for i in bar({items}):
18+
{loop_code}
19+
'''
20+
21+
22+
def _create_script(widgets=None, items=list(range(9)),
23+
loop_code='fake_time.tick(1)', term_width=60,
24+
**kwargs):
25+
kwargs['term_width'] = term_width
26+
27+
# Reindent the loop code
28+
indent = '\n '
29+
loop_code = loop_code.strip('\n').split('\n')
30+
dedent = len(loop_code[0]) - len(loop_code[0].lstrip())
31+
for i, line in enumerate(loop_code):
32+
loop_code[i] = line[dedent:]
33+
34+
script = SCRIPT.format(
35+
items=items,
36+
widgets=widgets,
37+
kwargs=kwargs,
38+
loop_code=indent.join(loop_code),
39+
)
40+
print(script)
41+
return script
42+
43+
644
def test_list_example(testdir):
745
''' Run the simple example code in a python subprocess and then compare its
846
stderr to what we expect to see from it. We run it in a subprocess to
947
best capture its stderr. We expect to see match_lines in order in the
1048
output. This test is just a sanity check to ensure that the progress
1149
bar progresses from 1 to 10, it does not make sure that the '''
1250

13-
v = testdir.makepyfile('''
14-
import time
15-
import timeit
16-
import freezegun
17-
import progressbar
18-
19-
with freezegun.freeze_time() as fake_time:
20-
timeit.default_timer = time.time
21-
bar = progressbar.ProgressBar(term_width=65)
22-
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
23-
for i in bar(list(range(9))):
24-
fake_time.tick(1)
25-
''')
26-
result = testdir.runpython(v)
51+
result = testdir.runpython(testdir.makepyfile(_create_script(
52+
term_width=65,
53+
)))
2754
result.stderr.lines = [l.rstrip() for l in result.stderr.lines
2855
if l.strip()]
2956
pprint.pprint(result.stderr.lines, width=70)
@@ -47,21 +74,9 @@ def test_generator_example(testdir):
4774
best capture its stderr. We expect to see match_lines in order in the
4875
output. This test is just a sanity check to ensure that the progress
4976
bar progresses from 1 to 10, it does not make sure that the '''
50-
51-
v = testdir.makepyfile('''
52-
import time
53-
import timeit
54-
import freezegun
55-
import progressbar
56-
57-
with freezegun.freeze_time() as fake_time:
58-
timeit.default_timer = time.time
59-
bar = progressbar.ProgressBar(term_width=60)
60-
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
61-
for i in bar(iter(range(9))):
62-
fake_time.tick(1)
63-
''')
64-
result = testdir.runpython(v)
77+
result = testdir.runpython(testdir.makepyfile(_create_script(
78+
items='iter(range(9))',
79+
)))
6580
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
6681
pprint.pprint(result.stderr.lines, width=70)
6782

@@ -79,23 +94,16 @@ def test_rapid_updates(testdir):
7994
this is meant to test that the progressbar progresses normally with
8095
this sample code, since there were issues with it in the past '''
8196

82-
v = testdir.makepyfile('''
83-
import time
84-
import timeit
85-
import freezegun
86-
import progressbar
87-
88-
with freezegun.freeze_time() as fake_time:
89-
timeit.default_timer = time.time
90-
bar = progressbar.ProgressBar(term_width=60)
91-
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
92-
for i in bar(range(10)):
93-
if i < 5:
94-
fake_time.tick(1)
95-
else:
96-
fake_time.tick(2)
97-
''')
98-
result = testdir.runpython(v)
97+
result = testdir.runpython(testdir.makepyfile(_create_script(
98+
term_width=60,
99+
items=list(range(10)),
100+
loop_code='''
101+
if i < 5:
102+
fake_time.tick(1)
103+
else:
104+
fake_time.tick(2)
105+
'''
106+
)))
99107
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
100108
pprint.pprint(result.stderr.lines, width=70)
101109
result.stderr.fnmatch_lines([
@@ -113,52 +121,11 @@ def test_rapid_updates(testdir):
113121
])
114122

115123

116-
def test_context_wrapper(testdir):
117-
v = testdir.makepyfile('''
118-
import time
119-
import timeit
120-
import freezegun
121-
import progressbar
122-
123-
with freezegun.freeze_time() as fake_time:
124-
timeit.default_timer = time.time
125-
with progressbar.ProgressBar(term_width=60) as bar:
126-
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
127-
for _ in bar(list(range(5))):
128-
fake_time.tick(1)
129-
''')
130-
131-
result = testdir.runpython(v)
132-
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
133-
pprint.pprint(result.stderr.lines, width=70)
134-
result.stderr.fnmatch_lines([
135-
'N/A% (0 of 5) | | Elapsed Time: ?:00:00 ETA: --:--:--',
136-
' 20% (1 of 5) |# | Elapsed Time: ?:00:01 ETA: ?:00:04',
137-
' 40% (2 of 5) |## | Elapsed Time: ?:00:02 ETA: ?:00:03',
138-
' 60% (3 of 5) |#### | Elapsed Time: ?:00:03 ETA: ?:00:02',
139-
' 80% (4 of 5) |##### | Elapsed Time: ?:00:04 ETA: ?:00:01',
140-
'100% (5 of 5) |#######| Elapsed Time: ?:00:05 Time: ?:00:05',
141-
])
142-
143-
144124
def test_non_timed(testdir):
145-
v = testdir.makepyfile('''
146-
import time
147-
import timeit
148-
import freezegun
149-
import progressbar
150-
151-
widgets = [progressbar.Percentage(), progressbar.Bar()]
152-
153-
with freezegun.freeze_time() as fake_time:
154-
timeit.default_timer = time.time
155-
with progressbar.ProgressBar(widgets=widgets, term_width=60) as bar:
156-
bar._MINIMUM_UPDATE_INTERVAL = 1e-9
157-
for _ in bar(list(range(5))):
158-
fake_time.tick(1)
159-
''')
160-
161-
result = testdir.runpython(v)
125+
result = testdir.runpython(testdir.makepyfile(_create_script(
126+
widgets='[progressbar.Percentage(), progressbar.Bar()]',
127+
items=list(range(5)),
128+
)))
162129
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
163130
pprint.pprint(result.stderr.lines, width=70)
164131
result.stderr.fnmatch_lines([
@@ -169,3 +136,72 @@ def test_non_timed(testdir):
169136
' 80%|########################################### |',
170137
'100%|######################################################|',
171138
])
139+
140+
141+
def test_line_breaks(testdir):
142+
result = testdir.runpython(testdir.makepyfile(_create_script(
143+
widgets='[progressbar.Percentage(), progressbar.Bar()]',
144+
line_breaks=True,
145+
items=list(range(5)),
146+
)))
147+
pprint.pprint(result.stderr.str(), width=70)
148+
assert result.stderr.str() == u'\n'.join((
149+
u'N/A%| |',
150+
u' 20%|########## |',
151+
u' 40%|##################### |',
152+
u' 60%|################################ |',
153+
u' 80%|########################################### |',
154+
u'100%|######################################################|',
155+
u'100%|######################################################|',
156+
))
157+
158+
159+
def test_no_line_breaks(testdir):
160+
result = testdir.runpython(testdir.makepyfile(_create_script(
161+
widgets='[progressbar.Percentage(), progressbar.Bar()]',
162+
line_breaks=False,
163+
items=list(range(5)),
164+
)))
165+
pprint.pprint(result.stderr.str(), width=70)
166+
assert result.stderr.str() == u'\n'.join((
167+
u'',
168+
u' ',
169+
u'',
170+
u'N/A%| |',
171+
u' ',
172+
u'',
173+
u' 20%|########## |',
174+
u' ',
175+
u'',
176+
u' 40%|##################### |',
177+
u' ',
178+
u'',
179+
u' 60%|################################ |',
180+
u' ',
181+
u'',
182+
u' 80%|########################################### |',
183+
u' ',
184+
u'',
185+
u'100%|######################################################|',
186+
u'',
187+
u' ',
188+
u'',
189+
u'100%|######################################################|'
190+
))
191+
192+
193+
def test_colors(testdir):
194+
kwargs = dict(
195+
items=range(1),
196+
widgets=['\033[92mgreen\033[0m'],
197+
)
198+
199+
result = testdir.runpython(testdir.makepyfile(_create_script(
200+
enable_colors=True, **kwargs)))
201+
pprint.pprint(result.stderr.lines, width=70)
202+
assert result.stderr.lines == [u'\x1b[92mgreen\x1b[0m'] * 3
203+
204+
result = testdir.runpython(testdir.makepyfile(_create_script(
205+
enable_colors=False, **kwargs)))
206+
pprint.pprint(result.stderr.lines, width=70)
207+
assert result.stderr.lines == [u'green'] * 3

tests/test_progressbar.py

Lines changed: 11 additions & 4 deletions

0 commit comments

Comments
 (0)