mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Fix --upgrade to leave already up-to-date packages alone. Add --force-reinstall to force reinstallation even of up-to-date packages, as was the prior behavior.
This commit is contained in:
parent
2a5e21b41f
commit
1ecda0db16
|
@ -106,6 +106,12 @@ class InstallCommand(Command):
|
||||||
dest='upgrade',
|
dest='upgrade',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Upgrade all packages to the newest available version')
|
help='Upgrade all packages to the newest available version')
|
||||||
|
self.parser.add_option(
|
||||||
|
'--force-reinstall',
|
||||||
|
dest='force_reinstall',
|
||||||
|
action='store_true',
|
||||||
|
help='When upgrading, reinstall all packages even if they are '
|
||||||
|
'already up-to-date.')
|
||||||
self.parser.add_option(
|
self.parser.add_option(
|
||||||
'-I', '--ignore-installed',
|
'-I', '--ignore-installed',
|
||||||
dest='ignore_installed',
|
dest='ignore_installed',
|
||||||
|
@ -190,7 +196,8 @@ class InstallCommand(Command):
|
||||||
download_cache=options.download_cache,
|
download_cache=options.download_cache,
|
||||||
upgrade=options.upgrade,
|
upgrade=options.upgrade,
|
||||||
ignore_installed=options.ignore_installed,
|
ignore_installed=options.ignore_installed,
|
||||||
ignore_dependencies=options.ignore_dependencies)
|
ignore_dependencies=options.ignore_dependencies,
|
||||||
|
force_reinstall=options.force_reinstall)
|
||||||
for name in args:
|
for name in args:
|
||||||
requirement_set.add_requirement(
|
requirement_set.add_requirement(
|
||||||
InstallRequirement.from_line(name, None))
|
InstallRequirement.from_line(name, None))
|
||||||
|
|
|
@ -13,6 +13,11 @@ class DistributionNotFound(InstallationError):
|
||||||
"""Raised when a distribution cannot be found to satisfy a requirement"""
|
"""Raised when a distribution cannot be found to satisfy a requirement"""
|
||||||
|
|
||||||
|
|
||||||
|
class BestVersionAlreadyInstalled(Exception):
|
||||||
|
"""Raised when the most up-to-date version of a package is already
|
||||||
|
installed.
|
||||||
|
"""
|
||||||
|
|
||||||
class BadCommand(Exception):
|
class BadCommand(Exception):
|
||||||
"""Raised when virtualenv or a command is not found"""
|
"""Raised when virtualenv or a command is not found"""
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import zlib
|
||||||
from pip.log import logger
|
from pip.log import logger
|
||||||
from pip.util import Inf
|
from pip.util import Inf
|
||||||
from pip.util import normalize_name, splitext
|
from pip.util import normalize_name, splitext
|
||||||
from pip.exceptions import DistributionNotFound
|
from pip.exceptions import DistributionNotFound, BestVersionAlreadyInstalled
|
||||||
from pip.backwardcompat import (WindowsError, BytesIO,
|
from pip.backwardcompat import (WindowsError, BytesIO,
|
||||||
Queue, httplib, urlparse,
|
Queue, httplib, urlparse,
|
||||||
URLError, HTTPError, u,
|
URLError, HTTPError, u,
|
||||||
|
@ -172,6 +172,7 @@ class PackageFinder(object):
|
||||||
if applicable_versions[0][1] is Inf:
|
if applicable_versions[0][1] is Inf:
|
||||||
logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
|
logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
|
||||||
% req.satisfied_by.version)
|
% req.satisfied_by.version)
|
||||||
|
raise BestVersionAlreadyInstalled
|
||||||
else:
|
else:
|
||||||
logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
|
logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
|
||||||
% (req.satisfied_by.version, applicable_versions[0][1]))
|
% (req.satisfied_by.version, applicable_versions[0][1]))
|
||||||
|
@ -184,7 +185,7 @@ class PackageFinder(object):
|
||||||
# We have an existing version, and its the best version
|
# We have an existing version, and its the best version
|
||||||
logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
|
logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
|
||||||
% (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
|
% (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
|
||||||
return None
|
raise BestVersionAlreadyInstalled
|
||||||
if len(applicable_versions) > 1:
|
if len(applicable_versions) > 1:
|
||||||
logger.info('Using version %s (newest of versions: %s)' %
|
logger.info('Using version %s (newest of versions: %s)' %
|
||||||
(applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
|
(applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
|
||||||
|
|
25
pip/req.py
25
pip/req.py
|
@ -6,7 +6,8 @@ import zipfile
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
import tempfile
|
import tempfile
|
||||||
from pip.locations import bin_py, running_under_virtualenv
|
from pip.locations import bin_py, running_under_virtualenv
|
||||||
from pip.exceptions import InstallationError, UninstallationError
|
from pip.exceptions import (InstallationError, UninstallationError,
|
||||||
|
BestVersionAlreadyInstalled)
|
||||||
from pip.vcs import vcs
|
from pip.vcs import vcs
|
||||||
from pip.log import logger
|
from pip.log import logger
|
||||||
from pip.util import display_path, rmtree
|
from pip.util import display_path, rmtree
|
||||||
|
@ -776,13 +777,14 @@ class RequirementSet(object):
|
||||||
|
|
||||||
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
|
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
|
||||||
upgrade=False, ignore_installed=False,
|
upgrade=False, ignore_installed=False,
|
||||||
ignore_dependencies=False):
|
ignore_dependencies=False, force_reinstall=False):
|
||||||
self.build_dir = build_dir
|
self.build_dir = build_dir
|
||||||
self.src_dir = src_dir
|
self.src_dir = src_dir
|
||||||
self.download_dir = download_dir
|
self.download_dir = download_dir
|
||||||
self.download_cache = download_cache
|
self.download_cache = download_cache
|
||||||
self.upgrade = upgrade
|
self.upgrade = upgrade
|
||||||
self.ignore_installed = ignore_installed
|
self.ignore_installed = ignore_installed
|
||||||
|
self.force_reinstall = force_reinstall
|
||||||
self.requirements = Requirements()
|
self.requirements = Requirements()
|
||||||
# Mapping of alias: real_name
|
# Mapping of alias: real_name
|
||||||
self.requirement_aliases = {}
|
self.requirement_aliases = {}
|
||||||
|
@ -903,15 +905,32 @@ class RequirementSet(object):
|
||||||
else:
|
else:
|
||||||
req_to_install = reqs.pop(0)
|
req_to_install = reqs.pop(0)
|
||||||
install = True
|
install = True
|
||||||
|
best_installed = False
|
||||||
if not self.ignore_installed and not req_to_install.editable:
|
if not self.ignore_installed and not req_to_install.editable:
|
||||||
req_to_install.check_if_exists()
|
req_to_install.check_if_exists()
|
||||||
if req_to_install.satisfied_by:
|
if req_to_install.satisfied_by:
|
||||||
if self.upgrade:
|
if self.upgrade:
|
||||||
|
if not self.force_reinstall:
|
||||||
|
try:
|
||||||
|
finder.find_requirement(req_to_install,
|
||||||
|
self.uninstall)
|
||||||
|
except BestVersionAlreadyInstalled:
|
||||||
|
best_installed = True
|
||||||
|
install = False
|
||||||
|
except:
|
||||||
|
# Ignore DistributionNotFound for now
|
||||||
|
pass
|
||||||
|
|
||||||
|
if self.force_reinstall or not best_installed:
|
||||||
req_to_install.conflicts_with = req_to_install.satisfied_by
|
req_to_install.conflicts_with = req_to_install.satisfied_by
|
||||||
req_to_install.satisfied_by = None
|
req_to_install.satisfied_by = None
|
||||||
else:
|
else:
|
||||||
install = False
|
install = False
|
||||||
if req_to_install.satisfied_by:
|
if req_to_install.satisfied_by:
|
||||||
|
if best_installed:
|
||||||
|
logger.notify('Requirement already up-to-date: %s'
|
||||||
|
% req_to_install)
|
||||||
|
else:
|
||||||
logger.notify('Requirement already satisfied '
|
logger.notify('Requirement already satisfied '
|
||||||
'(use --upgrade to upgrade): %s'
|
'(use --upgrade to upgrade): %s'
|
||||||
% req_to_install)
|
% req_to_install)
|
||||||
|
@ -1081,7 +1100,7 @@ class RequirementSet(object):
|
||||||
def install(self, install_options, global_options=()):
|
def install(self, install_options, global_options=()):
|
||||||
"""Install everything in this set (after having downloaded and unpacked the packages)"""
|
"""Install everything in this set (after having downloaded and unpacked the packages)"""
|
||||||
to_install = [r for r in self.requirements.values()
|
to_install = [r for r in self.requirements.values()
|
||||||
if self.upgrade or not r.satisfied_by]
|
if (self.upgrade and not r.satisfied_by) or not r.satisfied_by]
|
||||||
|
|
||||||
if to_install:
|
if to_install:
|
||||||
logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install]))
|
logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install]))
|
||||||
|
|
Loading…
Reference in a new issue