-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
First of all, thanks to all contributors, your work is much appreciated!
The right aligned percent progress looks great in the terminal, but sometimes the nice alignment is marred by verbose (-vv+) output.
Here is an example of the current alignment:
tests/implementations/test_hdfs.py::TestUPathHDFS::test_fsspec_compat SKIPPED (Possible installation
problem, error: Unable to load libhdfs: ./libhdfs.so: cannot open shared object file: No such file
or directory) [ 49%]
tests/test_core.py::TestUPathMock::test_instance_type <- upath/tests/cases.py PASSED [ 50%]
I was thinking that it would be nice to keep the percentages aligned even for multiline output. It struck me that this could be done by always padding to the rounded up next multiple of terminal width. I think this would make the output in these situations look much nicer.
Here is an example of how the output could be improved:
tests/implementations/test_hdfs.py::TestUPathHDFS::test_fsspec_compat SKIPPED (Possible
installation problem, error: Unable to load libhdfs: ./libhdfs.so: cannot open shared object
file: No such file or directory) [ 49%]
tests/test_core.py::TestUPathMock::test_instance_type <- upath/tests/cases.py PASSED [ 50%]
I wrote a function using python's built-in text wrap module that should be easy to drop in to accomplish this, along with a test.
import textwrap
_DEFAULT_PROGRESS_MARGIN_SIZE = 7
def _pad_wrap_message(
msg: str,
width: int,
margin: int = _DEFAULT_PROGRESS_MARGIN_SIZE,
line_sep: str="",
):
"""Wrap and pad message with margin for progress info."""
wrapped = textwrap.wrap(msg, width - margin, drop_whitespace=True)
out_lines = [line.ljust(width) for line in wrapped[:-1]]
out_lines.append(wrapped[-1].ljust(width - margin))
msg_out = line_sep.join(out_lines)
return msg_out
def test_pad_wrap_message():
width = 80
count = 200
msg = "b"
progress = " [100%]"
margin = len(progress)
result = _pad_wrap_message(msg * count, width=width, line_sep="\n")
assert result.count(msg) == count
lines = (result + progress).split("\n")
expected_lines = (len(msg) * count) // (width - margin) + 1
assert len(lines) == expected_lines
expected_len = expected_lines * (width + 1) - margin - 1
assert len(result) == expected_len
for _ in lines:
assert len(_) == width
assert _[-len(progress)] == " " # space before progress columnIf this approach is acceptable, I can submit a PR.