Commit 61a0e710 authored by PJ Eby's avatar PJ Eby

The ``path`` attribute of ``Distribution`` objects is now ``location``,

because it isn't necessarily a filesystem path (and hasn't been for some
time now).  ``Distribution`` objects now have an ``as_requirement()``
method that returns a ``Requirement`` for the distribution's project name
and version.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041134
parent 63d507ad
......@@ -311,7 +311,7 @@ class AvailableDistributions(object):
path = sys.path
distros = self.get(requirement.key, ())
find = dict([(dist.path,dist) for dist in distros]).get
find = dict([(dist.location,dist) for dist in distros]).get
for item in path:
dist = find(item)
......@@ -1314,16 +1314,15 @@ class Distribution(object):
"""Wrap an actual or potential sys.path entry w/metadata"""
def __init__(self,
path_str, metadata=None, project_name=None, version=None,
location, metadata=None, project_name=None, version=None,
py_version=PY_MAJOR, platform=None, distro_type = EGG_DIST
):
if project_name:
self.project_name = safe_name(project_name)
self.project_name = safe_name(project_name or 'Unknown')
if version is not None:
self._version = safe_version(version)
self.py_version = py_version
self.platform = platform
self.path = path_str
self.location = location
self.distro_type = distro_type
self._provider = metadata or empty_provider
......@@ -1331,23 +1330,24 @@ class Distribution(object):
"""Is this distro installed on `path`? (defaults to ``sys.path``)"""
if path is None:
path = sys.path
return self.path in path
return self.location in path
#@classmethod
def from_filename(cls,filename,metadata=None):
name,version,py_version,platform = [None]*4
basename,ext = os.path.splitext(os.path.basename(filename))
def from_location(cls,location,basename,metadata=None):
project_name, version, py_version, platform = [None]*4
basename, ext = os.path.splitext(basename)
if ext.lower()==".egg":
match = EGG_NAME(basename)
if match:
project_name,version,py_version,platform = match.group(
project_name, version, py_version, platform = match.group(
'name','ver','pyver','plat'
)
return cls(
filename, metadata, project_name=project_name, version=version,
location, metadata, project_name=project_name, version=version,
py_version=py_version, platform=platform
)
from_filename = classmethod(from_filename)
from_location = classmethod(from_location)
......@@ -1405,17 +1405,18 @@ class Distribution(object):
_dep_map = property(_dep_map)
def depends(self,options=()):
def depends(self,extras=()):
"""List of Requirements needed for this distro if `options` are used"""
dm = self._dep_map
deps = []
deps.extend(dm.get(None,()))
for opt in options:
for ext in extras:
try:
deps.extend(dm[opt.lower()])
deps.extend(dm[ext.lower()])
except KeyError:
raise InvalidOption("No such option", self, opt)
raise InvalidOption(
"%s has no such extra feature %r" % (self, ext)
)
return deps
def _get_metadata(self,name):
......@@ -1426,13 +1427,12 @@ class Distribution(object):
def install_on(self,path=None):
"""Ensure distribution is importable on `path` (default=sys.path)"""
if path is None: path = sys.path
if self.path not in path:
path.append(self.path)
if self.location not in path:
path.append(self.location)
if path is sys.path:
fixup_namespace_packages(self.path)
fixup_namespace_packages(self.location)
map(declare_namespace, self._get_metadata('namespace_packages.txt'))
def egg_name(self):
"""Return what this distribution's standard .egg filename should be"""
filename = "%s-%s-py%s" % (
......@@ -1446,7 +1446,7 @@ class Distribution(object):
return filename
def __repr__(self):
return "%s (%s)" % (self,self.path)
return "%s (%s)" % (self,self.location)
def __str__(self):
version = getattr(self,'version',None) or "[unknown version]"
......@@ -1458,10 +1458,13 @@ class Distribution(object):
raise AttributeError,attr
return getattr(self._provider, attr)
#@classmethod
def from_filename(cls,filename,metadata=None):
return cls.from_location(filename, os.path.basename(filename), metadata)
from_filename = classmethod(from_filename)
def as_requirement(self):
return Requirement.parse('%s==%s' % (dist.project_name, dist.version))
......
......@@ -1352,6 +1352,13 @@ Release Notes/Change History
attribute for the project name they refer to. (Previously these were
``name`` and ``distname`` attributes.)
* The ``path`` attribute of ``Distribution`` objects is now ``location``,
because it isn't necessarily a filesystem path (and hasn't been for some
time now).
* ``Distribution`` objects now have an ``as_requirement()`` method that
returns a ``Requirement`` for the distribution's project name and version.
0.5a13
* Fixed a bug in resource extraction from nested packages in a zipped egg.
......
#!python
"""\
Easy Install
------------
......@@ -17,7 +16,8 @@ from setuptools import Command
from setuptools.sandbox import run_setup
from distutils import log, dir_util
from distutils.sysconfig import get_python_lib
from distutils.errors import DistutilsArgError, DistutilsOptionError, DistutilsError
from distutils.errors import DistutilsArgError, DistutilsOptionError, \
DistutilsError
from setuptools.archive_util import unpack_archive
from setuptools.package_index import PackageIndex, parse_bdist_wininst
from setuptools.package_index import URL_SCHEME
......@@ -350,7 +350,7 @@ class easy_install(Command):
self.install_egg_scripts(dist)
log.warn(self.installation_report(dist, *info))
if requirement is None:
requirement = Requirement.parse('%s==%s'%(dist.project_name,dist.version))
requirement = dist.as_requirement()
if dist in requirement:
log.info("Processing dependencies for %s", requirement)
try:
......@@ -419,7 +419,7 @@ class easy_install(Command):
options = match.group(1) or ''
if options:
options = ' '+options
spec = '%s==%s' % (dist.project_name,dist.version)
spec = dist.as_requirement()
executable = os.path.normpath(sys.executable)
if dev_path:
......@@ -547,7 +547,7 @@ class easy_install(Command):
)
# Convert the .exe to an unpacked egg
egg_path = dist.path = os.path.join(tmpdir, dist.egg_name()+'.egg')
egg_path = dist.location = os.path.join(tmpdir, dist.egg_name()+'.egg')
egg_tmp = egg_path+'.tmp'
pkg_inf = os.path.join(egg_tmp, 'EGG-INFO', 'PKG-INFO')
ensure_directory(pkg_inf) # make sure EGG-INFO dir exists
......@@ -718,7 +718,7 @@ Note also that the installation directory must be on sys.path at runtime for
this to work. (e.g. by being the application's script directory, by being on
PYTHONPATH, or by being added to sys.path by your code.)
"""
eggloc = dist.path
eggloc = dist.location
name = dist.project_name
version = dist.version
return msg % locals()
......@@ -782,14 +782,14 @@ PYTHONPATH, or by being added to sys.path by your code.)
return
for d in self.pth_file.get(dist.key,()): # drop old entries
if self.multi_version or normalize(d.path) != normalize(dist.path):
if self.multi_version or normalize(d.location) != normalize(dist.location):
log.info("Removing %s from easy-install.pth file", d)
self.pth_file.remove(d)
if normalize(d.path) in self.shadow_path:
self.shadow_path.remove(d.path)
if normalize(d.location) in self.shadow_path:
self.shadow_path.remove(d.location)
if not self.multi_version:
if normalize(dist.path) in map(normalize,self.pth_file.paths):
if normalize(dist.location) in map(normalize,self.pth_file.paths):
log.info(
"%s is already the active version in easy-install.pth",
dist
......@@ -797,8 +797,8 @@ PYTHONPATH, or by being added to sys.path by your code.)
else:
log.info("Adding %s to easy-install.pth file", dist)
self.pth_file.add(dist) # add new entry
if normalize(dist.path) not in self.shadow_path:
self.shadow_path.append(normalize(dist.path))
if normalize(dist.location) not in self.shadow_path:
self.shadow_path.append(normalize(dist.location))
self.pth_file.save()
......@@ -806,7 +806,7 @@ PYTHONPATH, or by being added to sys.path by your code.)
# Ensure that setuptools itself never becomes unavailable!
# XXX should this check for latest version?
f = open(os.path.join(self.install_dir,'setuptools.pth'), 'w')
f.write(dist.path+'\n')
f.write(dist.location+'\n')
f.close()
......@@ -1051,14 +1051,14 @@ class PthDistributions(AvailableDistributions):
def add(self,dist):
"""Add `dist` to the distribution map"""
if dist.path not in self.paths:
self.paths.append(dist.path); self.dirty = True
if dist.location not in self.paths:
self.paths.append(dist.location); self.dirty = True
AvailableDistributions.add(self,dist)
def remove(self,dist):
"""Remove `dist` from the distribution map"""
while dist.path in self.paths:
self.paths.remove(dist.path); self.dirty = True
while dist.location in self.paths:
self.paths.remove(dist.location); self.dirty = True
AvailableDistributions.remove(self,dist)
......
......@@ -52,10 +52,8 @@ def distros_for_filename(url_or_path, basename, metadata=None):
if basename.endswith('.egg.zip'):
basename = basename[:-4] # strip the .zip
if basename.endswith('.egg'):
dist = Distribution.from_filename(basename, metadata)
dist.path = url_or_path
return [dist] # only one, unambiguous interpretation
if basename.endswith('.egg'): # only one, unambiguous interpretation
return [Distribution.from_location(url_or_path, basename, metadata)]
if basename.endswith('.exe'):
win_base, py_ver = parse_bdist_wininst(basename)
......@@ -80,6 +78,8 @@ def distros_for_filename(url_or_path, basename, metadata=None):
def interpret_distro_name(url_or_path, basename, metadata,
py_version=None, distro_type=SOURCE_DIST, platform=None
):
......
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