Skip to content

Commit 308096a

Browse files
committed
Merge branch 'release/3.54.0'
2 parents cb73782 + 36f59c1 commit 308096a

File tree

8 files changed

+118
-18
lines changed

8 files changed

+118
-18
lines changed

.github/workflows/main.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: tox
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
timeout-minutes: 10
12+
strategy:
13+
matrix:
14+
python-version: [3.6, 3.7, 3.8, 3.9]
15+
16+
steps:
17+
- uses: actions/checkout@v2
18+
- name: Set up Python ${{ matrix.python-version }}
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install tox tox-gh-actions
26+
- name: Test with tox
27+
run: tox

README.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
Text progress bar library for Python.
33
##############################################################################
44

5-
Travis status:
5+
Build status:
66

7-
.. image:: https://travis-ci.org/WoLpH/python-progressbar.svg?branch=master
8-
:target: https://travis-ci.org/WoLpH/python-progressbar
7+
.. image:: https://github.com/WoLpH/python-progressbar/actions/workflows/main.yml/badge.svg
8+
:alt: python-progressbar test status
9+
:target: https://github.com/WoLpH/python-progressbar/actions
910

1011
Coverage:
1112

@@ -58,7 +59,9 @@ of widgets:
5859
- `FileTransferSpeed <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#FileTransferSpeed>`_
5960
- `FormatCustomText <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#FormatCustomText>`_
6061
- `FormatLabel <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#FormatLabel>`_
62+
- `FormatLabelBar <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#FormatLabel>`_
6163
- `Percentage <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#Percentage>`_
64+
- `PercentageLabelBar <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#PercentageLabelBar>`_
6265
- `ReverseBar <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#ReverseBar>`_
6366
- `RotatingMarker <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#RotatingMarker>`_
6467
- `SimpleProgress <http://progressbar-2.readthedocs.io/en/latest/_modules/progressbar/widgets.html#SimpleProgress>`_

examples.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ def multi_progress_bar_example(left=True):
177177
time.sleep(0.02)
178178

179179

