Skip to content

Commit b5858b4

Browse files
committed
Update legacy tests for corrected double-finish semantics
The monitor_progress goldens and the colors test encoded the duplicate final render caused by the double finish() from the iterator plus the context manager; finish() is idempotent now so the bar renders its final state once. The multibar example finishes its bars explicitly since the context manager now genuinely waits for completion. The transfer-speed golden for zero progress uses the regular format. Also: FORCE_COLOR handling returns directly instead of break (avoids an unrecordable coverage arc), SIGWINCH dispatch and reverse-order unwrapping gained coverage, and the repro_bugs.py scratch battery is replaced by the regression tests.
1 parent 7e4f1b9 commit b5858b4

9 files changed

Lines changed: 29 additions & 21 deletions

File tree

‎examples.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ def do_something(bar):
8585
# Increment one of the progress bars at random
8686
multibar[bar_label].increment()
8787

88+
# The multibar context manager waits for all bars to finish on
89+
# exit, so finish them explicitly
90+
for bar_label in bar_labels:
91+
multibar[bar_label].finish()
92+
8893

8994
@example
9095
def multiple_bars_line_offset_example() -> None:

‎progressbar/env.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ def from_env(cls) -> ColorSupport:
9696
# Generic truthy flags such as `FORCE_COLOR=1` enable
9797
# color support but don't specify the depth; assume full
9898
# color support analogous to the Jupyter handling above.
99-
support = cls.XTERM_TRUECOLOR
100-
break
99+
return cls.XTERM_TRUECOLOR
101100

102101
return support
103102

‎progressbar/multi.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,10 @@ def stop(self, timeout: float | None = None):
386386
self.join(timeout=timeout)
387387

388388
def get_sorted_bars(self):
389-
# Snapshot the values so other threads can add or remove bars
390-
# while we are sorting/rendering
389+
# sorted() materializes the values in a single pass, so other
390+
# threads can add or remove bars while we are rendering
391391
return sorted(
392-
list(self.values()),
392+
self.values(),
393393
key=self.sort_keyfunc,
394394
reverse=self.sort_reverse,
395395
)

‎tests/test_color.py‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,7 @@ def test_hsl_interpolate_preserves_components() -> None:
418418
start_color = terminal.HSL(0, 100, 25)
419419
end_color = terminal.HSL(0, 100, 75)
420420

421-
assert start_color.interpolate(end_color, 0.5) == terminal.HSL(
422-
0, 100, 50
423-
)
421+
assert start_color.interpolate(end_color, 0.5) == terminal.HSL(0, 100, 50)
424422

425423

426424
@pytest.mark.parametrize('value', ['1', 'true', 'on'])

‎tests/test_monitor_progress.py‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ def test_line_breaks(testdir) -> None:
200200
' 60%|################################ |',
201201
' 80%|########################################### |',
202202
'100%|######################################################|',
203-
'100%|######################################################|',
204203
),
205204
)
206205

@@ -224,8 +223,6 @@ def test_no_line_breaks(testdir) -> None:
224223
' 60%|################################ |',
225224
' 80%|########################################### |',
226225
'100%|######################################################|',
227-
'',
228-
'100%|######################################################|',
229226
]
230227

231228

@@ -248,8 +245,6 @@ def test_percentage_label_bar(testdir) -> None:
248245
'|###########################60%#### |',
249246
'|###########################80%################ |',
250247
'|###########################100%###########################|',
251-
'',
252-
'|###########################100%###########################|',
253248
]
254249

255250

@@ -272,8 +267,6 @@ def test_granular_bar(testdir) -> None:
272267
'|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOo |',
273268
'|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO. |',
274269
'|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO|',
275-
'',
276-
'|OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO|',
277270
]
278271

279272

@@ -287,10 +280,10 @@ def test_colors(testdir) -> None:
287280
testdir.makepyfile(_create_script(enable_colors=True, **kwargs)),
288281
)
289282
pprint.pprint(result.stderr.lines, width=70)
290-
assert result.stderr.lines == ['\x1b[92mgreen\x1b[0m'] * 3
283+
assert result.stderr.lines == ['\x1b[92mgreen\x1b[0m'] * 2
291284

292285
result = testdir.runpython(
293286
testdir.makepyfile(_create_script(enable_colors=False, **kwargs)),
294287
)
295288
pprint.pprint(result.stderr.lines, width=70)
296-
assert result.stderr.lines == ['green'] * 3
289+
assert result.stderr.lines == ['green'] * 2

‎tests/test_progressbar.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ def test_sigwinch_restored_with_overlapping_bars() -> None:
160160
bar2 = progressbar.ProgressBar(max_value=5, fd=io.StringIO())
161161
bar2.start()
162162

163+
# A resize signal is dispatched to all live bars
164+
signal.raise_signal(signal.SIGWINCH)
165+
assert isinstance(bar1.term_width, int)
166+
assert isinstance(bar2.term_width, int)
167+
163168
bar1.update(5)
164169
bar1.finish()
165170
bar2.update(5)

‎tests/test_speed.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
@pytest.mark.parametrize(
77
'total_seconds_elapsed,value,expected',
88
[
9-
(1, 0, ' 0.0 s/B'),
9+
# Zero progress means no data yet, so the regular format is used
10+
# instead of the inverse (seconds per unit) format
11+
(1, 0, ' 0.0 B/s'),
1012
(1, 0.01, '100.0 s/B'),
1113
(1, 0.1, ' 0.1 B/s'),
1214
(1, 1, ' 1.0 B/s'),

‎tests/test_utils.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ def test_stream_wrapper_unwrap_restores_excepthook() -> None:
137137
assert sys.excepthook == wrapper.excepthook
138138
wrapper.unwrap_stderr()
139139
assert sys.excepthook is hook_before
140+
141+
# Same in reverse order: stderr first, then stdout
142+
wrapper.wrap_stdout()
143+
wrapper.wrap_stderr()
144+
wrapper.unwrap_stderr()
145+
assert sys.excepthook == wrapper.excepthook
146+
wrapper.unwrap_stdout()
147+
assert sys.excepthook is hook_before
140148
finally:
141149
sys.excepthook = wrapper.original_excepthook
142150
sys.stdout = wrapper.original_stdout

‎tests/test_windows.py‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,5 @@ def fake_read_console_input(handle, buffer, length, events_read):
111111
events_read._obj.value = 1
112112
return 1
113113

114-
monkeypatch.setattr(
115-
windows, '_ReadConsoleInput', fake_read_console_input
116-
)
114+
monkeypatch.setattr(windows, '_ReadConsoleInput', fake_read_console_input)
117115
assert windows.getch() == 'a'

0 commit comments

Comments
 (0)