Skip to content

Fixed issue#949 #4414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions news/949.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added a way to distinguish between pip installed packages and those from
the system package manager in 'pip list'. Specifically, 'pip list -v' also
shows the installer of package if it has that meta data.
15 changes: 14 additions & 1 deletion pip/commands/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pip.utils import (
get_installed_distributions, dist_is_editable)
from pip.utils.deprecation import RemovedInPip11Warning
from pip.utils.packaging import get_installer
from pip.cmdoptions import make_option_group, index_group

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -210,7 +211,14 @@ def iter_packages_latest_infos(self, packages, options):
yield dist

def output_legacy(self, dist, options):
if options.verbose >= 1 or dist_is_editable(dist):
if options.verbose >= 1:
return '%s (%s, %s, %s)' % (
dist.project_name,
dist.version,
dist.location,
get_installer(dist),
)
elif dist_is_editable(dist):
return '%s (%s, %s)' % (
dist.project_name,
dist.version,
Expand Down Expand Up @@ -298,6 +306,8 @@ def format_for_columns(pkgs, options):
data = []
if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs):
header.append("Location")
if options.verbose >= 1:
header.append("Installer")

for proj in pkgs:
# if we're working on the 'outdated' list, separate out the
Expand All @@ -310,6 +320,8 @@ def format_for_columns(pkgs, options):

if options.verbose >= 1 or dist_is_editable(proj):
row.append(proj.location)
if options.verbose >= 1:
row.append(get_installer(proj))

data.append(row)

Expand All @@ -325,6 +337,7 @@ def format_for_json(packages, options):
}
if options.verbose >= 1:
info['location'] = dist.location
info['installer'] = get_installer(dist)
if options.outdated:
info['latest_version'] = six.text_type(dist.latest_version)
info['latest_filetype'] = dist.latest_filetype
Expand Down
8 changes: 8 additions & 0 deletions pip/utils/packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,11 @@ def check_dist_requires_python(dist):
"Package %s has an invalid Requires-Python entry %s - %s" % (
dist.project_name, requires_python, e))
return


def get_installer(dist):
if dist.has_metadata('INSTALLER'):
for line in dist.get_metadata_lines('INSTALLER'):
if line.strip():
return line.strip()
return ''
3 changes: 2 additions & 1 deletion tests/functional/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ def test_verbose_flag(script, data):
'install', '-f', data.find_links, '--no-index', 'simple==1.0',
'simple2==3.0',
)
result = script.pip('list', '-v')
result = script.pip('list', '-v', '--format=columns')
assert 'Package' in result.stdout, str(result)
assert 'Version' in result.stdout, str(result)
assert 'Location' in result.stdout, str(result)
assert 'Installer' in result.stdout, str(result)
assert 'simple 1.0' in result.stdout, str(result)
assert 'simple2 3.0' in result.stdout, str(result)

Expand Down