Switch the default for pip list to the columns format

This commit is contained in:
Donald Stufft 2017-03-19 22:08:31 -04:00
parent e6bfa12403
commit 0b1f521059
5 changed files with 97 additions and 78 deletions

2
news/3654.removal Normal file
View File

@ -0,0 +1,2 @@
Switch the default for ``pip list`` to the columns format, and deprecate the
legacy format.

2
news/3686.removal Normal file
View File

@ -0,0 +1,2 @@
Switch the default for ``pip list`` to the columns format, and deprecate the
legacy format.

View File

@ -15,7 +15,7 @@ from pip.exceptions import CommandError
from pip.index import PackageFinder from pip.index import PackageFinder
from pip.utils import ( from pip.utils import (
get_installed_distributions, dist_is_editable) get_installed_distributions, dist_is_editable)
from pip.utils.deprecation import RemovedInPip10Warning from pip.utils.deprecation import RemovedInPip11Warning
from pip.cmdoptions import make_option_group, index_group from pip.cmdoptions import make_option_group, index_group
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -78,9 +78,10 @@ class ListCommand(Command):
'--format', '--format',
action='store', action='store',
dest='list_format', dest='list_format',
default="columns",
choices=('legacy', 'columns', 'freeze', 'json'), choices=('legacy', 'columns', 'freeze', 'json'),
help="Select the output format among: legacy (default), columns, " help="Select the output format among: columns (default), freeze, "
"freeze or json.", "json, or legacy.",
) )
cmd_opts.add_option( cmd_opts.add_option(
@ -123,13 +124,11 @@ class ListCommand(Command):
) )
def run(self, options, args): def run(self, options, args):
if options.list_format is None: if options.list_format == "legacy":
warnings.warn( warnings.warn(
"The default format will switch to columns in the future. " "The legacy format has been deprecated and will be removed "
"You can use --format=(legacy|columns) (or define a " "in the future.",
"format=(legacy|columns) in your pip.conf under the [list] " RemovedInPip11Warning,
"section) to disable this warning.",
RemovedInPip10Warning,
) )
if options.outdated and options.uptodate: if options.outdated and options.uptodate:
@ -240,7 +239,7 @@ class ListCommand(Command):
logger.info("%s==%s", dist.project_name, dist.version) logger.info("%s==%s", dist.project_name, dist.version)
elif options.list_format == 'json': elif options.list_format == 'json':
logger.info(format_for_json(packages, options)) logger.info(format_for_json(packages, options))
else: # legacy elif options.list_format == "legacy":
for dist in packages: for dist in packages:
if options.outdated: if options.outdated:
logger.info(self.output_legacy_latest(dist)) logger.info(self.output_legacy_latest(dist))

View File

