aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/tests/test_easy_install.py
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/tests/test_easy_install.py')
-rw-r--r--setuptools/tests/test_easy_install.py326
1 files changed, 139 insertions, 187 deletions
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index 8dfe234e..5e83831d 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -1,21 +1,23 @@
"""Easy install Tests
"""
+from __future__ import absolute_import
+
import sys
import os
import shutil
import tempfile
-import unittest
import site
import contextlib
-import textwrap
import tarfile
import logging
-import distutils.core
+import itertools
import io
-import six
from six.moves import urllib
+import pytest
+import mock
+from setuptools import sandbox
from setuptools.sandbox import run_setup, SandboxViolation
from setuptools.command.easy_install import (
easy_install, fix_jython_executable, get_script_args, nt_quote_arg)
@@ -26,7 +28,11 @@ from pkg_resources import working_set, VersionConflict
from pkg_resources import Distribution as PRDistribution
import setuptools.tests.server
import pkg_resources
-from .py26compat import skipIf
+
+from .py26compat import tarfile_open
+from . import contexts
+from .textwrap import DALS
+
class FakeDist(object):
def get_entry_map(self, group):
@@ -37,26 +43,26 @@ class FakeDist(object):
def as_requirement(self):
return 'spec'
-WANTED = """\
-#!%s
-# EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name'
-__requires__ = 'spec'
-import sys
-from pkg_resources import load_entry_point
+WANTED = DALS("""
+ #!%s
+ # EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name'
+ __requires__ = 'spec'
+ import sys
+ from pkg_resources import load_entry_point
-if __name__ == '__main__':
- sys.exit(
- load_entry_point('spec', 'console_scripts', 'name')()
- )
-""" % nt_quote_arg(fix_jython_executable(sys.executable, ""))
+ if __name__ == '__main__':
+ sys.exit(
+ load_entry_point('spec', 'console_scripts', 'name')()
+ )
+ """) % nt_quote_arg(fix_jython_executable(sys.executable, ""))
-SETUP_PY = """\
-from setuptools import setup
+SETUP_PY = DALS("""
+ from setuptools import setup
-setup(name='foo')
-"""
+ setup(name='foo')
+ """)
-class TestEasyInstallTest(unittest.TestCase):
+class TestEasyInstallTest:
def test_install_site_py(self):
dist = Distribution()
@@ -66,20 +72,17 @@ class TestEasyInstallTest(unittest.TestCase):
try:
cmd.install_site_py()
sitepy = os.path.join(cmd.install_dir, 'site.py')
- self.assertTrue(os.path.exists(sitepy))
+ assert os.path.exists(sitepy)
finally:
shutil.rmtree(cmd.install_dir)
def test_get_script_args(self):
dist = FakeDist()
- old_platform = sys.platform
- try:
- name, script = [i for i in next(get_script_args(dist))][0:2]
- finally:
- sys.platform = old_platform
+ args = next(get_script_args(dist))
+ name, script = itertools.islice(args, 2)
- self.assertEqual(script, WANTED)
+ assert script == WANTED
def test_no_find_links(self):
# new option '--no-find-links', that blocks find-links added at
@@ -92,7 +95,7 @@ class TestEasyInstallTest(unittest.TestCase):
cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok')
cmd.args = ['ok']
cmd.ensure_finalized()
- self.assertEqual(cmd.package_index.scanned_urls, {})
+ assert cmd.package_index.scanned_urls == {}
# let's try without it (default behavior)
cmd = easy_install(dist)
@@ -102,61 +105,44 @@ class TestEasyInstallTest(unittest.TestCase):
cmd.args = ['ok']
cmd.ensure_finalized()
keys = sorted(cmd.package_index.scanned_urls.keys())
- self.assertEqual(keys, ['link1', 'link2'])
+ assert keys == ['link1', 'link2']
-class TestPTHFileWriter(unittest.TestCase):
+class TestPTHFileWriter:
def test_add_from_cwd_site_sets_dirty(self):
'''a pth file manager should set dirty
if a distribution is in site but also the cwd
'''
pth = PthDistributions('does-not_exist', [os.getcwd()])
- self.assertTrue(not pth.dirty)
+ assert not pth.dirty
pth.add(PRDistribution(os.getcwd()))
- self.assertTrue(pth.dirty)
+ assert pth.dirty
def test_add_from_site_is_ignored(self):
- if os.name != 'nt':
- location = '/test/location/does-not-have-to-exist'
- else:
- location = 'c:\\does_not_exist'
+ location = '/test/location/does-not-have-to-exist'
+ # PthDistributions expects all locations to be normalized
+ location = pkg_resources.normalize_path(location)
pth = PthDistributions('does-not_exist', [location, ])
- self.assertTrue(not pth.dirty)
+ assert not pth.dirty
pth.add(PRDistribution(location))
- self.assertTrue(not pth.dirty)
-
+ assert not pth.dirty
-class TestUserInstallTest(unittest.TestCase):
- def setUp(self):
- self.dir = tempfile.mkdtemp()
- setup = os.path.join(self.dir, 'setup.py')
- f = open(setup, 'w')
+@pytest.yield_fixture
+def setup_context(tmpdir):
+ with (tmpdir/'setup.py').open('w') as f:
f.write(SETUP_PY)
- f.close()
- self.old_cwd = os.getcwd()
- os.chdir(self.dir)
-
- self.old_enable_site = site.ENABLE_USER_SITE
- self.old_file = easy_install_pkg.__file__
- self.old_base = site.USER_BASE
- site.USER_BASE = tempfile.mkdtemp()
- self.old_site = site.USER_SITE
- site.USER_SITE = tempfile.mkdtemp()
- easy_install_pkg.__file__ = site.USER_SITE
+ with tmpdir.as_cwd():
+ yield tmpdir
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.dir)
- shutil.rmtree(site.USER_BASE)
- shutil.rmtree(site.USER_SITE)
- site.USER_BASE = self.old_base
- site.USER_SITE = self.old_site
- site.ENABLE_USER_SITE = self.old_enable_site
- easy_install_pkg.__file__ = self.old_file
+@pytest.mark.usefixtures("user_override")
+@pytest.mark.usefixtures("setup_context")
+class TestUserInstallTest:
+ @mock.patch('setuptools.command.easy_install.__file__', None)
def test_user_install_implied(self):
+ easy_install_pkg.__file__ = site.USER_SITE
site.ENABLE_USER_SITE = True # disabled sometimes
#XXX: replace with something meaningfull
dist = Distribution()
@@ -164,7 +150,7 @@ class TestUserInstallTest(unittest.TestCase):
cmd = easy_install(dist)
cmd.args = ['py']
cmd.ensure_finalized()
- self.assertTrue(cmd.user, 'user should be implied')
+ assert cmd.user, 'user should be implied'
def test_multiproc_atexit(self):
try:
@@ -185,7 +171,7 @@ class TestUserInstallTest(unittest.TestCase):
cmd = easy_install(dist)
cmd.args = ['py']
cmd.initialize_options()
- self.assertFalse(cmd.user, 'NOT user should be implied')
+ assert not cmd.user, 'NOT user should be implied'
def test_local_index(self):
# make sure the local index is used
@@ -194,11 +180,8 @@ class TestUserInstallTest(unittest.TestCase):
new_location = tempfile.mkdtemp()
target = tempfile.mkdtemp()
egg_file = os.path.join(new_location, 'foo-1.0.egg-info')
- f = open(egg_file, 'w')
- try:
+ with open(egg_file, 'w') as f:
f.write('Name: foo\n')
- finally:
- f.close()
sys.path.append(target)
old_ppath = os.environ.get('PYTHONPATH')
@@ -214,7 +197,7 @@ class TestUserInstallTest(unittest.TestCase):
res = cmd.easy_install('foo')
actual = os.path.normcase(os.path.realpath(res.location))
expected = os.path.normcase(os.path.realpath(new_location))
- self.assertEqual(actual, expected)
+ assert actual == expected
finally:
sys.path.remove(target)
for basedir in [new_location, target, ]:
@@ -229,6 +212,25 @@ class TestUserInstallTest(unittest.TestCase):
else:
del os.environ['PYTHONPATH']
+ @contextlib.contextmanager
+ def user_install_setup_context(self, *args, **kwargs):
+ """
+ Wrap sandbox.setup_context to patch easy_install in that context to
+ appear as user-installed.
+ """
+ with self.orig_context(*args, **kwargs):
+ import setuptools.command.easy_install as ei
+ ei.__file__ = site.USER_SITE
+ yield
+
+ def patched_setup_context(self):
+ self.orig_context = sandbox.setup_context
+
+ return mock.patch(
+ 'setuptools.sandbox.setup_context',
+ self.user_install_setup_context,
+ )
+
def test_setup_requires(self):
"""Regression test for Distribute issue #318
@@ -237,12 +239,12 @@ class TestUserInstallTest(unittest.TestCase):
SandboxViolation.
"""
- test_pkg = create_setup_requires_package(self.dir)
+ test_pkg = create_setup_requires_package(os.getcwd())
test_setup_py = os.path.join(test_pkg, 'setup.py')
try:
- with quiet_context():
- with reset_setup_stop_context():
+ with contexts.quiet():
+ with self.patched_setup_context():
run_setup(test_setup_py, ['install'])
except SandboxViolation:
self.fail('Installation caused SandboxViolation')
@@ -252,7 +254,24 @@ class TestUserInstallTest(unittest.TestCase):
pass
-class TestSetupRequires(unittest.TestCase):
+@pytest.yield_fixture
+def distutils_package():
+ distutils_setup_py = SETUP_PY.replace(
+ 'from setuptools import setup',
+ 'from distutils.core import setup',
+ )
+ with contexts.tempdir(cd=os.chdir):
+ with open('setup.py', 'w') as f:
+ f.write(distutils_setup_py)
+ yield
+
+
+class TestDistutilsPackage:
+ def test_bdist_egg_available_on_distutils_pkg(self, distutils_package):
+ run_setup('setup.py', ['bdist_egg'])
+
+
+class TestSetupRequires:
def test_setup_requires_honors_fetch_params(self):
"""
@@ -269,25 +288,27 @@ class TestSetupRequires(unittest.TestCase):
# Some platforms (Jython) don't find a port to which to bind,
# so skip this test for them.
return
- with quiet_context():
+ with contexts.quiet():
# create an sdist that has a build-time dependency.
with TestSetupRequires.create_sdist() as dist_file:
- with tempdir_context() as temp_install_dir:
- with environment_context(PYTHONPATH=temp_install_dir):
- ei_params = ['--index-url', p_index.url,
+ with contexts.tempdir() as temp_install_dir:
+ with contexts.environment(PYTHONPATH=temp_install_dir):
+ ei_params = [
+ '--index-url', p_index.url,
'--allow-hosts', p_index_loc,
- '--exclude-scripts', '--install-dir', temp_install_dir,
- dist_file]
- with reset_setup_stop_context():
- with argv_context(['easy_install']):
- # attempt to install the dist. It should fail because
- # it doesn't exist.
- self.assertRaises(SystemExit,
- easy_install_pkg.main, ei_params)
+ '--exclude-scripts',
+ '--install-dir', temp_install_dir,
+ dist_file,
+ ]
+ with contexts.argv(['easy_install']):
+ # attempt to install the dist. It should fail because
+ # it doesn't exist.
+ with pytest.raises(SystemExit):
+ easy_install_pkg.main(ei_params)
# there should have been two or three requests to the server
# (three happens on Python 3.3a)
- self.assertTrue(2 <= len(p_index.requests) <= 3)
- self.assertEqual(p_index.requests[0].path, '/does-not-exist/')
+ assert 2 <= len(p_index.requests) <= 3
+ assert p_index.requests[0].path == '/does-not-exist/'
@staticmethod
@contextlib.contextmanager
@@ -296,18 +317,17 @@ class TestSetupRequires(unittest.TestCase):
Return an sdist with a setup_requires dependency (of something that
doesn't exist)
"""
- with tempdir_context() as dir:
+ with contexts.tempdir() as dir:
dist_path = os.path.join(dir, 'setuptools-test-fetcher-1.0.tar.gz')
- make_trivial_sdist(
- dist_path,
- textwrap.dedent("""
- import setuptools
- setuptools.setup(
- name="setuptools-test-fetcher",
- version="1.0",
- setup_requires = ['does-not-exist'],
- )
- """).lstrip())
+ script = DALS("""
+ import setuptools
+ setuptools.setup(
+ name="setuptools-test-fetcher",
+ version="1.0",
+ setup_requires = ['does-not-exist'],
+ )
+ """)
+ make_trivial_sdist(dist_path, script)
yield dist_path
def test_setup_requires_overrides_version_conflict(self):
@@ -325,22 +345,21 @@ class TestSetupRequires(unittest.TestCase):
working_set.add(fake_dist)
try:
- with tempdir_context() as temp_dir:
+ with contexts.tempdir() as temp_dir:
test_pkg = create_setup_requires_package(temp_dir)
test_setup_py = os.path.join(test_pkg, 'setup.py')
- with quiet_context() as (stdout, stderr):
- with reset_setup_stop_context():
- try:
- # Don't even need to install the package, just
- # running the setup.py at all is sufficient
- run_setup(test_setup_py, ['--name'])
- except VersionConflict:
- self.fail('Installing setup.py requirements '
- 'caused a VersionConflict')
+ with contexts.quiet() as (stdout, stderr):
+ try:
+ # Don't even need to install the package, just
+ # running the setup.py at all is sufficient
+ run_setup(test_setup_py, ['--name'])
+ except VersionConflict:
+ self.fail('Installing setup.py requirements '
+ 'caused a VersionConflict')
lines = stdout.readlines()
- self.assertTrue(len(lines) > 0)
- self.assertTrue(lines[-1].strip(), 'test_pkg')
+ assert len(lines) > 0
+ assert lines[-1].strip(), 'test_pkg'
finally:
pkg_resources.__setstate__(pr_state)
@@ -361,17 +380,16 @@ def create_setup_requires_package(path):
test_setup_py = os.path.join(test_pkg, 'setup.py')
os.mkdir(test_pkg)
- f = open(test_setup_py, 'w')
- f.write(textwrap.dedent("""\
- import setuptools
- setuptools.setup(**%r)
- """ % test_setup_attrs))
- f.close()
+ with open(test_setup_py, 'w') as f:
+ f.write(DALS("""
+ import setuptools
+ setuptools.setup(**%r)
+ """ % test_setup_attrs))
foobar_path = os.path.join(path, 'foobar-0.1.tar.gz')
make_trivial_sdist(
foobar_path,
- textwrap.dedent("""\
+ DALS("""
import setuptools
setuptools.setup(
name='foobar',
@@ -390,71 +408,5 @@ def make_trivial_sdist(dist_path, setup_py):
setup_py_file = tarfile.TarInfo(name='setup.py')
setup_py_bytes = io.BytesIO(setup_py.encode('utf-8'))
setup_py_file.size = len(setup_py_bytes.getvalue())
- dist = tarfile.open(dist_path, 'w:gz')
- try:
+ with tarfile_open(dist_path, 'w:gz') as dist:
dist.addfile(setup_py_file, fileobj=setup_py_bytes)
- finally:
- dist.close()
-
-
-@contextlib.contextmanager
-def tempdir_context(cd=lambda dir:None):
- temp_dir = tempfile.mkdtemp()
- orig_dir = os.getcwd()
- try:
- cd(temp_dir)
- yield temp_dir
- finally:
- cd(orig_dir)
- shutil.rmtree(temp_dir)
-
-@contextlib.contextmanager
-def environment_context(**updates):
- old_env = os.environ.copy()
- os.environ.update(updates)
- try:
- yield
- finally:
- for key in updates:
- del os.environ[key]
- os.environ.update(old_env)
-
-@contextlib.contextmanager
-def argv_context(repl):
- old_argv = sys.argv[:]
- sys.argv[:] = repl
- yield
- sys.argv[:] = old_argv
-
-@contextlib.contextmanager
-def reset_setup_stop_context():
- """
- When the setuptools tests are run using setup.py test, and then
- one wants to invoke another setup() command (such as easy_install)
- within those tests, it's necessary to reset the global variable
- in distutils.core so that the setup() command will run naturally.
- """
- setup_stop_after = distutils.core._setup_stop_after
- distutils.core._setup_stop_after = None
- yield
- distutils.core._setup_stop_after = setup_stop_after
-
-
-@contextlib.contextmanager
-def quiet_context():
- """
- 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 = six.StringIO()
- new_stderr = sys.stderr = six.StringIO()
- try:
- yield new_stdout, new_stderr
- finally:
- new_stdout.seek(0)
- new_stderr.seek(0)
- sys.stdout = old_stdout
- sys.stderr = old_stderr