mirror of https://github.com/pypa/pip
fix finder version sorting with Inf object
This commit is contained in:
parent
4ea13f474c
commit
93bdb858d8
27
pip/index.py
27
pip/index.py
|
@ -165,7 +165,7 @@ class PackageFinder(object):
|
|||
logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
|
||||
raise DistributionNotFound('No distributions at all found for %s' % req)
|
||||
if req.satisfied_by is not None:
|
||||
found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version))
|
||||
found_versions.append((req.satisfied_by.parsed_version, InfLink, req.satisfied_by.version))
|
||||
if file_versions:
|
||||
file_versions.sort(reverse=True)
|
||||
logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions]))
|
||||
|
@ -177,31 +177,31 @@ class PackageFinder(object):
|
|||
logger.info("Ignoring link %s, version %s doesn't match %s"
|
||||
% (link, version, ','.join([''.join(s) for s in req.req.specs])))
|
||||
continue
|
||||
applicable_versions.append((link, version))
|
||||
applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True)
|
||||
existing_applicable = bool([link for link, version in applicable_versions if link is Inf])
|
||||
applicable_versions.append((parsed_version, link, version))
|
||||
applicable_versions = sorted(applicable_versions, reverse=True)
|
||||
existing_applicable = bool([link for parsed_version, link, version in applicable_versions if link is InfLink])
|
||||
if not upgrade and existing_applicable:
|
||||
if applicable_versions[0][1] is Inf:
|
||||
if applicable_versions[0][1] is InfLink:
|
||||
logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
|
||||
% req.satisfied_by.version)
|
||||
raise BestVersionAlreadyInstalled
|
||||
else:
|
||||
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][2]))
|
||||
return None
|
||||
if not applicable_versions:
|
||||
logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
|
||||
% (req, ', '.join([version for parsed_version, link, version in found_versions])))
|
||||
raise DistributionNotFound('No distributions matching the version for %s' % req)
|
||||
if applicable_versions[0][0] is Inf:
|
||||
if applicable_versions[0][1] is InfLink:
|
||||
# We have an existing version, and its the best version
|
||||
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 parsed_version, link, version in applicable_versions[1:]]) or 'none'))
|
||||
raise BestVersionAlreadyInstalled
|
||||
if len(applicable_versions) > 1:
|
||||
logger.info('Using version %s (newest of versions: %s)' %
|
||||
(applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
|
||||
return applicable_versions[0][0]
|
||||
(applicable_versions[0][2], ', '.join([version for parsed_version, link, version in applicable_versions])))
|
||||
return applicable_versions[0][1]
|
||||
|
||||
|
||||
def _find_url_name(self, index_url, url_name, req):
|
||||
"""Finds the true URL name of a package, when the given name isn't quite correct.
|
||||
|
@ -595,7 +595,7 @@ class Link(object):
|
|||
if self.comes_from:
|
||||
return '%s (from %s)' % (self.url, self.comes_from)
|
||||
else:
|
||||
return self.url
|
||||
return str(self.url)
|
||||
|
||||
def __repr__(self):
|
||||
return '<Link %s>' % self
|
||||
|
@ -673,6 +673,9 @@ class Link(object):
|
|||
def show_url(self):
|
||||
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
|
||||
|
||||
#An "Infinite Link" that compares greater than other links
|
||||
InfLink = Link(Inf)
|
||||
|
||||
|
||||
def get_requirement_from_url(url):
|
||||
"""Get a requirement from the URL, if possible. This looks for #egg
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
from pkg_resources import parse_version
|
||||
from pip.backwardcompat import urllib
|
||||
|
||||
from pip.req import InstallRequirement
|
||||
from pip.index import PackageFinder
|
||||
|
||||
from pip.exceptions import BestVersionAlreadyInstalled
|
||||
from tests.path import Path
|
||||
from tests.test_pip import here
|
||||
from nose.tools import assert_raises
|
||||
from mock import Mock
|
||||
|
||||
find_links = 'file://' + urllib.quote(str(Path(here).abspath/'packages').replace('\\', '/'))
|
||||
find_links2 = 'file://' + urllib.quote(str(Path(here).abspath/'packages2').replace('\\', '/'))
|
||||
|
@ -35,3 +37,41 @@ def test_duplicates_sort_ok():
|
|||
found = finder.find_requirement(req, False)
|
||||
|
||||
assert found.url.endswith("duplicate-1.0.tar.gz"), found
|
||||
|
||||
|
||||
def test_finder_detects_latest_find_links():
|
||||
"""Test PackageFinder detects latest using find-links"""
|
||||
req = InstallRequirement.from_line('simple', None)
|
||||
finder = PackageFinder([find_links], [])
|
||||
link = finder.find_requirement(req, False)
|
||||
assert link.url.endswith("simple-3.0.tar.gz")
|
||||
|
||||
|
||||
def test_finder_detects_latest_already_satisfied_find_links():
|
||||
"""Test PackageFinder detects latest already satisified using find-links"""
|
||||
req = InstallRequirement.from_line('simple', None)
|
||||
#the latest simple in local pkgs is 3.0
|
||||
latest_version = "3.0"
|
||||
satisfied_by = Mock(
|
||||
location = "/path",
|
||||
parsed_version = parse_version(latest_version),
|
||||
version = latest_version
|
||||
)
|
||||
req.satisfied_by = satisfied_by
|
||||
finder = PackageFinder([find_links], [])
|
||||
assert_raises(BestVersionAlreadyInstalled, finder.find_requirement, req, True)
|
||||
|
||||
|
||||
def test_finder_detects_latest_already_satisfied_pypi_links():
|
||||
"""Test PackageFinder detects latest already satisified using pypi links"""
|
||||
req = InstallRequirement.from_line('initools', None)
|
||||
#the latest initools on pypi is 0.3.1
|
||||
latest_version = "0.3.1"
|
||||
satisfied_by = Mock(
|
||||
location = "/path",
|
||||
parsed_version = parse_version(latest_version),
|
||||
version = latest_version
|
||||
)
|
||||
req.satisfied_by = satisfied_by
|
||||
finder = PackageFinder([], ["http://pypi.python.org/simple"])
|
||||
assert_raises(BestVersionAlreadyInstalled, finder.find_requirement, req, True)
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
from pip.backwardcompat import urllib
|
||||
from tests.path import Path
|
||||
from pip.index import package_to_requirement, HTMLPage, get_mirrors, DEFAULT_MIRROR_HOSTNAME
|
||||
from pip.index import PackageFinder
|
||||
from pip.index import PackageFinder, Link, InfLink
|
||||
from tests.test_pip import reset_env, run_pip, pyversion, here
|
||||
from string import ascii_lowercase
|
||||
from mock import patch
|
||||
|
@ -101,3 +101,7 @@ def test_file_index_url_quoting():
|
|||
assert (env.site_packages/'simple') in result.files_created, str(result.stdout)
|
||||
assert (env.site_packages/'simple-1.0-py%s.egg-info' % pyversion) in result.files_created, str(result)
|
||||
|
||||
|
||||
def test_inflink_greater():
|
||||
"""Test InfLink compares greater."""
|
||||
assert InfLink > Link(object())
|
||||
|
|
|
@ -49,11 +49,12 @@ def test_upgrade_with_newest_already_installed():
|
|||
not be reinstalled and the user should be informed.
|
||||
"""
|
||||
|
||||
find_links = 'file://' + join(here, 'packages')
|
||||
env = reset_env()
|
||||
run_pip('install', 'INITools')
|
||||
result = run_pip('install', '--upgrade', 'INITools')
|
||||
assert not result.files_created, 'pip install --upgrade INITools upgraded when it should not have'
|
||||
assert 'already up-to-date' in result.stdout
|
||||
run_pip('install', '-f', find_links, '--no-index', 'simple')
|
||||
result = run_pip('install', '--upgrade', '-f', find_links, '--no-index', 'simple')
|
||||
assert not result.files_created, 'simple upgraded when it should not have'
|
||||
assert 'already up-to-date' in result.stdout, result.stdout
|
||||
|
||||
|
||||
def test_upgrade_force_reinstall_newest():
|
||||
|
|
Loading…
Reference in New Issue