Skip to content

Commit 32f0be7

Browse files
committed
Merge pull request pypa#702 from qwcode/link_sort2
put back finder link priority (with tests)
2 parents f54f422 + c770ad6 commit 32f0be7

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

pip/index.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def sort_path(path):
101101
return files, urls
102102

103103
def find_requirement(self, req, upgrade):
104+
104105
def mkurl_pypi_url(url):
105106
loc = posixpath.join(url, url_name)
106107
# For maximum compatibility with easy_install, ensure the path
@@ -165,21 +166,23 @@ def mkurl_pypi_url(url):
165166
if not found_versions and not page_versions and not dependency_versions and not file_versions:
166167
logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
167168
raise DistributionNotFound('No distributions at all found for %s' % req)
169+
installed_version = []
168170
if req.satisfied_by is not None:
169-
found_versions.append((req.satisfied_by.parsed_version, InfLink, req.satisfied_by.version))
171+
installed_version = [(req.satisfied_by.parsed_version, InfLink, req.satisfied_by.version)]
170172
if file_versions:
171173
file_versions.sort(reverse=True)
172174
logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions]))
173-
found_versions = file_versions + found_versions
174-
all_versions = found_versions + page_versions + dependency_versions
175+
#this is an intentional priority ordering
176+
all_versions = installed_version + file_versions + found_versions + page_versions + dependency_versions
175177
applicable_versions = []
176178
for (parsed_version, link, version) in all_versions:
177179
if version not in req.req:
178180
logger.info("Ignoring link %s, version %s doesn't match %s"
179181
% (link, version, ','.join([''.join(s) for s in req.req.specs])))
180182
continue
181183
applicable_versions.append((parsed_version, link, version))
182-
applicable_versions = sorted(applicable_versions, reverse=True)
184+
#bring the latest version to the front, but maintains the priority ordering as secondary
185+
applicable_versions = sorted(applicable_versions, key=lambda v: v[0], reverse=True)
183186
existing_applicable = bool([link for parsed_version, link, version in applicable_versions if link is InfLink])
184187
if not upgrade and existing_applicable:
185188
if applicable_versions[0][1] is InfLink:
@@ -191,7 +194,7 @@ def mkurl_pypi_url(url):
191194
return None
192195
if not applicable_versions:
193196
logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
194-
% (req, ', '.join([version for parsed_version, link, version in found_versions])))
197+
% (req, ', '.join([version for parsed_version, link, version in all_versions])))
195198
raise DistributionNotFound('No distributions matching the version for %s' % req)
196199
if applicable_versions[0][1] is InfLink:
197200
# We have an existing version, and its the best version
@@ -675,7 +678,7 @@ def show_url(self):
675678
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
676679

677680
#An "Infinite Link" that compares greater than other links
678-
InfLink = Link(Inf)
681+
InfLink = Link(Inf) #this object is not currently used as a sortable
679682

680683

681684
def get_requirement_from_url(url):

pip/util.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ def __ge__(self, other):
161161
def __repr__(self):
162162
return 'Inf'
163163

164-
Inf = _Inf()
164+
165+
Inf = _Inf() #this object is not currently used as a sortable in our code
165166
del _Inf
166167

167168

tests/test_finder.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,38 @@ def test_finder_detects_latest_already_satisfied_pypi_links():
7575
req.satisfied_by = satisfied_by
7676
finder = PackageFinder([], ["http://pypi.python.org/simple"])
7777
assert_raises(BestVersionAlreadyInstalled, finder.find_requirement, req, True)
78+
79+
80+
def test_finder_priority_file_over_page():
81+
"""Test PackageFinder prefers file links over equivalent page links"""
82+
req = InstallRequirement.from_line('gmpy==1.15', None)
83+
finder = PackageFinder([find_links], ["http://pypi.python.org/simple"])
84+
link = finder.find_requirement(req, False)
85+
assert link.url.startswith("file://")
86+
87+
88+
def test_finder_priority_page_over_deplink():
89+
"""Test PackageFinder prefers page links over equivalent dependency links"""
90+
req = InstallRequirement.from_line('gmpy==1.15', None)
91+
finder = PackageFinder([], ["http://pypi.python.org/simple"])
92+
finder.add_dependency_links(['http://c.pypi.python.org/simple/gmpy/'])
93+
link = finder.find_requirement(req, False)
94+
assert link.url.startswith("http://pypi")
95+
96+
97+
def test_finder_priority_nonegg_over_eggfragments():
98+
"""Test PackageFinder prefers non-egg links over "#egg=" links"""
99+
req = InstallRequirement.from_line('bar==1.0', None)
100+
links = ['http://foo/bar.py#egg=bar-1.0', 'http://foo/bar-1.0.tar.gz']
101+
102+
finder = PackageFinder(links, [])
103+
link = finder.find_requirement(req, False)
104+
assert link.url.endswith('tar.gz')
105+
106+
links.reverse()
107+
finder = PackageFinder(links, [])
108+
link = finder.find_requirement(req, False)
109+
assert link.url.endswith('tar.gz')
110+
111+
112+

0 commit comments

Comments
 (0)