Merge pull request #7988 from McSinyx/tabulate

Fix tabulate col size in case of empty cell
This commit is contained in:
Xavier Fernandez 2020-04-09 13:35:16 +02:00 committed by GitHub
commit ea9cb06c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 20 deletions

View File

@ -7,7 +7,6 @@ import json
import logging
from pip._vendor import six
from pip._vendor.six.moves import zip_longest
from pip._internal.cli import cmdoptions
from pip._internal.cli.req_command import IndexGroupCommand
@ -18,6 +17,7 @@ from pip._internal.self_outdated_check import make_link_collector
from pip._internal.utils.misc import (
dist_is_editable,
get_installed_distributions,
tabulate,
write_output,
)
from pip._internal.utils.packaging import get_installer
@ -241,24 +241,6 @@ class ListCommand(IndexGroupCommand):
write_output(val)
def tabulate(vals):
# From pfmoore on GitHub:
# https://github.com/pypa/pip/issues/3651#issuecomment-216932564
assert len(vals) > 0
sizes = [0] * max(len(x) for x in vals)
for row in vals:
sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)]
result = []
for row in vals:
display = " ".join([str(c).ljust(s) if c is not None else ''
for s, c in zip_longest(sizes, row)])
result.append(display)
return result, sizes
def format_for_columns(pkgs, options):
"""
Convert the package data into something usable

View File

@ -22,7 +22,7 @@ from pip._vendor import pkg_resources
# why we ignore the type on this import.
from pip._vendor.retrying import retry # type: ignore
from pip._vendor.six import PY2, text_type
from pip._vendor.six.moves import input, zip_longest
from pip._vendor.six.moves import input, map, zip_longest
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote
@ -275,6 +275,21 @@ def format_size(bytes):
return '{} bytes'.format(int(bytes))
def tabulate(rows):
# type: (Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]]
"""Return a list of formatted rows and a list of column sizes.
For example::
>>> tabulate([['foobar', 2000], [0xdeadbeef]])
(['foobar 2000', '3735928559'], [10, 4])
"""
rows = [tuple(map(str, row)) for row in rows]
sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue='')]
table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows]
return table, sizes
def is_installable_dir(path):
# type: (str) -> bool
"""Is path is a directory containing setup.py or pyproject.toml?

View File

@ -50,6 +50,7 @@ from pip._internal.utils.misc import (
rmtree_errorhandler,
split_auth_from_netloc,
split_auth_netloc_from_url,
tabulate,
)
from pip._internal.utils.setuptools_build import make_setuptools_shim_args
@ -970,3 +971,20 @@ def test_is_console_interactive(monkeypatch, isatty, no_stdin, expected):
])
def test_format_size(size, expected):
assert format_size(size) == expected
@pytest.mark.parametrize(
('rows', 'table', 'sizes'),
[([], [], []),
([('I?', 'version', 'sdist', 'wheel'),
('', '1.18.2', 'zip', 'cp38-cp38m-win_amd64'),
('v', 1.18, 'zip')],
['I? version sdist wheel',
' 1.18.2 zip cp38-cp38m-win_amd64',
'v 1.18 zip'],
[2, 7, 5, 20]),
([('I?', 'version', 'sdist', 'wheel'), (), ('v', '1.18.1', 'zip')],
['I? version sdist wheel', '', 'v 1.18.1 zip'],
[2, 7, 5, 5])])
def test_tabulate(rows, table, sizes):
assert tabulate(rows) == (table, sizes)