Permalink
Browse files

fix finder version sorting with Inf object

  • Loading branch information...
1 parent 4ea13f4 commit 93bdb858d87c5814b9af42fe6ba41b3d902b43ba @qwcode committed Sep 23, 2012
Showing with 67 additions and 19 deletions.
  1. +15 −12 pip/index.py
  2. +42 −2 tests/test_finder.py
  3. +5 −1 tests/test_index.py
  4. +5 −4 tests/test_upgrade.py
View
@@ -165,7 +165,7 @@ def mkurl_pypi_url(url):
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 @@ def mkurl_pypi_url(url):
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 @@ def __str__(self):
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 @@ def hash_name(self):
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
View
@@ -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)
View
@@ -2,7 +2,7 @@
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())
View
@@ -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():

0 comments on commit 93bdb85

Please sign in to comment.