Commit ca9ccbf6 authored by PJ Eby's avatar PJ Eby

The ``--always-copy`` option now skips "system" and "development" eggs

since they can't be reliably copied.  Note that this may cause EasyInstall
to choose an older version of a package than what you expected, or it may
cause downloading and installation of a fresh version of what's already
installed.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4042260
parent 48dd1efa
......@@ -589,6 +589,14 @@ Command-Line Options
from other sys.path directories to the installation directory, unless you
explicitly gave the distribution's filename on the command line.
Note that as of 0.6a10, using this option excludes "system" and
"development" eggs from consideration because they can't be reliably
copied. This may cause EasyInstall to choose an older version of a package
than what you expected, or it may cause downloading and installation of a
fresh copy of something that's already installed. You will see warning
messages for any eggs that EasyInstall skips, before it falls back to an
older version or attempts to download a fresh copy.
``--find-links=URL, -f URL`` (Option renamed in 0.4a2)
Scan the specified "download pages" for direct links to downloadable eggs
or source distributions. Any usable packages will be downloaded if they
......@@ -982,6 +990,11 @@ Known Issues
linking to them (e.g. from within their own PyPI page or download links
page).
* The ``--always-copy`` option now skips "system" and "development" eggs since
they can't be reliably copied. Note that this may cause EasyInstall to
choose an older version of a package than what you expected, or it may cause
downloading and installation of a fresh version of what's already installed.
0.6a9
* Fixed ``.pth`` file processing picking up nested eggs (i.e. ones inside
"baskets") when they weren't explicitly listed in the ``.pth`` file.
......
......@@ -305,27 +305,27 @@ class easy_install(Command):
spec = parse_requirement_arg(spec)
self.check_editable(spec)
download = self.package_index.fetch(
spec, tmpdir, self.upgrade, self.editable
dist = self.package_index.fetch_distribution(
spec, tmpdir, self.upgrade, self.editable, not self.always_copy
)
if download is None:
raise DistutilsError(
"Could not find distribution for %r" % spec
)
return self.install_item(spec, download, tmpdir, deps)
if dist is None:
msg = "Could not find suitable distribution for %r" % spec
if self.always_copy:
msg+=" (--always-copy skips system and development eggs)"
raise DistutilsError(msg)
elif dist.precedence==DEVELOP_DIST:
# .egg-info dists don't need installing, just process deps
self.process_distribution(spec, dist, deps, "Using")
return dist
else:
return self.install_item(spec, dist.location, tmpdir, deps)
finally:
if os.path.exists(tmpdir):
rmtree(tmpdir)
def install_item(self, spec, download, tmpdir, deps, install_needed=False):
# Installation is also needed if file in tmpdir or is not an egg
......
......@@ -337,12 +337,12 @@ class PackageIndex(Environment):
automatically created alongside the downloaded file.
If `spec` is a ``Requirement`` object or a string containing a
project/version requirement spec, this method is equivalent to
the ``fetch()`` method. If `spec` is a local, existing file or
directory name, it is simply returned unchanged. If `spec` is a URL,
it is downloaded to a subpath of `tmpdir`, and the local filename is
returned. Various errors may be raised if a problem occurs during
downloading.
project/version requirement spec, this method returns the location of
a matching distribution (possibly after downloading it to `tmpdir`).
If `spec` is a locally existing file or directory name, it is simply
returned unchanged. If `spec` is a URL, it is downloaded to a subpath
of `tmpdir`, and the local filename is returned. Various errors may be
raised if a problem occurs during downloading.
"""
if not isinstance(spec,Requirement):
scheme = URL_SCHEME(spec)
......@@ -364,31 +364,49 @@ class PackageIndex(Environment):
"Not a URL, existing file, or requirement spec: %r" %
(spec,)
)
return self.fetch(spec, tmpdir)
return getattr(self.fetch_distribution(spec, tmpdir),'location',None)
def fetch(self, requirement, tmpdir, force_scan=False, source=False):
"""Obtain a file suitable for fulfilling `requirement`
def fetch_distribution(self,
requirement, tmpdir, force_scan=False, source=False, develop_ok=False
):
"""Obtain a distribution suitable for fulfilling `requirement`
`requirement` must be a ``pkg_resources.Requirement`` instance.
If necessary, or if the `force_scan` flag is set, the requirement is
searched for in the (online) package index as well as the locally
installed packages. If a distribution matching `requirement` is found,
the return value is the same as if you had called the ``download()``
method with the matching distribution's URL. If no matching
distribution is found, returns ``None``.
the returned distribution's ``location`` is the value you would have
gotten from calling the ``download()`` method with the matching
distribution's URL or filename. If no matching distribution is found,
``None`` is returned.
If the `source` flag is set, only source distributions and source
checkout links will be considered.
checkout links will be considered. Unless the `develop_ok` flag is
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 = {}
def find(req):
# Find a matching distribution; may be called more than once
for dist in self[req.key]:
if dist.precedence==DEVELOP_DIST and not develop_ok:
if dist not in skipped:
self.warn("Skipping development or system egg: %s",dist)
skipped[dist] = 1
continue
if dist in req and (dist.precedence<=SOURCE_DIST or not source):
self.info("Best match: %s", dist)
return self.download(dist.location, tmpdir)
return dist.clone(
location=self.download(dist.location, tmpdir)
)
if force_scan:
self.find_packages(requirement)
......@@ -407,6 +425,29 @@ class PackageIndex(Environment):
)
return dist
def fetch(self, requirement, tmpdir, force_scan=False, source=False):
"""Obtain a file suitable for fulfilling `requirement`
DEPRECATED; use the ``fetch_distribution()`` method now instead. For
backward compatibility, this routine is identical but returns the
``location`` of the downloaded distribution instead of a distribution
object.
"""
dist = self.fetch_dist(requirement,tmpdir,force_scan,source)
if dist is not None:
return dist.location
return None
def gen_setup(self, filename, fragment, tmpdir):
match = EGG_FRAGMENT.match(fragment); #import pdb; pdb.set_trace()
......
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