From 0b1f521059765fd1d853fb76f4e2ebc4582650b0 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Sun, 19 Mar 2017 22:08:31 -0400 Subject: [PATCH] Switch the default for pip list to the columns format --- news/3654.removal | 2 + news/3686.removal | 2 + pip/commands/list.py | 19 +++-- tests/functional/test_list.py | 111 ++++++++++++++++------------- tests/functional/test_uninstall.py | 41 ++++++----- 5 files changed, 97 insertions(+), 78 deletions(-) create mode 100644 news/3654.removal create mode 100644 news/3686.removal diff --git a/news/3654.removal b/news/3654.removal new file mode 100644 index 000000000..c2679b06e --- /dev/null +++ b/news/3654.removal @@ -0,0 +1,2 @@ +Switch the default for ``pip list`` to the columns format, and deprecate the +legacy format. diff --git a/news/3686.removal b/news/3686.removal new file mode 100644 index 000000000..c2679b06e --- /dev/null +++ b/news/3686.removal @@ -0,0 +1,2 @@ +Switch the default for ``pip list`` to the columns format, and deprecate the +legacy format. diff --git a/pip/commands/list.py b/pip/commands/list.py index 9e40a1758..9d31bb65b 100644 --- a/pip/commands/list.py +++ b/pip/commands/list.py @@ -15,7 +15,7 @@ from pip.exceptions import CommandError from pip.index import PackageFinder from pip.utils import ( 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 logger = logging.getLogger(__name__) @@ -78,9 +78,10 @@ class ListCommand(Command): '--format', action='store', dest='list_format', + default="columns", choices=('legacy', 'columns', 'freeze', 'json'), - help="Select the output format among: legacy (default), columns, " - "freeze or json.", + help="Select the output format among: columns (default), freeze, " + "json, or legacy.", ) cmd_opts.add_option( @@ -123,13 +124,11 @@ class ListCommand(Command): ) def run(self, options, args): - if options.list_format is None: + if options.list_format == "legacy": warnings.warn( - "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.", - RemovedInPip10Warning, + "The legacy format has been deprecated and will be removed " + "in the future.", + RemovedInPip11Warning, ) if options.outdated and options.uptodate: @@ -240,7 +239,7 @@ class ListCommand(Command): logger.info("%s==%s", dist.project_name, dist.version) elif options.list_format == 'json': logger.info(format_for_json(packages, options)) - else: # legacy + elif options.list_format == "legacy": for dist in packages: if options.outdated: logger.info(self.output_legacy_latest(dist)) diff --git a/tests/functional/test_list.py b/tests/functional/test_list.py index f8bbe7fe8..7b4169683 100644 --- a/tests/functional/test_list.py +++ b/tests/functional/test_list.py @@ -2,26 +2,19 @@ import json import os 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): """ Test default behavior of list command without format specifier. - A warning is expected. """ script.pip( 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0', ) - result = script.pip('list', expect_stderr=True) - assert WARN_FORMAT in result.stderr, str(result) - assert 'simple (1.0)' in result.stdout, str(result) - assert 'simple2 (3.0)' in result.stdout, str(result) + result = script.pip('list') + assert 'simple 1.0' in result.stdout, str(result) + assert 'simple2 3.0' in result.stdout, str(result) 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', '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 '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', '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 'simple2 (3.0)' 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') - result = script.pip('list', '--local', '--format=legacy') - assert 'simple (1.0)' in result.stdout + result = script.pip('list', '--local', '--format=json') + assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout) def test_local_columns_flag(script, data): @@ -105,7 +99,8 @@ def test_local_legacy_flag(script, data): command. """ 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 @@ -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', '--user', 'simple2==2.0') - result = script.pip('list', '--user', '--format=legacy') - assert 'simple (1.0)' not in result.stdout - assert 'simple2 (2.0)' in result.stdout + result = script.pip('list', '--user', '--format=json') + assert {"name": "simple", "version": "1.0"} \ + 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): @@ -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', '--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 'simple2 (2.0)' in result.stdout, str(result) @@ -169,11 +166,13 @@ def test_uptodate_flag(script, data): ) result = script.pip( '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 'pip-test-package (0.1.1,' in result.stdout # editables included - assert 'simple2 (3.0)' in result.stdout, str(result) + assert {"name": "simple", "version": "1.0"} \ + not in json.loads(result.stdout) # 3.0 is latest + 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 @@ -219,6 +218,7 @@ def test_uptodate_legacy_flag(script, data): result = script.pip( 'list', '-f', data.find_links, '--no-index', '--uptodate', '--format=legacy', + expect_stderr=True, ) assert 'simple (1.0)' not in result.stdout # 3.0 is latest 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( 'list', '-f', data.find_links, '--no-index', '--outdated', - '--format=legacy', + '--format=json', ) - assert 'simple (1.0) - Latest: 3.0 [sdist]' in result.stdout - assert 'simplewheel (1.0) - Latest: 2.0 [wheel]' in result.stdout - assert 'pip-test-package (0.1, ' in result.stdout - assert ' Latest: 0.1.1 [sdist]' in result.stdout - assert 'simple2' not in result.stdout, str(result) # 3.0 is latest + assert {"name": "simple", "version": "1.0", + "latest_version": "3.0", "latest_filetype": "sdist"} \ + in json.loads(result.stdout) + assert dict(name="simplewheel", version="1.0", + 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 @@ -303,6 +308,7 @@ def test_outdated_legacy(script, data): result = script.pip( 'list', '-f', data.find_links, '--no-index', '--outdated', '--format=legacy', + expect_stderr=True, ) assert 'simple (1.0) - Latest: 3.0 [sdist]' 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', 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' ) - result = script.pip('list', '--editable', '--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) - ) + result = script.pip('list', '--editable', '--format=json') + result2 = script.pip('list', '--editable') + assert {"name": "simple", "version": "1.0"} \ + not in json.loads(result.stdout) + assert os.path.join('src', 'pip-test-package') in result2.stdout @pytest.mark.network @@ -338,9 +344,10 @@ def test_exclude_editable_flag(script, data): 'install', '-e', 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' ) - result = script.pip('list', '--exclude-editable', '--format=legacy') - assert 'simple (1.0)' in result.stdout, str(result) - assert 'pip-test-package (0.1, ' not in result.stdout + result = script.pip('list', '--exclude-editable', '--format=json') + assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout) + assert "pip-test-package" \ + not in {p["name"] for p in json.loads(result.stdout)} @pytest.mark.network @@ -394,9 +401,8 @@ def test_uptodate_editables_flag(script, data): result = script.pip( 'list', '-f', data.find_links, '--no-index', '--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, ( str(result) ) @@ -439,6 +445,7 @@ def test_uptodate_editables_legacy(script, data): result = script.pip( 'list', '-f', data.find_links, '--no-index', '--editable', '--uptodate', '--format=legacy', + expect_stderr=True, ) assert 'simple (1.0)' not in result.stdout, str(result) 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( 'list', '-f', data.find_links, '--no-index', '--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 @@ -505,6 +509,7 @@ def test_outdated_editables_legacy(script, data): result = script.pip( 'list', '-f', data.find_links, '--no-index', '--editable', '--outdated', '--format=legacy', + expect_stderr=True, ) assert 'simple (1.0)' not in result.stdout, str(result) 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('') result = script.pip( '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( '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', '--find-links', wheelhouse_path, - '--outdated', '--pre', '--format=legacy') - assert 'simple (1.0) - Latest: 2.0.dev0 [wheel]' in result_pre.stdout + '--outdated', '--pre', '--format=json') + 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): @@ -552,7 +561,7 @@ def test_outdated_formats(script, data): # Check legacy 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 # Check columns diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py index d1416dc29..6206840e7 100644 --- a/tests/functional/test_uninstall.py +++ b/tests/functional/test_uninstall.py @@ -1,5 +1,6 @@ from __future__ import with_statement +import json import textwrap import os import sys @@ -8,7 +9,7 @@ import pretend from os.path import join, normpath 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.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.pip('list', '--format=legacy') - assert "distutils-install (0.1)" in result.stdout + result = script.pip('list', '--format=json') + assert {"name": "distutils-install", "version": "0.1"} \ + in json.loads(result.stdout) script.pip('uninstall', 'distutils_install', '-y', expect_stderr=True) - result2 = script.pip('list', '--format=legacy') - assert "distutils-install (0.1)" not in result2.stdout + result2 = script.pip('list', '--format=json') + assert {"name": "distutils-install", "version": "0.1"} \ + not in json.loads(result2.stdout) @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()) result = script.pip('install', pkg_path) assert script_name.exists - result = script.pip('list', '--format=legacy') - assert "ep-install (0.1)" in result.stdout + result = script.pip('list', '--format=json') + assert {"name": "ep-install", "version": "0.1"} \ + in json.loads(result.stdout) script.pip('uninstall', 'ep_install', '-y') assert not script_name.exists - result2 = script.pip('list', '--format=legacy') - assert "ep-install (0.1)" not in result2.stdout + result2 = script.pip('list', '--format=json') + assert {"name": "ep-install", "version": "0.1"} \ + not in json.loads(result2.stdout) def test_uninstall_gui_scripts(script): @@ -416,8 +421,9 @@ def test_uninstall_setuptools_develop_install(script, data): expect_stderr=True, cwd=pkg_path) script.run('python', 'setup.py', 'install', expect_stderr=True, cwd=pkg_path) - list_result = script.pip('list', '--format=legacy') - assert "FSPkg (0.1.dev0, " in list_result.stdout + list_result = script.pip('list', '--format=json') + assert {"name": "FSPkg", "version": "0.1.dev0"} \ + in json.loads(list_result.stdout) # Uninstall both develop and install uninstall = script.pip('uninstall', 'FSPkg', '-y') assert any(filename.endswith('.egg') @@ -426,8 +432,8 @@ def test_uninstall_setuptools_develop_install(script, data): assert join( script.site_packages, 'FSPkg.egg-link' ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) - list_result2 = script.pip('list', '--format=legacy') - assert "FSPkg" not in list_result2.stdout + list_result2 = script.pip('list', '--format=json') + assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)} 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: script.pip('install', '--ignore-installed', '.', expect_stderr=True, cwd=pkg_path) - list_result = script.pip('list', '--format=legacy') - assert "FSPkg (0.1.dev0, " in list_result.stdout + list_result = script.pip('list', '--format=json') + assert {"name": "FSPkg", "version": "0.1.dev0"} \ + in json.loads(list_result.stdout) # Uninstall both develop and install uninstall = script.pip('uninstall', 'FSPkg', '-y') assert not any(filename.endswith('.egg-link') @@ -453,5 +460,5 @@ def test_uninstall_editable_and_pip_install(script, data): assert join( script.site_packages, 'FSPkg.egg-link' ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) - list_result2 = script.pip('list', '--format=legacy') - assert "FSPkg" not in list_result2.stdout + list_result2 = script.pip('list', '--format=json') + assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)}