Commit f95da2a3 authored by PJ Eby's avatar PJ Eby

PyPI searches now use the exact spelling of requirements specified on

the command line or in a project's ``install_requires``.  Previously, a
normalized form of the name was used, which could lead to unnecessary
full-index searches when a project's name had an underscore (``_``)
in it.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041942
parent 5d732201
......@@ -962,6 +962,12 @@ Known Issues
* There's no automatic retry for borked Sourceforge mirrors, which can easily
time out or be missing a file.
0.6a10
* PyPI searches now use the exact spelling of requirements specified on the
command line or in a project's ``install_requires``. Previously, a
normalized form of the name was used, which could lead to unnecessary
full-index searches when a project's name had an underscore (``_``) in it.
0.6a9
* Fixed ``.pth`` file processing picking up nested eggs (i.e. ones inside
......
......@@ -1529,8 +1529,8 @@ def yield_lines(strs):
LINE_END = re.compile(r"\s*(#.*)?$").match # whitespace and comment
CONTINUE = re.compile(r"\s*\\\s*(#.*)?$").match # line continuation
DISTRO = re.compile(r"\s*(\w+)").match # Distribution or option
VERSION = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|\.)+)").match # version info
DISTRO = re.compile(r"\s*((\w|-)+)").match # Distribution or option
VERSION = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)").match # ver. info
COMMA = re.compile(r"\s*,").match # comma between items
OBRACKET = re.compile(r"\s*\[").match
CBRACKET = re.compile(r"\s*\]").match
......@@ -1982,7 +1982,7 @@ def parse_requirements(strs):
while not TERMINATOR(line,p):
if CONTINUE(line,p):
try:
line = lines.next().replace('-','_'); p = 0
line = lines.next(); p = 0
except StopIteration:
raise ValueError(
"\\ must not appear on the last nonblank line"
......@@ -2008,7 +2008,6 @@ def parse_requirements(strs):
return line, p, items
for line in lines:
line = line.replace('-','_')
match = DISTRO(line)
if not match:
raise ValueError("Missing distribution spec", line)
......@@ -2024,8 +2023,8 @@ def parse_requirements(strs):
)
line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec")
specs = [(op,val.replace('_','-')) for op,val in specs]
yield Requirement(project_name.replace('_','-'), specs, extras)
specs = [(op,safe_version(val)) for op,val in specs]
yield Requirement(project_name, specs, extras)
def _sort_dists(dists):
......@@ -2048,9 +2047,11 @@ def _sort_dists(dists):
class Requirement:
def __init__(self, project_name, specs, extras):
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
self.unsafe_name, project_name = project_name, safe_name(project_name)
self.project_name, self.key = project_name, project_name.lower()
index = [(parse_version(v),state_machine[op],op,v) for op,v in specs]
index.sort()
......@@ -2068,8 +2069,6 @@ class Requirement:
if extras: extras = '[%s]' % extras
return '%s%s%s' % (self.project_name, extras, specs)
def __repr__(self): return "Requirement.parse(%r)" % str(self)
def __eq__(self,other):
return isinstance(other,Requirement) and self.hashCmp==other.hashCmp
......@@ -2089,9 +2088,12 @@ class Requirement:
if last is None: last = True # no rules encountered
return last
def __hash__(self):
return self.__hash
def __repr__(self): return "Requirement.parse(%r)" % str(self)
#@staticmethod
def parse(s):
reqs = list(parse_requirements(s))
......@@ -2103,7 +2105,6 @@ class Requirement:
parse = staticmethod(parse)
state_machine = {
# =><
'<' : '--T',
......@@ -2122,7 +2123,6 @@ def _get_mro(cls):
return cls.__mro__[1:]
return cls.__mro__
def _find_adapter(registry, ob):
"""Return an adapter factory for `ob` from `registry`"""
for t in _get_mro(getattr(ob, '__class__', type(ob))):
......
......@@ -245,12 +245,16 @@ class PackageIndex(Environment):
def find_packages(self, requirement):
self.scan_url(self.index_url + requirement.project_name+'/')
self.scan_url(self.index_url + requirement.unsafe_name+'/')
if not self.package_pages.get(requirement.key):
# Fall back to safe version of the name
self.scan_url(self.index_url + requirement.project_name+'/')
if not self.package_pages.get(requirement.key):
# We couldn't find the target package, so search the index page too
self.warn(
"Couldn't find index page for %r (maybe misspelled?)",
requirement.project_name
requirement.unsafe_name
)
if self.index_url not in self.fetched_urls:
self.warn(
......@@ -281,10 +285,6 @@ class PackageIndex(Environment):
"; possible download problem?"
)
def download(self, spec, tmpdir):
"""Locate and/or download `spec` to `tmpdir`, returning a local path
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment