aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/package_index.py
diff options
context:
space:
mode:
authorPJ Eby <distutils-sig@python.org>2009-10-12 20:00:02 +0000
committerPJ Eby <distutils-sig@python.org>2009-10-12 20:00:02 +0000
commit9294929b0028f551a54dd48cc3325581933b3c5f (patch)
treee07221c46c7f32ac39160b3f2cb50e649cd5cc2e /setuptools/package_index.py
parent20a0abd3d0f10198d6c21033ad2c11db2edbad71 (diff)
downloadexternal_python_setuptools-9294929b0028f551a54dd48cc3325581933b3c5f.tar.gz
external_python_setuptools-9294929b0028f551a54dd48cc3325581933b3c5f.tar.bz2
external_python_setuptools-9294929b0028f551a54dd48cc3325581933b3c5f.zip
Major updates and fixes include:
* Fix for the Python 2.6.3 build_ext API change * Support for the most recent Sourceforge download link insanity * Support for SVN 1.6 * Stop crashing on certain types of HTTP error * Stop re-trying URLs that already failed retrieval once * Fixes for various dependency management problems such as looping builds, re-downloading packages already present on sys.path (but not in a registered "site" directory), and randomly preferring local -f packages over local installed packages * Prevent lots of spurious "already imported from another path" warnings (e.g. when pkg_resources is imported late) * Ensure C libraries (as opposed to extensions) are also built when doing bdist_egg Other changes: * Misc. documentation fixes * Improved Jython support * Fewer warnings under Python 2.6+ * Warn when 'packages' uses paths instead of package names (because it causes other problems, like spurious "already imported" warnings) * Stop using /usr/bin/sw_vers on Mac OS (replaced w/'platform' module calls) Note: This is NOT a merge from Distribute; upon review, many of the tracker-submitted patches used as a basis for forking were incorrect, incomplete, introduced new bugs, or were not addressing the root causes. (E.g., one of the changes in this patch fixes three superficially unrelated issues in the setuptools bug tracker.) Careful review will be required if you want to merge this work back into Distribute. --HG-- branch : setuptools-0.6 extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/branches/setuptools-0.6%4075385
Diffstat (limited to 'setuptools/package_index.py')
-rwxr-xr-xsetuptools/package_index.py62
1 files changed, 31 insertions, 31 deletions
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index da3fed12..70b75a6f 100755
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -1,5 +1,6 @@
"""PyPI and direct package downloading"""
import sys, os.path, re, urlparse, urllib2, shutil, random, socket, cStringIO
+import httplib
from pkg_resources import *
from distutils import log
from distutils.errors import DistutilsError
@@ -8,7 +9,6 @@ try:
except ImportError:
from md5 import md5
from fnmatch import translate
-
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$')
HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I)
# this is here to fix emacs' cruddy broken syntax highlighting
@@ -42,6 +42,8 @@ def parse_bdist_wininst(name):
def egg_info_for_url(url):
scheme, server, path, parameters, query, fragment = urlparse.urlparse(url)
base = urllib2.unquote(path.split('/')[-1])
+ if server=='sourceforge.net' and base=='download': # XXX Yuck
+ base = urllib2.unquote(path.split('/')[-2])
if '#' in base: base, fragment = base.split('#',1)
return base,fragment
@@ -64,14 +66,12 @@ def distros_for_location(location, basename, metadata=None):
if basename.endswith('.egg') and '-' in basename:
# only one, unambiguous interpretation
return [Distribution.from_location(location, basename, metadata)]
-
if basename.endswith('.exe'):
win_base, py_ver = parse_bdist_wininst(basename)
if win_base is not None:
return interpret_distro_name(
location, win_base, metadata, py_ver, BINARY_DIST, "win32"
)
-
# Try source distro extensions (.zip, .tgz, etc.)
#
for ext in EXTENSIONS:
@@ -186,10 +186,10 @@ class PackageIndex(Environment):
return
self.info("Reading %s", url)
+ self.fetched_urls[url] = True # prevent multiple fetch attempts
f = self.open_url(url, "Download error: %s -- Some packages may not be found!")
if f is None: return
- self.fetched_urls[url] = self.fetched_urls[f.url] = True
-
+ self.fetched_urls[f.url] = True
if 'html' not in f.headers.get('content-type', '').lower():
f.close() # not html, we can't process it
return
@@ -329,7 +329,7 @@ class PackageIndex(Environment):
def check_md5(self, cs, info, filename, tfp):
if re.match('md5=[0-9a-f]{32}$', info):
self.debug("Validating md5 checksum for %s", filename)
- if cs.hexdigest()<>info[4:]:
+ if cs.hexdigest()!=info[4:]:
tfp.close()
os.unlink(filename)
raise DistutilsError(
@@ -409,7 +409,8 @@ class PackageIndex(Environment):
def fetch_distribution(self,
- requirement, tmpdir, force_scan=False, source=False, develop_ok=False
+ requirement, tmpdir, force_scan=False, source=False, develop_ok=False,
+ local_index=None,
):
"""Obtain a distribution suitable for fulfilling `requirement`
@@ -427,15 +428,15 @@ class PackageIndex(Environment):
set, development and system eggs (i.e., those using the ``.egg-info``
format) will be ignored.
"""
-
# process a Requirement
self.info("Searching for %s", requirement)
skipped = {}
+ dist = None
- def find(req):
+ def find(env, req):
# Find a matching distribution; may be called more than once
- for dist in self[req.key]:
+ for dist in env[req.key]:
if dist.precedence==DEVELOP_DIST and not develop_ok:
if dist not in skipped:
@@ -444,23 +445,25 @@ class PackageIndex(Environment):
continue
if dist in req and (dist.precedence<=SOURCE_DIST or not source):
- self.info("Best match: %s", dist)
- return dist.clone(
- location=self.download(dist.location, tmpdir)
- )
+ return dist
+
+
if force_scan:
self.prescan()
self.find_packages(requirement)
+ dist = find(self, requirement)
+
+ if local_index is not None:
+ dist = dist or find(local_index, requirement)
- dist = find(requirement)
if dist is None and self.to_scan is not None:
self.prescan()
- dist = find(requirement)
+ dist = find(self, requirement)
if dist is None and not force_scan:
self.find_packages(requirement)
- dist = find(requirement)
+ dist = find(self, requirement)
if dist is None:
self.warn(
@@ -468,7 +471,9 @@ class PackageIndex(Environment):
(source and "a source distribution of " or ""),
requirement,
)
- return dist
+ self.info("Best match: %s", dist)
+ return dist.clone(location=self.download(dist.location, tmpdir))
+
def fetch(self, requirement, tmpdir, force_scan=False, source=False):
"""Obtain a file suitable for fulfilling `requirement`
@@ -485,11 +490,6 @@ class PackageIndex(Environment):
-
-
-
-
-
def gen_setup(self, filename, fragment, tmpdir):
match = EGG_FRAGMENT.match(fragment)
dists = match and [d for d in
@@ -573,17 +573,19 @@ class PackageIndex(Environment):
def open_url(self, url, warning=None):
- if url.startswith('file:'):
- return local_open(url)
+ if url.startswith('file:'): return local_open(url)
try:
return open_with_auth(url)
except urllib2.HTTPError, v:
return v
except urllib2.URLError, v:
- if warning: self.warn(warning, v.reason)
- else:
- raise DistutilsError("Download error for %s: %s"
- % (url, v.reason))
+ reason = v.reason
+ except httplib.HTTPException, v:
+ reason = "%s: %s" % (v.__doc__ or v.__class__.__name__, v)
+ if warning:
+ self.warn(warning, reason)
+ else:
+ raise DistutilsError("Download error for %s: %s" % (url, reason))
def _download_url(self, scheme, url, tmpdir):
# Determine download filename
@@ -611,8 +613,6 @@ class PackageIndex(Environment):
self.url_ok(url, True) # raises error if not allowed
return self._attempt_download(url, filename)
-
-
def scan_url(self, url):
self.process_url(url, True)