mirror of https://github.com/pypa/pip
Add --exclude option to pip freeze and pip list commands
This commit is contained in:
parent
cdc5422ed5
commit
9725229888
|
@ -0,0 +1 @@
|
|||
Add ``--exclude`` option to ``pip freeze`` and ``pip list`` commands to explicitly exclude packages from the output.
|
|
@ -0,0 +1,2 @@
|
|||
``pip freeze`` will stop filtering the ``pip``, ``setuptools``, ``distribute`` and ``wheel`` packages from ``pip freeze`` output in a future version.
|
||||
To keep the previous behavior, users should use the new ``--exclude`` option.
|
|
@ -20,6 +20,8 @@ from functools import partial
|
|||
from optparse import SUPPRESS_HELP, Option, OptionGroup
|
||||
from textwrap import dedent
|
||||
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
|
||||
from pip._internal.cli.progress_bars import BAR_TYPES
|
||||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.locations import USER_CACHE_DIR, get_src_prefix
|
||||
|
@ -133,9 +135,15 @@ def _path_option_check(option, opt, value):
|
|||
return os.path.expanduser(value)
|
||||
|
||||
|
||||
def _package_name_option_check(option, opt, value):
|
||||
# type: (Option, str, str) -> str
|
||||
return canonicalize_name(value)
|
||||
|
||||
|
||||
class PipOption(Option):
|
||||
TYPES = Option.TYPES + ("path",)
|
||||
TYPES = Option.TYPES + ("path", "package_name")
|
||||
TYPE_CHECKER = Option.TYPE_CHECKER.copy()
|
||||
TYPE_CHECKER["package_name"] = _package_name_option_check
|
||||
TYPE_CHECKER["path"] = _path_option_check
|
||||
|
||||
|
||||
|
@ -866,6 +874,17 @@ def check_list_path_option(options):
|
|||
)
|
||||
|
||||
|
||||
list_exclude = partial(
|
||||
PipOption,
|
||||
'--exclude',
|
||||
dest='excludes',
|
||||
action='append',
|
||||
metavar='package',
|
||||
type='package_name',
|
||||
help="Exclude specified package from the output",
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
no_python_version_warning = partial(
|
||||
Option,
|
||||
'--no-python-version-warning',
|
||||
|
|
|
@ -74,6 +74,7 @@ class FreezeCommand(Command):
|
|||
dest='exclude_editable',
|
||||
action='store_true',
|
||||
help='Exclude editable package from output.')
|
||||
self.cmd_opts.add_option(cmdoptions.list_exclude())
|
||||
|
||||
self.parser.insert_option_group(0, self.cmd_opts)
|
||||
|
||||
|
@ -85,6 +86,9 @@ class FreezeCommand(Command):
|
|||
if not options.freeze_all:
|
||||
skip.update(DEV_PKGS)
|
||||
|
||||
if options.excludes:
|
||||
skip.update(options.excludes)
|
||||
|
||||
cmdoptions.check_list_path_option(options)
|
||||
|
||||
if options.find_links:
|
||||
|
|
|
@ -12,6 +12,7 @@ from pip._internal.exceptions import CommandError
|
|||
from pip._internal.index.collector import LinkCollector
|
||||
from pip._internal.index.package_finder import PackageFinder
|
||||
from pip._internal.models.selection_prefs import SelectionPreferences
|
||||
from pip._internal.utils.compat import stdlib_pkgs
|
||||
from pip._internal.utils.misc import (
|
||||
dist_is_editable,
|
||||
get_installed_distributions,
|
||||
|
@ -114,6 +115,7 @@ class ListCommand(IndexGroupCommand):
|
|||
help='Include editable package from output.',
|
||||
default=True,
|
||||
)
|
||||
self.cmd_opts.add_option(cmdoptions.list_exclude())
|
||||
index_opts = cmdoptions.make_option_group(
|
||||
cmdoptions.index_group, self.parser
|
||||
)
|
||||
|
@ -147,12 +149,17 @@ class ListCommand(IndexGroupCommand):
|
|||
|
||||
cmdoptions.check_list_path_option(options)
|
||||
|
||||
skip = set(stdlib_pkgs)
|
||||
if options.excludes:
|
||||
skip.update(options.excludes)
|
||||
|
||||
packages = get_installed_distributions(
|
||||
local_only=options.local,
|
||||
user_only=options.user,
|
||||
editables_only=options.editable,
|
||||
include_editables=options.include_editable,
|
||||
paths=options.path,
|
||||
skip=skip,
|
||||
)
|
||||
|
||||
# get_not_required must be called firstly in order to find and
|
||||
|
|
|
@ -16,6 +16,7 @@ from tests.lib import (
|
|||
need_mercurial,
|
||||
need_svn,
|
||||
path_to_url,
|
||||
wheel,
|
||||
)
|
||||
|
||||
distribute_re = re.compile('^distribute==[0-9.]+\n', re.MULTILINE)
|
||||
|
@ -80,6 +81,25 @@ def test_freeze_with_pip(script):
|
|||
assert 'pip==' in result.stdout
|
||||
|
||||
|
||||
def test_exclude_and_normalization(script, tmpdir):
|
||||
req_path = wheel.make_wheel(
|
||||
name="Normalizable_Name", version="1.0").save_to_dir(tmpdir)
|
||||
script.pip("install", "--no-index", req_path)
|
||||
result = script.pip("freeze")
|
||||
assert "Normalizable-Name" in result.stdout
|
||||
result = script.pip("freeze", "--exclude", "normalizablE-namE")
|
||||
assert "Normalizable-Name" not in result.stdout
|
||||
|
||||
|
||||
def test_freeze_multiple_exclude_with_all(script, with_wheel):
|
||||
result = script.pip('freeze', '--all')
|
||||
assert 'pip==' in result.stdout
|
||||
assert 'wheel==' in result.stdout
|
||||
result = script.pip('freeze', '--all', '--exclude', 'pip', '--exclude', 'wheel')
|
||||
assert 'pip==' not in result.stdout
|
||||
assert 'wheel==' not in result.stdout
|
||||
|
||||
|
||||
def test_freeze_with_invalid_names(script):
|
||||
"""
|
||||
Test that invalid names produce warnings and are passed over gracefully.
|
||||
|
|
|
@ -3,7 +3,7 @@ import os
|
|||
|
||||
import pytest
|
||||
|
||||
from tests.lib import create_test_package_with_setup
|
||||
from tests.lib import create_test_package_with_setup, wheel
|
||||
from tests.lib.path import Path
|
||||
|
||||
|
||||
|
@ -94,6 +94,19 @@ def test_local_columns_flag(simple_script):
|
|||
assert 'simple 1.0' in result.stdout, str(result)
|
||||
|
||||
|
||||
def test_multiple_exclude_and_normalization(script, tmpdir):
|
||||
req_path = wheel.make_wheel(
|
||||
name="Normalizable_Name", version="1.0").save_to_dir(tmpdir)
|
||||
script.pip("install", "--no-index", req_path)
|
||||
result = script.pip("list")
|
||||
print(result.stdout)
|
||||
assert "Normalizable-Name" in result.stdout
|
||||
assert "pip" in result.stdout
|
||||
result = script.pip("list", "--exclude", "normalizablE-namE", "--exclude", "pIp")
|
||||
assert "Normalizable-Name" not in result.stdout
|
||||
assert "pip" not in result.stdout
|
||||
|
||||
|
||||
@pytest.mark.network
|
||||
@pytest.mark.incompatible_with_test_venv
|
||||
def test_user_flag(script, data):
|
||||
|
|
Loading…
Reference in New Issue