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

add bar colour option (notebook and std CLI) #1040

Merged
merged 5 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ Parameters
The screen height. If specified, hides nested bars outside this
bound. If unspecified, attempts to use environment height.
The fallback is 20.
* colour : str, optional
Bar colour (e.g. ``'green'``, ``'#00ff00'``).

Extra CLI Options
~~~~~~~~~~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions tqdm/completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ _tqdm(){
prv="${COMP_WORDS[COMP_CWORD - 1]}"

case ${prv} in
--bar_format|--buf_size|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor)
--bar_format|--buf_size|--colour|--comppath|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor)
# await user input
;;
"--log")
COMPREPLY=($(compgen -W 'CRITICAL FATAL ERROR WARN WARNING INFO DEBUG NOTSET' -- ${cur}))
;;
*)
COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur}))
COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur}))
;;
esac
}
Expand Down
12 changes: 12 additions & 0 deletions tqdm/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,16 @@ def display(self, msg=None, pos=None,
except AttributeError:
self.container.visible = False

@property
def colour(self):
if hasattr(self, 'container'):
return self.container.children[-2].style.bar_color

@colour.setter
def colour(self, bar_color):
if hasattr(self, 'container'):
self.container.children[-2].style.bar_color = bar_color

def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
# Setup default output
Expand All @@ -198,6 +208,7 @@ def __init__(self, *args, **kwargs):
'{bar}', '<bar/>')
# convert disable = None to False
kwargs['disable'] = bool(kwargs.get('disable', False))
colour = kwargs.pop('colour', None)
super(tqdm_notebook, self).__init__(*args, **kwargs)
if self.disable or not kwargs['gui']:
self.sp = lambda *_, **__: None
Expand All @@ -212,6 +223,7 @@ def __init__(self, *args, **kwargs):
self.container = self.status_printer(
self.fp, total, self.desc, self.ncols)
self.sp = self.display
self.colour = colour

# Print initial bar state
if not self.disable:
Expand Down
56 changes: 48 additions & 8 deletions tqdm/std.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,44 @@ class Bar(object):
ASCII = " 123456789#"
UTF = u" " + u''.join(map(_unich, range(0x258F, 0x2587, -1)))
BLANK = " "
COLOUR_RESET = '\x1b[0m'
COLOUR_RGB = '\x1b[38;2;%d;%d;%dm'
COLOURS = dict(BLACK='\x1b[30m', RED='\x1b[31m', GREEN='\x1b[32m',
YELLOW='\x1b[33m', BLUE='\x1b[34m', MAGENTA='\x1b[35m',
CYAN='\x1b[36m', WHITE='\x1b[37m')

def __init__(self, frac, default_len=10, charset=UTF):
def __init__(self, frac, default_len=10, charset=UTF, colour=None):
if not (0 <= frac <= 1):
warn("clamping frac to range [0, 1]", TqdmWarning, stacklevel=2)
frac = max(0, min(1, frac))
assert default_len > 0
self.frac = frac
self.default_len = default_len
self.charset = charset
self.colour = colour

@property
def colour(self):
return self._colour

@colour.setter
def colour(self, value):
if not value:
self._colour = None
return
try:
if value.upper() in self.COLOURS:
self._colour = self.COLOURS[value.upper()]
elif value[0] == '#' and len(value) == 7:
self._colour = self.COLOUR_RGB % tuple(
int(i, 16) for i in (value[1:3], value[3:5], value[5:7]))
else:
raise KeyError
except (KeyError, AttributeError):
warn("Unknown colour (%s); valid choices: [hex (#00ff00), %s]" % (
value, ", ".join(self.COLOURS)),
TqdmWarning, stacklevel=2)
self._colour = None

def __format__(self, format_spec):
if format_spec:
Expand Down Expand Up @@ -178,8 +207,10 @@ def __format__(self, format_spec):

# whitespace padding
if bar_length < N_BARS:
return bar + frac_bar + \
bar = bar + frac_bar + \
charset[0] * (N_BARS - bar_length - 1)
if self.colour:
return self.colour + bar + self.COLOUR_RESET
return bar


Expand Down Expand Up @@ -309,7 +340,7 @@ def print_status(s):
@staticmethod
def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
unit='it', unit_scale=False, rate=None, bar_format=None,
postfix=None, unit_divisor=1000, initial=0,
postfix=None, unit_divisor=1000, initial=0, colour=None,
**extra_kwargs):
"""
Return a string-based progress bar given some parameters
Expand Down Expand Up @@ -368,6 +399,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
[default: 1000], ignored unless `unit_scale` is True.
initial : int or float, optional
The initial counter value [default: 0].
colour : str, optional
Bar colour (e.g. `'green'`, `'#00ff00'`).

Returns
-------
Expand Down Expand Up @@ -442,6 +475,7 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
rate_noinv_fmt=rate_noinv_fmt, rate_inv=inv_rate,
rate_inv_fmt=rate_inv_fmt,
postfix=postfix, unit_divisor=unit_divisor,
colour=colour,
# plus more useful definitions
remaining=remaining_str, remaining_s=remaining,
l_bar=l_bar, r_bar=r_bar,
Expand Down Expand Up @@ -483,7 +517,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
frac,
max(1, ncols - disp_len(nobar))
if ncols else 10,
charset=Bar.ASCII if ascii is True else ascii or Bar.UTF)
charset=Bar.ASCII if ascii is True else ascii or Bar.UTF,
colour=colour)
if not _is_ascii(full_bar.charset) and _is_ascii(bar_format):
bar_format = _unicode(bar_format)
res = bar_format.format(bar=full_bar, **format_dict)
Expand All @@ -501,7 +536,8 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
0,
max(1, ncols - disp_len(nobar))
if ncols else 10,
charset=Bar.BLANK)
charset=Bar.BLANK,
colour=colour)
res = bar_format.format(bar=full_bar, **format_dict)
return disp_trim(res, ncols) if ncols else res
else:
Expand Down Expand Up @@ -802,7 +838,7 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
unit_scale=False, dynamic_ncols=False, smoothing=0.3,
bar_format=None, initial=0, position=None, postfix=None,
unit_divisor=1000, write_bytes=None, lock_args=None,
nrows=None,
nrows=None, colour=None,
gui=False, **kwargs):
"""
Parameters
Expand Down Expand Up @@ -908,6 +944,8 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
The screen height. If specified, hides nested bars outside this
bound. If unspecified, attempts to use environment height.
The fallback is 20.
colour : str, optional
Bar colour (e.g. `'green'`, `'#00ff00'`).
gui : bool, optional
WARNING: internal parameter - do not use.
Use tqdm.gui.tqdm(...) instead. If set, will attempt to use
Expand Down Expand Up @@ -1029,9 +1067,10 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True,
self.dynamic_ncols = dynamic_ncols
self.smoothing = smoothing
self.avg_time = None
self._time = time
self.bar_format = bar_format
self.postfix = None
self.colour = colour
self._time = time
if postfix:
try:
self.set_postfix(refresh=False, **postfix)
Expand Down Expand Up @@ -1453,7 +1492,8 @@ def format_dict(self):
unit_scale=self.unit_scale,
rate=1 / self.avg_time if self.avg_time else None,
bar_format=self.bar_format, postfix=self.postfix,
unit_divisor=self.unit_divisor, initial=self.initial)
unit_divisor=self.unit_divisor, initial=self.initial,
colour=self.colour)

def display(self, msg=None, pos=None):
"""
Expand Down
27 changes: 25 additions & 2 deletions tqdm/tests/tests_tqdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from tqdm import tqdm
from tqdm import trange
from tqdm import TqdmDeprecationWarning
from tqdm import TqdmDeprecationWarning, TqdmWarning
from tqdm.std import Bar
from tqdm.contrib import DummyTqdmFile

Expand Down Expand Up @@ -1895,7 +1895,7 @@ def test_float_progress():
with closing(StringIO()) as our_file:
with trange(10, total=9.6, file=our_file) as t:
with catch_warnings(record=True) as w:
simplefilter("always")
simplefilter("always", category=TqdmWarning)
for i in t:
if i < 9:
assert not w
Expand Down Expand Up @@ -1987,3 +1987,26 @@ def test_initial():
out = our_file.getvalue()
assert '10/19' in out
assert '19/19' in out


@with_setup(pretest, posttest)
def test_colour():
"""Test `colour`"""
with closing(StringIO()) as our_file:
for _ in tqdm(_range(9), file=our_file, colour="#beefed"):
pass
out = our_file.getvalue()
assert '\x1b[38;2;%d;%d;%dm' % (0xbe, 0xef, 0xed) in out

with catch_warnings(record=True) as w:
simplefilter("always", category=TqdmWarning)
with tqdm(total=1, file=our_file, colour="charm") as t:
assert w
t.update()
assert "Unknown colour" in str(w[-1].message)

with closing(StringIO()) as our_file2:
for _ in tqdm(_range(9), file=our_file2, colour="blue"):
pass
out = our_file2.getvalue()
assert '\x1b[34m' in out
9 changes: 8 additions & 1 deletion tqdm/tqdm.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.\" Automatically generated by Pandoc 1.19.2.1
.\" Automatically generated by Pandoc 1.19.2
.\"
.TH "TQDM" "1" "2015\-2020" "tqdm User Manuals" ""
.hy
Expand Down Expand Up @@ -227,6 +227,13 @@ The fallback is 20.
.RS
.RE
.TP
.B \-\-colour=\f[I]colour\f[]
str, optional.
Bar colour (e.g.
\f[C]\[aq]green\[aq]\f[], \f[C]\[aq]#00ff00\[aq]\f[]).
.RS
.RE
.TP
.B \-\-delim=\f[I]delim\f[]
chr, optional.
Delimiting character [default: \[aq]\\n\[aq]].
Expand Down