@ -2,26 +2,19 @@ import json
import os import os
import pytest import pytest
WARN_FORMAT = ("DEPRECATION: The default format will switch to columns in the "
"future. You can use --format=(legacy|columns) (or define a "
"format=(legacy|columns) in your pip.conf under the [list] "
"section) to disable this warning.")
def test_list_command(script, data): def test_list_command(script, data):
""" """
Test default behavior of list command without format specifier. Test default behavior of list command without format specifier.
A warning is expected.
""" """
script.pip( script.pip(
'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'install', '-f', data.find_links, '--no-index', 'simple==1.0',
'simple2==3.0', 'simple2==3.0',
) )
result = script.pip('list', expect_stderr=True) result = script.pip('list')
assert WARN_FORMAT in result.stderr, str(result) assert 'simple 1.0' in result.stdout, str(result)
assert 'simple (1.0)' in result.stdout, str(result) assert 'simple2 3.0' in result.stdout, str(result)
assert 'simple2 (3.0)' in result.stdout, str(result)
def test_columns_flag(script, data): def test_columns_flag(script, data):
@ -48,7 +41,7 @@ def test_legacy_format(script, data):
'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'install', '-f', data.find_links, '--no-index', 'simple==1.0',
'simple2==3.0', 'simple2==3.0',
) )
result = script.pip('list', '--format=legacy') result = script.pip('list', '--format=legacy', expect_stderr=True)
assert 'simple (1.0)' in result.stdout, str(result) assert 'simple (1.0)' in result.stdout, str(result)
assert 'simple2 (3.0)' in result.stdout, str(result) assert 'simple2 (3.0)' in result.stdout, str(result)
@ -61,7 +54,8 @@ def test_format_priority(script, data):
'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'install', '-f', data.find_links, '--no-index', 'simple==1.0',
'simple2==3.0', 'simple2==3.0',
) )
result = script.pip('list', '--format=columns', '--format=legacy') result = script.pip('list', '--format=columns', '--format=legacy',
expect_stderr=True)
assert 'simple (1.0)' in result.stdout, str(result) assert 'simple (1.0)' in result.stdout, str(result)
assert 'simple2 (3.0)' in result.stdout, str(result) assert 'simple2 (3.0)' in result.stdout, str(result)
assert 'simple 1.0' not in result.stdout, str(result) assert 'simple 1.0' not in result.stdout, str(result)
@ -82,8 +76,8 @@ def test_local_flag(script, data):
""" """
script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0')
result = script.pip('list', '--local', '--format=legacy') result = script.pip('list', '--local', '--format=json')
assert 'simple (1.0)' in result.stdout assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout)
def test_local_columns_flag(script, data): def test_local_columns_flag(script, data):
@ -105,7 +99,8 @@ def test_local_legacy_flag(script, data):
command. command.
""" """
script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0')
result = script.pip('list', '--local', '--format=legacy') result = script.pip('list', '--local', '--format=legacy',
expect_stderr=True)
assert 'simple (1.0)' in result.stdout assert 'simple (1.0)' in result.stdout
@ -118,9 +113,10 @@ def test_user_flag(script, data, virtualenv):
script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0')
script.pip('install', '-f', data.find_links, '--no-index', script.pip('install', '-f', data.find_links, '--no-index',
'--user', 'simple2==2.0') '--user', 'simple2==2.0')
result = script.pip('list', '--user', '--format=legacy') result = script.pip('list', '--user', '--format=json')
assert 'simple (1.0)' not in result.stdout assert {"name": "simple", "version": "1.0"} \
assert 'simple2 (2.0)' in result.stdout not in json.loads(result.stdout)
assert {"name": "simple2", "version": "2.0"} in json.loads(result.stdout)
def test_user_columns_flag(script, data, virtualenv): def test_user_columns_flag(script, data, virtualenv):
@ -148,7 +144,8 @@ def test_user_legacy(script, data, virtualenv):
script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0')
script.pip('install', '-f', data.find_links, '--no-index', script.pip('install', '-f', data.find_links, '--no-index',
'--user', 'simple2==2.0') '--user', 'simple2==2.0')
result = script.pip('list', '--user', '--format=legacy') result = script.pip('list', '--user', '--format=legacy',
expect_stderr=True)
assert 'simple (1.0)' not in result.stdout assert 'simple (1.0)' not in result.stdout
assert 'simple2 (2.0)' in result.stdout, str(result) assert 'simple2 (2.0)' in result.stdout, str(result)
@ -169,11 +166,13 @@ def test_uptodate_flag(script, data):
) )
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', '--uptodate', 'list', '-f', data.find_links, '--no-index', '--uptodate',
'--format=legacy', '--format=json',
) )
assert 'simple (1.0)' not in result.stdout # 3.0 is latest assert {"name": "simple", "version": "1.0"} \
assert 'pip-test-package (0.1.1,' in result.stdout # editables included not in json.loads(result.stdout) # 3.0 is latest
assert 'simple2 (3.0)' in result.stdout, str(result) assert {"name": "pip-test-package", "version": "0.1.1"} \
in json.loads(result.stdout) # editables included
assert {"name": "simple2", "version": "3.0"} in json.loads(result.stdout)
@pytest.mark.network @pytest.mark.network
@ -219,6 +218,7 @@ def test_uptodate_legacy_flag(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', '--uptodate', 'list', '-f', data.find_links, '--no-index', '--uptodate',
'--format=legacy', '--format=legacy',
expect_stderr=True,
) )
assert 'simple (1.0)' not in result.stdout # 3.0 is latest assert 'simple (1.0)' not in result.stdout # 3.0 is latest
assert 'pip-test-package (0.1.1,' in result.stdout # editables included assert 'pip-test-package (0.1.1,' in result.stdout # editables included
@ -242,13 +242,18 @@ def test_outdated_flag(script, data):
) )
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', '--outdated', 'list', '-f', data.find_links, '--no-index', '--outdated',
'--format=legacy', '--format=json',
) )
assert 'simple (1.0) - Latest: 3.0 [sdist]' in result.stdout assert {"name": "simple", "version": "1.0",
assert 'simplewheel (1.0) - Latest: 2.0 [wheel]' in result.stdout "latest_version": "3.0", "latest_filetype": "sdist"} \
assert 'pip-test-package (0.1, ' in result.stdout in json.loads(result.stdout)
assert ' Latest: 0.1.1 [sdist]' in result.stdout assert dict(name="simplewheel", version="1.0",
assert 'simple2' not in result.stdout, str(result) # 3.0 is latest latest_version="2.0", latest_filetype="wheel") \
in json.loads(result.stdout)
assert dict(name="pip-test-package", version="0.1",
latest_version="0.1.1", latest_filetype="sdist") \
in json.loads(result.stdout)
assert "simple2" not in {p["name"] for p in json.loads(result.stdout)}
@pytest.mark.network @pytest.mark.network
@ -303,6 +308,7 @@ def test_outdated_legacy(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', '--outdated', 'list', '-f', data.find_links, '--no-index', '--outdated',
'--format=legacy', '--format=legacy',
expect_stderr=True,
) )
assert 'simple (1.0) - Latest: 3.0 [sdist]' in result.stdout assert 'simple (1.0) - Latest: 3.0 [sdist]' in result.stdout
assert 'simplewheel (1.0) - Latest: 2.0 [wheel]' in result.stdout assert 'simplewheel (1.0) - Latest: 2.0 [wheel]' in result.stdout
@ -321,11 +327,11 @@ def test_editables_flag(script, data):
'install', '-e', 'install', '-e',
'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package'
) )
result = script.pip('list', '--editable', '--format=legacy') result = script.pip('list', '--editable', '--format=json')
assert 'simple (1.0)' not in result.stdout, str(result) result2 = script.pip('list', '--editable')
assert os.path.join('src', 'pip-test-package') in result.stdout, ( assert {"name": "simple", "version": "1.0"} \
str(result) not in json.loads(result.stdout)
) assert os.path.join('src', 'pip-test-package') in result2.stdout
@pytest.mark.network @pytest.mark.network
@ -338,9 +344,10 @@ def test_exclude_editable_flag(script, data):
'install', '-e', 'install', '-e',
'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package'
) )
result = script.pip('list', '--exclude-editable', '--format=legacy') result = script.pip('list', '--exclude-editable', '--format=json')
assert 'simple (1.0)' in result.stdout, str(result) assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout)
assert 'pip-test-package (0.1, ' not in result.stdout assert "pip-test-package" \
not in {p["name"] for p in json.loads(result.stdout)}
@pytest.mark.network @pytest.mark.network
@ -394,9 +401,8 @@ def test_uptodate_editables_flag(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', 'list', '-f', data.find_links, '--no-index',
'--editable', '--uptodate', '--editable', '--uptodate',
'--format=legacy',
) )
assert 'simple (1.0)' not in result.stdout, str(result) assert 'simple' not in result.stdout
assert os.path.join('src', 'pip-test-package') in result.stdout, ( assert os.path.join('src', 'pip-test-package') in result.stdout, (
str(result) str(result)
) )
@ -439,6 +445,7 @@ def test_uptodate_editables_legacy(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', '--editable', 'list', '-f', data.find_links, '--no-index', '--editable',
'--uptodate', '--format=legacy', '--uptodate', '--format=legacy',
expect_stderr=True,
) )
assert 'simple (1.0)' not in result.stdout, str(result) assert 'simple (1.0)' not in result.stdout, str(result)
assert os.path.join('src', 'pip-test-package') in result.stdout, ( assert os.path.join('src', 'pip-test-package') in result.stdout, (
@ -460,12 +467,9 @@ def test_outdated_editables_flag(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', 'list', '-f', data.find_links, '--no-index',
'--editable', '--outdated', '--editable', '--outdated',
'--format=legacy',
)
assert 'simple (1.0)' not in result.stdout, str(result)
assert os.path.join('src', 'pip-test-package') in result.stdout, (
str(result)
) )
assert 'simple' not in result.stdout
assert os.path.join('src', 'pip-test-package') in result.stdout
@pytest.mark.network @pytest.mark.network
@ -505,6 +509,7 @@ def test_outdated_editables_legacy(script, data):
result = script.pip( result = script.pip(
'list', '-f', data.find_links, '--no-index', 'list', '-f', data.find_links, '--no-index',
'--editable', '--outdated', '--format=legacy', '--editable', '--outdated', '--format=legacy',
expect_stderr=True,
) )
assert 'simple (1.0)' not in result.stdout, str(result) assert 'simple (1.0)' not in result.stdout, str(result)
assert os.path.join('src', 'pip-test-package') in result.stdout, ( assert os.path.join('src', 'pip-test-package') in result.stdout, (
@ -522,18 +527,22 @@ def test_outdated_pre(script, data):
wheelhouse_path.join('simple-2.0.dev0-py2.py3-none-any.whl').write('') wheelhouse_path.join('simple-2.0.dev0-py2.py3-none-any.whl').write('')
result = script.pip( result = script.pip(
'list', '--no-index', '--find-links', wheelhouse_path, 'list', '--no-index', '--find-links', wheelhouse_path,
'--format=legacy', '--format=json',
) )
assert 'simple (1.0)' in result.stdout assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout)
result = script.pip( result = script.pip(
'list', '--no-index', '--find-links', wheelhouse_path, '--outdated', 'list', '--no-index', '--find-links', wheelhouse_path, '--outdated',
'--format=legacy', '--format=json',
) )
assert 'simple (1.0) - Latest: 1.1 [wheel]' in result.stdout assert {"name": "simple", "version": "1.0",
"latest_version": "1.1", "latest_filetype": "wheel"} \
in json.loads(result.stdout)
result_pre = script.pip('list', '--no-index', result_pre = script.pip('list', '--no-index',
'--find-links', wheelhouse_path, '--find-links', wheelhouse_path,
'--outdated', '--pre', '--format=legacy') '--outdated', '--pre', '--format=json')
assert 'simple (1.0) - Latest: 2.0.dev0 [wheel]' in result_pre.stdout assert {"name": "simple", "version": "1.0",
"latest_version": "2.0.dev0", "latest_filetype": "wheel"} \
in json.loads(result_pre.stdout)
def test_outdated_formats(script, data): def test_outdated_formats(script, data):
@ -552,7 +561,7 @@ def test_outdated_formats(script, data):
# Check legacy # Check legacy
result = script.pip('list', '--no-index', '--find-links', wheelhouse_path, result = script.pip('list', '--no-index', '--find-links', wheelhouse_path,
'--outdated', '--format=legacy') '--outdated', '--format=legacy', expect_stderr=True)
assert 'simple (1.0) - Latest: 1.1 [wheel]' in result.stdout assert 'simple (1.0) - Latest: 1.1 [wheel]' in result.stdout
# Check columns # Check columns

View File

@ -1,5 +1,6 @@
from __future__ import with_statement from __future__ import with_statement
import json
import textwrap import textwrap
import os import os
import sys import sys
@ -8,7 +9,7 @@ import pretend
from os.path import join, normpath from os.path import join, normpath
from tempfile import mkdtemp from tempfile import mkdtemp
from tests.lib import assert_all_changes, pyversion from tests.lib import assert_all_changes
from tests.lib import create_test_package_with_setup from tests.lib import create_test_package_with_setup
from tests.lib.local_repos import local_repo, local_checkout from tests.lib.local_repos import local_repo, local_checkout
@ -48,11 +49,13 @@ def test_simple_uninstall_distutils(script):
) )
""")) """))
result = script.run('python', pkg_path / 'setup.py', 'install') result = script.run('python', pkg_path / 'setup.py', 'install')
result = script.pip('list', '--format=legacy') result = script.pip('list', '--format=json')
assert "distutils-install (0.1)" in result.stdout assert {"name": "distutils-install", "version": "0.1"} \
in json.loads(result.stdout)
script.pip('uninstall', 'distutils_install', '-y', expect_stderr=True) script.pip('uninstall', 'distutils_install', '-y', expect_stderr=True)
result2 = script.pip('list', '--format=legacy') result2 = script.pip('list', '--format=json')
assert "distutils-install (0.1)" not in result2.stdout assert {"name": "distutils-install", "version": "0.1"} \
not in json.loads(result2.stdout)
@pytest.mark.network @pytest.mark.network
@ -177,12 +180,14 @@ def test_uninstall_entry_point(script, console_scripts):
script_name = script.bin_path.join(console_scripts.split('=')[0].strip()) script_name = script.bin_path.join(console_scripts.split('=')[0].strip())
result = script.pip('install', pkg_path) result = script.pip('install', pkg_path)
assert script_name.exists assert script_name.exists
result = script.pip('list', '--format=legacy') result = script.pip('list', '--format=json')
assert "ep-install (0.1)" in result.stdout assert {"name": "ep-install", "version": "0.1"} \
in json.loads(result.stdout)
script.pip('uninstall', 'ep_install', '-y') script.pip('uninstall', 'ep_install', '-y')
assert not script_name.exists assert not script_name.exists
result2 = script.pip('list', '--format=legacy') result2 = script.pip('list', '--format=json')
assert "ep-install (0.1)" not in result2.stdout assert {"name": "ep-install", "version": "0.1"} \
not in json.loads(result2.stdout)
def test_uninstall_gui_scripts(script): def test_uninstall_gui_scripts(script):
@ -416,8 +421,9 @@ def test_uninstall_setuptools_develop_install(script, data):
expect_stderr=True, cwd=pkg_path) expect_stderr=True, cwd=pkg_path)
script.run('python', 'setup.py', 'install', script.run('python', 'setup.py', 'install',
expect_stderr=True, cwd=pkg_path) expect_stderr=True, cwd=pkg_path)
list_result = script.pip('list', '--format=legacy') list_result = script.pip('list', '--format=json')
assert "FSPkg (0.1.dev0, " in list_result.stdout assert {"name": "FSPkg", "version": "0.1.dev0"} \
in json.loads(list_result.stdout)
# Uninstall both develop and install # Uninstall both develop and install
uninstall = script.pip('uninstall', 'FSPkg', '-y') uninstall = script.pip('uninstall', 'FSPkg', '-y')
assert any(filename.endswith('.egg') assert any(filename.endswith('.egg')
@ -426,8 +432,8 @@ def test_uninstall_setuptools_develop_install(script, data):
assert join( assert join(
script.site_packages, 'FSPkg.egg-link' script.site_packages, 'FSPkg.egg-link'
) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys())
list_result2 = script.pip('list', '--format=legacy') list_result2 = script.pip('list', '--format=json')
assert "FSPkg" not in list_result2.stdout assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)}
def test_uninstall_editable_and_pip_install(script, data): def test_uninstall_editable_and_pip_install(script, data):
@ -443,8 +449,9 @@ def test_uninstall_editable_and_pip_install(script, data):
# ensure both are installed with --ignore-installed: # ensure both are installed with --ignore-installed:
script.pip('install', '--ignore-installed', '.', script.pip('install', '--ignore-installed', '.',
expect_stderr=True, cwd=pkg_path) expect_stderr=True, cwd=pkg_path)
list_result = script.pip('list', '--format=legacy') list_result = script.pip('list', '--format=json')
assert "FSPkg (0.1.dev0, " in list_result.stdout assert {"name": "FSPkg", "version": "0.1.dev0"} \
in json.loads(list_result.stdout)
# Uninstall both develop and install # Uninstall both develop and install
uninstall = script.pip('uninstall', 'FSPkg', '-y') uninstall = script.pip('uninstall', 'FSPkg', '-y')
assert not any(filename.endswith('.egg-link') assert not any(filename.endswith('.egg-link')
@ -453,5 +460,5 @@ def test_uninstall_editable_and_pip_install(script, data):
assert join( assert join(
script.site_packages, 'FSPkg.egg-link' script.site_packages, 'FSPkg.egg-link'
) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys())
list_result2 = script.pip('list', '--format=legacy') list_result2 = script.pip('list', '--format=json')
assert "FSPkg" not in list_result2.stdout assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)}