180+
@example
181+
def percentage_label_bar_example():
182+
widgets = [progressbar.PercentageLabelBar()]
183+
bar = progressbar.ProgressBar(widgets=widgets, max_value=10).start()
184+
for i in range(10):
185+
# do something
186+
time.sleep(0.1)
187+
bar.update(i + 1)
188+
bar.finish()
189+
190+
180191
@example
181192
def file_transfer_example():
182193
widgets = [

progressbar/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
long running operations.
2020
'''.strip().split())
2121
__email__ = 'wolph@wol.ph'
22-
__version__ = '3.53.3'
22+
__version__ = '3.54.0'
2323
__license__ = 'BSD'
2424
__copyright__ = 'Copyright 2015 Rick van Hattem (Wolph)'
2525
__url__ = 'https://github.com/WoLpH/python-progressbar'

progressbar/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
VariableMixin,
2727
MultiRangeBar,
2828
MultiProgressBar,
29+
FormatLabelBar,
30+
PercentageLabelBar,
2931
Variable,
3032
DynamicMessage,
3133
FormatCustomText,
@@ -72,6 +74,8 @@
7274
'VariableMixin',
7375
'MultiRangeBar',
7476
'MultiProgressBar',
77+
'FormatLabelBar',
78+
'PercentageLabelBar',
7579
'Variable',
7680
'DynamicMessage',
7781
'FormatCustomText',

progressbar/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ def __cmp__(self, other): # pragma: no cover
1515

1616
class UnknownLength(six.with_metaclass(FalseMeta, object)):
1717
pass
18+
19+
20+
class Undefined(six.with_metaclass(FalseMeta, object)):
21+
pass

progressbar/widgets.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,19 @@ def __init__(self, format, new_style=False, **kwargs):
114114
self.new_style = new_style
115115
self.format = format
116116

117+
def get_format(self, progress, data, format=None):
118+
return format or self.format
119+
117120
def __call__(self, progress, data, format=None):
118121
'''Formats the widget into a string'''
122+
format = self.get_format(progress, data, format)
119123
try:
120124
if self.new_style:
121-
return (format or self.format).format(**data)
125+
return format.format(**data)
122126
else:
123-
return (format or self.format) % data
127+
return format % data
124128
except (TypeError, KeyError):
125-
print('Error while formatting %r' % self.format, file=sys.stderr)
129+
print('Error while formatting %r' % format, file=sys.stderr)
126130
pprint.pprint(data, stream=sys.stderr)
127131
raise
128132

@@ -628,17 +632,18 @@ def __call__(self, progress, data, format=None):
628632
class Percentage(FormatWidgetMixin, WidgetBase):
629633
'''Displays the current percentage as a number with a percent sign.'''
630634

631-
def __init__(self, format='%(percentage)3d%%', **kwargs):
635+
def __init__(self, format='%(percentage)3d%%', na='N/A%%', **kwargs):
636+
self.na = na
632637
FormatWidgetMixin.__init__(self, format=format, **kwargs)
633638
WidgetBase.__init__(self, format=format, **kwargs)
634639

635-
def __call__(self, progress, data, format=None):
640+
def get_format(self, progress, data, format=None):
636641
# If percentage is not available, display N/A%
637-
if 'percentage' in data and not data['percentage']:
638-
return FormatWidgetMixin.__call__(self, progress, data,
639-
format='N/A%%')
642+
percentage = data.get('percentage', base.Undefined)
643+
if not percentage and percentage != 0:
644+
return self.na
640645

641-
return FormatWidgetMixin.__call__(self, progress, data)
646+
return FormatWidgetMixin.get_format(self, progress, data, format)
642647

643648

644649
class SimpleProgress(FormatWidgetMixin, WidgetBase):
@@ -904,6 +909,32 @@ def get_values(self, progress, data):
904909
return ranges
905910

906911

912+
class FormatLabelBar(FormatLabel, Bar):
913+
'''A bar which has a formatted label in the center.'''
914+
def __init__(self, format, **kwargs):
915+
FormatLabel.__init__(self, format, **kwargs)
916+
Bar.__init__(self, **kwargs)
917+
918+
def __call__(self, progress, data, width, format=None):
919+
center = FormatLabel.__call__(self, progress, data, format=format)
920+
bar = Bar.__call__(self, progress, data, width)
921+
922+
# Aligns the center of the label to the center of the bar
923+
center_len = progress.custom_len(center)
924+
center_left = int((width - center_len) / 2)
925+
center_right = center_left + center_len
926+
return bar[:center_left] + center + bar[center_right:]
927+
928+
929+
class PercentageLabelBar(Percentage, FormatLabelBar):
930+
'''A bar which displays the current percentage in the center.'''
931+
# %3d adds an extra space that makes it look off-center
932+
# %2d keeps the label somewhat consistently in-place
933+
def __init__(self, format='%(percentage)2d%%', na='N/A%%', **kwargs):
934+
Percentage.__init__(self, format, na=na, **kwargs)
935+
FormatLabelBar.__init__(self, format, **kwargs)
936+
937+
907938
class Variable(FormatWidgetMixin, VariableMixin, WidgetBase):
908939
'''Displays a custom variable.'''
909940

tests/test_monitor_progress.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def test_list_example(testdir):
6565
if l.strip()]
6666
pprint.pprint(result.stderr.lines, width=70)
6767
result.stderr.fnmatch_lines([
68-
'N/A% (0 of 9) | | Elapsed Time: ?:00:00 ETA: --:--:--',
68+
' 0% (0 of 9) | | Elapsed Time: ?:00:00 ETA: --:--:--',
6969
' 11% (1 of 9) |# | Elapsed Time: ?:00:01 ETA: ?:00:08',
7070
' 22% (2 of 9) |## | Elapsed Time: ?:00:02 ETA: ?:00:07',
7171
' 33% (3 of 9) |#### | Elapsed Time: ?:00:03 ETA: ?:00:06',
@@ -117,7 +117,7 @@ def test_rapid_updates(testdir):
117117
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
118118
pprint.pprint(result.stderr.lines, width=70)
119119
result.stderr.fnmatch_lines([
120-
'N/A% (0 of 10) | | Elapsed Time: ?:00:00 ETA: --:--:--',
120+
' 0% (0 of 10) | | Elapsed Time: ?:00:00 ETA: --:--:--',
121121
' 10% (1 of 10) | | Elapsed Time: ?:00:01 ETA: ?:00:09',
122122
' 20% (2 of 10) |# | Elapsed Time: ?:00:02 ETA: ?:00:08',
123123
' 30% (3 of 10) |# | Elapsed Time: ?:00:03 ETA: ?:00:07',
@@ -139,7 +139,7 @@ def test_non_timed(testdir):
139139
result.stderr.lines = [l for l in result.stderr.lines if l.strip()]
140140
pprint.pprint(result.stderr.lines, width=70)
141141
result.stderr.fnmatch_lines([
142-
'N/A%| |',
142+
' 0%| |',
143143
' 20%|########## |',
144144
' 40%|##################### |',
145145
' 60%|################################ |',
@@ -156,7 +156,7 @@ def test_line_breaks(testdir):
156156
)))
157157
pprint.pprint(result.stderr.str(), width=70)
158158
assert result.stderr.str() == u'\n'.join((
159-
u'N/A%| |',
159+
u' 0%| |',
160160
u' 20%|########## |',
161161
u' 40%|##################### |',
162162
u' 60%|################################ |',
@@ -175,7 +175,7 @@ def test_no_line_breaks(testdir):
175175
pprint.pprint(result.stderr.lines, width=70)
176176
assert result.stderr.lines == [
177177
u'',
178-
u'N/A%| |',
178+
u' 0%| |',
179179
u' 20%|########## |',
180180
u' 40%|##################### |',
181181
u' 60%|################################ |',
@@ -186,6 +186,26 @@ def test_no_line_breaks(testdir):
186186
]
187187

188188

189+
def test_percentage_label_bar(testdir):
190+
result = testdir.runpython(testdir.makepyfile(_create_script(
191+
widgets='[progressbar.PercentageLabelBar()]',
192+
line_breaks=False,
193+
items=list(range(5)),
194+
)))
195+
pprint.pprint(result.stderr.lines, width=70)
196+
assert result.stderr.lines == [
197+
u'',
198+
u'| 0% |',
199+
u'|########### 20% |',
200+
u'|####################### 40% |',
201+
u'|###########################60%#### |',
202+
u'|###########################80%################ |',
203+
u'|###########################100%###########################|',
204+
u'',
205+
u'|###########################100%###########################|'
206+
]
207+
208+
189209
def test_colors(testdir):
190210
kwargs = dict(
191211
items=range(1),

0 commit comments

Comments
 (0)