aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2012-11-26 09:20:11 -0500
committerJason R. Coombs <jaraco@jaraco.com>2012-11-26 09:20:11 -0500
commitceb03af882740ae02ef4be004a30b45c7b25b9ce (patch)
treecb576f8a6f5979aedcb3ce0a5b9585059e4f3f59
parentf31fb0ff20c63dd9bb82f91af45c12e97428e38c (diff)
downloadexternal_python_setuptools-ceb03af882740ae02ef4be004a30b45c7b25b9ce.tar.gz
external_python_setuptools-ceb03af882740ae02ef4be004a30b45c7b25b9ce.tar.bz2
external_python_setuptools-ceb03af882740ae02ef4be004a30b45c7b25b9ce.zip
Backed out changeset: 98a9f9dcce0e; Fixes #335.
--HG-- branch : distribute extra : rebase_source : 3f4ff1c880688e6dd72d2fa8fab3c07e7f486a7e
-rw-r--r--pkg_resources.py60
-rw-r--r--setuptools/dist.py5
-rw-r--r--setuptools/tests/test_easy_install.py142
3 files changed, 59 insertions, 148 deletions
diff --git a/pkg_resources.py b/pkg_resources.py
index a39a32dc..a5a10eb4 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -517,7 +517,7 @@ class WorkingSet(object):
seen[key]=1
yield self.by_key[key]
- def add(self, dist, entry=None, insert=True, replace=False):
+ def add(self, dist, entry=None, insert=True):
"""Add `dist` to working set, associated with `entry`
If `entry` is unspecified, it defaults to the ``.location`` of `dist`.
@@ -525,9 +525,8 @@ class WorkingSet(object):
set's ``.entries`` (if it wasn't already present).
`dist` is only added to the working set if it's for a project that
- doesn't already have a distribution in the set, unless `replace=True`.
- If it's added, any callbacks registered with the ``subscribe()`` method
- will be called.
+ doesn't already have a distribution in the set. If it's added, any
+ callbacks registered with the ``subscribe()`` method will be called.
"""
if insert:
dist.insert_on(self.entries, entry)
@@ -536,7 +535,7 @@ class WorkingSet(object):
entry = dist.location
keys = self.entry_keys.setdefault(entry,[])
keys2 = self.entry_keys.setdefault(dist.location,[])
- if not replace and dist.key in self.by_key:
+ if dist.key in self.by_key:
return # ignore hidden distros
self.by_key[dist.key] = dist
@@ -546,8 +545,7 @@ class WorkingSet(object):
keys2.append(dist.key)
self._added_new(dist)
- def resolve(self, requirements, env=None, installer=None,
- replacement=True, replace_conflicting=False):
+ def resolve(self, requirements, env=None, installer=None, replacement=True):
"""List all distributions needed to (recursively) meet `requirements`
`requirements` must be a sequence of ``Requirement`` objects. `env`,
@@ -557,12 +555,6 @@ class WorkingSet(object):
will be invoked with each requirement that cannot be met by an
already-installed distribution; it should return a ``Distribution`` or
``None``.
-
- Unless `replace_conflicting=True`, raises a VersionConflict exception if
- any requirements are found on the path that have the correct name but
- the wrong version. Otherwise, if an `installer` is supplied it will be
- invoked to obtain the correct version of the requirement and activate
- it.
"""
requirements = list(requirements)[::-1] # set up the stack
@@ -582,18 +574,10 @@ class WorkingSet(object):
if dist is None:
# Find the best distribution and add it to the map
dist = self.by_key.get(req.key)
- if dist is None or (dist not in req and replace_conflicting):
- ws = self
+ if dist is None:
if env is None:
- if dist is None:
- env = Environment(self.entries)
- else:
- # Use an empty environment and workingset to avoid
- # any further conflicts with the conflicting
- # distribution
- env = Environment([])
- ws = WorkingSet([])
- dist = best[req.key] = env.best_match(req, ws, installer)
+ env = Environment(self.entries)
+ dist = best[req.key] = env.best_match(req, self, installer)
if dist is None:
#msg = ("The '%s' distribution was not found on this "
# "system, and is required by this application.")
@@ -1814,7 +1798,6 @@ def register_namespace_handler(importer_type, namespace_handler):
def _handle_ns(packageName, path_item):
"""Ensure that named package includes a subpath of path_item (if needed)"""
-
importer = get_importer(path_item)
if importer is None:
return None
@@ -1824,19 +1807,14 @@ def _handle_ns(packageName, path_item):
module = sys.modules.get(packageName)
if module is None:
module = sys.modules[packageName] = types.ModuleType(packageName)
- module.__path__ = []
- _set_parent_ns(packageName)
+ module.__path__ = []; _set_parent_ns(packageName)
elif not hasattr(module,'__path__'):
raise TypeError("Not a package:", packageName)
handler = _find_adapter(_namespace_handlers, importer)
- subpath = handler(importer, path_item, packageName, module)
+ subpath = handler(importer,path_item,packageName,module)
if subpath is not None:
- path = module.__path__
- path.append(subpath)
- loader.load_module(packageName)
- for path_item in path:
- if path_item not in module.__path__:
- module.__path__.append(path_item)
+ path = module.__path__; path.append(subpath)
+ loader.load_module(packageName); module.__path__ = path
return subpath
def declare_namespace(packageName):
@@ -2142,7 +2120,7 @@ def _remove_md5_fragment(location):
class Distribution(object):
"""Wrap an actual or potential sys.path entry w/metadata"""
PKG_INFO = 'PKG-INFO'
-
+
def __init__(self,
location=None, metadata=None, project_name=None, version=None,
py_version=PY_MAJOR, platform=None, precedence = EGG_DIST
@@ -2481,7 +2459,7 @@ class DistInfoDistribution(Distribution):
from email.parser import Parser
self._pkg_info = Parser().parsestr(self.get_metadata(self.PKG_INFO))
return self._pkg_info
-
+
@property
def _dep_map(self):
try:
@@ -2492,7 +2470,7 @@ class DistInfoDistribution(Distribution):
def _preparse_requirement(self, requires_dist):
"""Convert 'Foobar (1); baz' to ('Foobar ==1', 'baz')
- Split environment marker, add == prefix to version specifiers as
+ Split environment marker, add == prefix to version specifiers as
necessary, and remove parenthesis.
"""
parts = requires_dist.split(';', 1) + ['']
@@ -2501,7 +2479,7 @@ class DistInfoDistribution(Distribution):
distvers = re.sub(self.EQEQ, r"\1==\2\3", distvers)
distvers = distvers.replace('(', '').replace(')', '')
return (distvers, mark)
-
+
def _compute_dependencies(self):
"""Recompute this distribution's dependencies."""
from _markerlib import compile as compile_marker
@@ -2514,7 +2492,7 @@ class DistInfoDistribution(Distribution):
parsed = parse_requirements(distvers).next()
parsed.marker_fn = compile_marker(mark)
reqs.append(parsed)
-
+
def reqs_for_extra(extra):
for req in reqs:
if req.marker_fn(override={'extra':extra}):
@@ -2522,13 +2500,13 @@ class DistInfoDistribution(Distribution):
common = frozenset(reqs_for_extra(None))
dm[None].extend(common)
-
+
for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
extra = safe_extra(extra.strip())
dm[extra] = list(frozenset(reqs_for_extra(extra)) - common)
return dm
-
+
_distributionImpl = {'.egg': Distribution,
'.egg-info': Distribution,
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 6236d5be..998a4dbe 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -242,10 +242,9 @@ class Distribution(_Distribution):
"""Resolve pre-setup requirements"""
from pkg_resources import working_set, parse_requirements
for dist in working_set.resolve(
- parse_requirements(requires), installer=self.fetch_build_egg,
- replace_conflicting=True
+ parse_requirements(requires), installer=self.fetch_build_egg
):
- working_set.add(dist, replace=True)
+ working_set.add(dist)
def finalize_options(self):
_Distribution.finalize_options(self)
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index 2f295b5c..b1799a5a 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -17,10 +17,8 @@ from setuptools.command.easy_install import easy_install, get_script_args, main
from setuptools.command.easy_install import PthDistributions
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
-from pkg_resources import working_set, VersionConflict
from pkg_resources import Distribution as PRDistribution
import setuptools.tests.server
-import pkg_resources
try:
# import multiprocessing solely for the purpose of testing its existence
@@ -275,16 +273,48 @@ class TestUserInstallTest(unittest.TestCase):
SandboxViolation.
"""
- test_pkg = create_setup_requires_package(self.dir)
+ test_setup_attrs = {
+ 'name': 'test_pkg', 'version': '0.0',
+ 'setup_requires': ['foobar'],
+ 'dependency_links': [os.path.abspath(self.dir)]
+ }
+
+ test_pkg = os.path.join(self.dir, 'test_pkg')
test_setup_py = os.path.join(test_pkg, 'setup.py')
+ test_setup_cfg = os.path.join(test_pkg, 'setup.cfg')
+ os.mkdir(test_pkg)
+ f = open(test_setup_py, 'w')
+ f.write(textwrap.dedent("""\
+ import setuptools
+ setuptools.setup(**%r)
+ """ % test_setup_attrs))
+ f.close()
+
+ foobar_path = os.path.join(self.dir, 'foobar-0.1.tar.gz')
+ make_trivial_sdist(
+ foobar_path,
+ textwrap.dedent("""\
+ import setuptools
+ setuptools.setup(
+ name='foobar',
+ version='0.1'
+ )
+ """))
+
+ old_stdout = sys.stdout
+ old_stderr = sys.stderr
+ sys.stdout = StringIO.StringIO()
+ sys.stderr = StringIO.StringIO()
try:
- quiet_context(
- lambda: reset_setup_stop_context(
- lambda: run_setup(test_setup_py, ['install'])
- ))
+ reset_setup_stop_context(
+ lambda: run_setup(test_setup_py, ['install'])
+ )
except SandboxViolation:
self.fail('Installation caused SandboxViolation')
+ finally:
+ sys.stdout = old_stdout
+ sys.stderr = old_stderr
class TestSetupRequires(unittest.TestCase):
@@ -330,7 +360,7 @@ class TestSetupRequires(unittest.TestCase):
tempdir_context(install_at)
# create an sdist that has a build-time dependency.
- quiet_context(lambda: self.create_sdist(install))
+ self.create_sdist(install)
# there should have been two or three requests to the server
# (three happens on Python 3.3a)
@@ -357,81 +387,6 @@ class TestSetupRequires(unittest.TestCase):
installer(dist_path)
tempdir_context(build_sdist)
- def test_setup_requires_overrides_version_conflict(self):
- """
- Regression test for issue #323.
-
- Ensures that a distribution's setup_requires requirements can still be
- installed and used locally even if a conflicting version of that
- requirement is already on the path.
- """
-
- pr_state = pkg_resources.__getstate__()
- fake_dist = PRDistribution('does-not-matter', project_name='foobar',
- version='0.0')
- working_set.add(fake_dist)
-
- def setup_and_run(temp_dir):
- test_pkg = create_setup_requires_package(temp_dir)
- test_setup_py = os.path.join(test_pkg, 'setup.py')
- try:
- stdout, stderr = quiet_context(
- lambda: reset_setup_stop_context(
- # Don't even need to install the package, just running
- # the setup.py at all is sufficient
- lambda: run_setup(test_setup_py, ['--name'])
- ))
- except VersionConflict:
- self.fail('Installing setup.py requirements caused '
- 'VersionConflict')
-
- lines = stdout.splitlines()
- self.assertTrue(len(lines) > 0)
- self.assertTrue(lines[-1].strip(), 'test_pkg')
-
- try:
- tempdir_context(setup_and_run)
- finally:
- pkg_resources.__setstate__(pr_state)
-
-
-def create_setup_requires_package(path):
- """Creates a source tree under path for a trivial test package that has a
- single requirement in setup_requires--a tarball for that requirement is
- also created and added to the dependency_links argument.
- """
-
- test_setup_attrs = {
- 'name': 'test_pkg', 'version': '0.0',
- 'setup_requires': ['foobar==0.1'],
- 'dependency_links': [os.path.abspath(path)]
- }
-
- test_pkg = os.path.join(path, 'test_pkg')
- test_setup_py = os.path.join(test_pkg, 'setup.py')
- test_setup_cfg = os.path.join(test_pkg, 'setup.cfg')
- os.mkdir(test_pkg)
-
- f = open(test_setup_py, 'w')
- f.write(textwrap.dedent("""\
- import setuptools
- setuptools.setup(**%r)
- """ % test_setup_attrs))
- f.close()
-
- foobar_path = os.path.join(path, 'foobar-0.1.tar.gz')
- make_trivial_sdist(
- foobar_path,
- textwrap.dedent("""\
- import setuptools
- setuptools.setup(
- name='foobar',
- version='0.1'
- )
- """))
-
- return test_pkg
-
def make_trivial_sdist(dist_path, setup_py):
"""Create a simple sdist tarball at dist_path, containing just a
@@ -466,7 +421,6 @@ def tempdir_context(f, cd=lambda dir:None):
cd(orig_dir)
shutil.rmtree(temp_dir)
-
def environment_context(f, **updates):
"""
Invoke f in the context
@@ -480,7 +434,6 @@ def environment_context(f, **updates):
del os.environ[key]
os.environ.update(old_env)
-
def argv_context(f, repl):
"""
Invoke f in the context
@@ -492,7 +445,6 @@ def argv_context(f, repl):
finally:
sys.argv[:] = old_argv
-
def reset_setup_stop_context(f):
"""
When the distribute tests are run using setup.py test, and then
@@ -506,21 +458,3 @@ def reset_setup_stop_context(f):
f()
finally:
distutils.core._setup_stop_after = setup_stop_after
-
-
-def quiet_context(f):
- """
- Redirect stdout/stderr to StringIO objects to prevent console output from
- distutils commands.
- """
-
- old_stdout = sys.stdout
- old_stderr = sys.stderr
- new_stdout = sys.stdout = StringIO.StringIO()
- new_stderr = sys.stderr = StringIO.StringIO()
- try:
- f()
- finally:
- sys.stdout = old_stdout
- sys.stderr = old_stderr
- return new_stdout.getvalue(), new_stderr.getvalue()