Skip to content

When pip was not installed by pip, don't show the upgrade warning #5368

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 1 commit into from
May 22, 2018
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
5 changes: 5 additions & 0 deletions news/5346.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Disable pip's version check (and upgrade message) when installed by a different package manager.

This works better with Linux distributions where pip's upgrade message may
result in users running pip in a manner that modifies files that should be
managed by the OS's package manager.
19 changes: 17 additions & 2 deletions src/pip/_internal/utils/outdated.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import os.path
import sys

from pip._vendor import lockfile
from pip._vendor import lockfile, pkg_resources
from pip._vendor.packaging import version as packaging_version

from pip._internal.compat import WINDOWS
Expand Down Expand Up @@ -58,6 +58,20 @@ def save(self, pypi_version, current_time):
separators=(",", ":"))


def pip_installed_by_pip():
"""Checks whether pip was installed by pip

This is used not to display the upgrade message when pip is in fact
installed by system package manager, such as dnf on Fedora.
"""
try:
dist = pkg_resources.get_distribution('pip')
return (dist.has_metadata('INSTALLER') and
'pip' in dist.get_metadata_lines('INSTALLER'))
except pkg_resources.DistributionNotFound:
return False


def pip_version_check(session, options):
"""Check for an update for pip.

Expand Down Expand Up @@ -110,7 +124,8 @@ def pip_version_check(session, options):

# Determine if our pypi_version is older
if (pip_version < remote_version and
pip_version.base_version != remote_version.base_version):
pip_version.base_version != remote_version.base_version and
pip_installed_by_pip()):
# Advise "python -m pip" on Windows to avoid issues
# with overwriting pip.exe.
if WINDOWS:
Expand Down
30 changes: 25 additions & 5 deletions tests/unit/test_unit_outdated.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import freezegun
import pretend
import pytest
from pip._vendor import lockfile
from pip._vendor import lockfile, pkg_resources

from pip._internal.index import InstallationCandidate
from pip._internal.utils import outdated
Expand All @@ -33,6 +33,20 @@ def find_all_candidates(self, project_name):
return self.INSTALLATION_CANDIDATES


class MockDistribution(object):
def __init__(self, installer):
self.installer = installer

def has_metadata(self, name):
return name == 'INSTALLER'

def get_metadata_lines(self, name):
if self.has_metadata(name):
yield self.installer
else:
raise NotImplementedError('nope')


def _options():
''' Some default options that we pass to outdated.pip_version_check '''
return pretend.stub(
Expand All @@ -47,27 +61,33 @@ def _options():
'stored_time',
'installed_ver',
'new_ver',
'installer',
'check_if_upgrade_required',
'check_warn_logs',
],
[
# Test we return None when installed version is None
('1970-01-01T10:00:00Z', None, '1.0', False, False),
('1970-01-01T10:00:00Z', None, '1.0', 'pip', False, False),
# Need an upgrade - upgrade warning should print
('1970-01-01T10:00:00Z', '1.0', '6.9.0', True, True),
('1970-01-01T10:00:00Z', '1.0', '6.9.0', 'pip', True, True),
# Upgrade available, pip installed via rpm - warning should not print
('1970-01-01T10:00:00Z', '1.0', '6.9.0', 'rpm', True, False),
# No upgrade - upgrade warning should not print
('1970-01-9T10:00:00Z', '6.9.0', '6.9.0', False, False),
('1970-01-9T10:00:00Z', '6.9.0', '6.9.0', 'pip', False, False),
]
)
def test_pip_version_check(monkeypatch, stored_time, installed_ver, new_ver,
check_if_upgrade_required, check_warn_logs):
installer, check_if_upgrade_required,
check_warn_logs):
monkeypatch.setattr(outdated, 'get_installed_version',
lambda name: installed_ver)
monkeypatch.setattr(outdated, 'PackageFinder', MockPackageFinder)
monkeypatch.setattr(outdated.logger, 'warning',
pretend.call_recorder(lambda *a, **kw: None))
monkeypatch.setattr(outdated.logger, 'debug',
pretend.call_recorder(lambda s, exc_info=None: None))
monkeypatch.setattr(pkg_resources, 'get_distribution',
lambda name: MockDistribution(installer))

fake_state = pretend.stub(
state={"last_check": stored_time, 'pypi_version': installed_ver},
Expand Down