summaryrefslogtreecommitdiff
path: root/setuptools/tests
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/tests')
-rw-r--r--setuptools/tests/__init__.py96
-rw-r--r--setuptools/tests/contexts.py2
-rw-r--r--setuptools/tests/environment.py10
-rw-r--r--setuptools/tests/fixtures.py16
-rw-r--r--setuptools/tests/py26compat.py2
-rw-r--r--setuptools/tests/server.py5
-rw-r--r--setuptools/tests/test_archive_util.py42
-rw-r--r--setuptools/tests/test_bdist_egg.py9
-rw-r--r--setuptools/tests/test_build_ext.py30
-rw-r--r--setuptools/tests/test_build_py.py1
-rw-r--r--setuptools/tests/test_develop.py4
-rw-r--r--setuptools/tests/test_dist_info.py91
-rw-r--r--setuptools/tests/test_easy_install.py97
-rw-r--r--setuptools/tests/test_egg_info.py29
-rw-r--r--setuptools/tests/test_find_packages.py15
-rw-r--r--setuptools/tests/test_install_scripts.py88
-rw-r--r--setuptools/tests/test_manifest.py476
-rw-r--r--setuptools/tests/test_msvc.py (renamed from setuptools/tests/test_msvc9compiler.py)14
-rw-r--r--setuptools/tests/test_packageindex.py15
-rw-r--r--setuptools/tests/test_sandbox.py1
-rw-r--r--setuptools/tests/test_sdist.py1
21 files changed, 902 insertions, 142 deletions
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py
index 32447356..53bd836c 100644
--- a/setuptools/tests/__init__.py
+++ b/setuptools/tests/__init__.py
@@ -27,7 +27,7 @@ def makeSetup(**args):
distutils.core._setup_stop_after = "commandline"
# Don't let system command line leak into tests!
- args.setdefault('script_args',['install'])
+ args.setdefault('script_args', ['install'])
try:
return setuptools.setup(**args)
@@ -40,6 +40,7 @@ needs_bytecode = pytest.mark.skipif(
reason="bytecode support not available",
)
+
class TestDepends:
def testExtractConst(self):
@@ -55,35 +56,35 @@ class TestDepends:
fc = six.get_function_code(f1)
# unrecognized name
- assert dep.extract_constant(fc,'q', -1) is None
+ assert dep.extract_constant(fc, 'q', -1) is None
# constant assigned
- dep.extract_constant(fc,'x', -1) == "test"
+ dep.extract_constant(fc, 'x', -1) == "test"
# expression assigned
- dep.extract_constant(fc,'y', -1) == -1
+ dep.extract_constant(fc, 'y', -1) == -1
# recognized name, not assigned
- dep.extract_constant(fc,'z', -1) is None
+ dep.extract_constant(fc, 'z', -1) is None
def testFindModule(self):
with pytest.raises(ImportError):
dep.find_module('no-such.-thing')
with pytest.raises(ImportError):
dep.find_module('setuptools.non-existent')
- f,p,i = dep.find_module('setuptools.tests')
+ f, p, i = dep.find_module('setuptools.tests')
f.close()
@needs_bytecode
def testModuleExtract(self):
from email import __version__
- assert dep.get_module_constant('email','__version__') == __version__
- assert dep.get_module_constant('sys','version') == sys.version
- assert dep.get_module_constant('setuptools.tests','__doc__') == __doc__
+ assert dep.get_module_constant('email', '__version__') == __version__
+ assert dep.get_module_constant('sys', 'version') == sys.version
+ assert dep.get_module_constant('setuptools.tests', '__doc__') == __doc__
@needs_bytecode
def testRequire(self):
- req = Require('Email','1.0.3','email')
+ req = Require('Email', '1.0.3', 'email')
assert req.name == 'Email'
assert req.module == 'email'
@@ -100,12 +101,12 @@ class TestDepends:
assert req.is_present()
assert req.is_current()
- req = Require('Email 3000','03000','email',format=LooseVersion)
+ req = Require('Email 3000', '03000', 'email', format=LooseVersion)
assert req.is_present()
assert not req.is_current()
assert not req.version_ok('unknown')
- req = Require('Do-what-I-mean','1.0','d-w-i-m')
+ req = Require('Do-what-I-mean', '1.0', 'd-w-i-m')
assert not req.is_present()
assert not req.is_current()
@@ -124,22 +125,22 @@ class TestDepends:
class TestDistro:
def setup_method(self, method):
- self.e1 = Extension('bar.ext',['bar.c'])
+ self.e1 = Extension('bar.ext', ['bar.c'])
self.e2 = Extension('c.y', ['y.c'])
self.dist = makeSetup(
packages=['a', 'a.b', 'a.b.c', 'b', 'c'],
- py_modules=['b.d','x'],
- ext_modules = (self.e1, self.e2),
- package_dir = {},
+ py_modules=['b.d', 'x'],
+ ext_modules=(self.e1, self.e2),
+ package_dir={},
)
def testDistroType(self):
- assert isinstance(self.dist,setuptools.dist.Distribution)
+ assert isinstance(self.dist, setuptools.dist.Distribution)
def testExcludePackage(self):
self.dist.exclude_package('a')
- assert self.dist.packages == ['b','c']
+ assert self.dist.packages == ['b', 'c']
self.dist.exclude_package('b')
assert self.dist.packages == ['c']
@@ -168,7 +169,7 @@ class TestDistro:
assert self.dist.ext_modules == [self.e2, self.e1]
def testExcludePackages(self):
- self.dist.exclude(packages=['c','b','a'])
+ self.dist.exclude(packages=['c', 'b', 'a'])
assert self.dist.packages == []
assert self.dist.py_modules == ['x']
assert self.dist.ext_modules == [self.e1]
@@ -198,13 +199,13 @@ class TestDistro:
with pytest.raises(DistutilsSetupError):
self.dist.exclude(nonexistent_option='x')
with pytest.raises(DistutilsSetupError):
- self.dist.include(packages={'x':'y'})
+ self.dist.include(packages={'x': 'y'})
with pytest.raises(DistutilsSetupError):
- self.dist.exclude(packages={'x':'y'})
+ self.dist.exclude(packages={'x': 'y'})
with pytest.raises(DistutilsSetupError):
- self.dist.include(ext_modules={'x':'y'})
+ self.dist.include(ext_modules={'x': 'y'})
with pytest.raises(DistutilsSetupError):
- self.dist.exclude(ext_modules={'x':'y'})
+ self.dist.exclude(ext_modules={'x': 'y'})
with pytest.raises(DistutilsSetupError):
self.dist.include(package_dir=['q'])
@@ -215,31 +216,31 @@ class TestDistro:
class TestFeatures:
def setup_method(self, method):
- self.req = Require('Distutils','1.0.3','distutils')
+ self.req = Require('Distutils', '1.0.3', 'distutils')
self.dist = makeSetup(
features={
- 'foo': Feature("foo",standard=True,require_features=['baz',self.req]),
- 'bar': Feature("bar", standard=True, packages=['pkg.bar'],
+ 'foo': Feature("foo", standard=True, require_features=['baz', self.req]),
+ 'bar': Feature("bar", standard=True, packages=['pkg.bar'],
py_modules=['bar_et'], remove=['bar.ext'],
- ),
+ ),
'baz': Feature(
"baz", optional=False, packages=['pkg.baz'],
- scripts = ['scripts/baz_it'],
- libraries=[('libfoo','foo/foofoo.c')]
+ scripts=['scripts/baz_it'],
+ libraries=[('libfoo', 'foo/foofoo.c')]
),
'dwim': Feature("DWIM", available=False, remove='bazish'),
},
script_args=['--without-bar', 'install'],
- packages = ['pkg.bar', 'pkg.foo'],
- py_modules = ['bar_et', 'bazish'],
- ext_modules = [Extension('bar.ext',['bar.c'])]
+ packages=['pkg.bar', 'pkg.foo'],
+ py_modules=['bar_et', 'bazish'],
+ ext_modules=[Extension('bar.ext', ['bar.c'])]
)
def testDefaults(self):
assert not Feature(
- "test",standard=True,remove='x',available=False
+ "test", standard=True, remove='x', available=False
).include_by_default()
- assert Feature("test",standard=True,remove='x').include_by_default()
+ assert Feature("test", standard=True, remove='x').include_by_default()
# Feature must have either kwargs, removes, or require_features
with pytest.raises(DistutilsSetupError):
Feature("test")
@@ -251,32 +252,32 @@ class TestFeatures:
def testFeatureOptions(self):
dist = self.dist
assert (
- ('with-dwim',None,'include DWIM') in dist.feature_options
+ ('with-dwim', None, 'include DWIM') in dist.feature_options
)
assert (
- ('without-dwim',None,'exclude DWIM (default)') in dist.feature_options
+ ('without-dwim', None, 'exclude DWIM (default)') in dist.feature_options
)
assert (
- ('with-bar',None,'include bar (default)') in dist.feature_options
+ ('with-bar', None, 'include bar (default)') in dist.feature_options
)
assert (
- ('without-bar',None,'exclude bar') in dist.feature_options
+ ('without-bar', None, 'exclude bar') in dist.feature_options
)
assert dist.feature_negopt['without-foo'] == 'with-foo'
assert dist.feature_negopt['without-bar'] == 'with-bar'
assert dist.feature_negopt['without-dwim'] == 'with-dwim'
- assert (not 'without-baz' in dist.feature_negopt)
+ assert ('without-baz' not in dist.feature_negopt)
def testUseFeatures(self):
dist = self.dist
assert dist.with_foo == 1
assert dist.with_bar == 0
assert dist.with_baz == 1
- assert (not 'bar_et' in dist.py_modules)
- assert (not 'pkg.bar' in dist.packages)
+ assert ('bar_et' not in dist.py_modules)
+ assert ('pkg.bar' not in dist.packages)
assert ('pkg.baz' in dist.packages)
assert ('scripts/baz_it' in dist.scripts)
- assert (('libfoo','foo/foofoo.c') in dist.libraries)
+ assert (('libfoo', 'foo/foofoo.c') in dist.libraries)
assert dist.ext_modules == []
assert dist.require_features == [self.req]
@@ -287,7 +288,8 @@ class TestFeatures:
def testFeatureWithInvalidRemove(self):
with pytest.raises(SystemExit):
- makeSetup(features={'x':Feature('x', remove='y')})
+ makeSetup(features={'x': Feature('x', remove='y')})
+
class TestCommandTests:
@@ -296,7 +298,7 @@ class TestCommandTests:
assert (isinstance(test_cmd, distutils.cmd.Command))
def testLongOptSuiteWNoDefault(self):
- ts1 = makeSetup(script_args=['test','--test-suite=foo.tests.suite'])
+ ts1 = makeSetup(script_args=['test', '--test-suite=foo.tests.suite'])
ts1 = ts1.get_command_obj('test')
ts1.ensure_finalized()
assert ts1.test_suite == 'foo.tests.suite'
@@ -309,7 +311,7 @@ class TestCommandTests:
def testDefaultWModuleOnCmdLine(self):
ts3 = makeSetup(
test_suite='bar.tests',
- script_args=['test','-m','foo.tests']
+ script_args=['test', '-m', 'foo.tests']
).get_command_obj('test')
ts3.ensure_finalized()
assert ts3.test_module == 'foo.tests'
@@ -317,7 +319,7 @@ class TestCommandTests:
def testConflictingOptions(self):
ts4 = makeSetup(
- script_args=['test','-m','bar.tests', '-s','foo.tests.suite']
+ script_args=['test', '-m', 'bar.tests', '-s', 'foo.tests.suite']
).get_command_obj('test')
with pytest.raises(DistutilsOptionError):
ts4.ensure_finalized()
@@ -325,4 +327,4 @@ class TestCommandTests:
def testNoSuite(self):
ts5 = makeSetup().get_command_obj('test')
ts5.ensure_finalized()
- assert ts5.test_suite == None
+ assert ts5.test_suite is None
diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py
index ae28c7c3..535ae107 100644
--- a/setuptools/tests/contexts.py
+++ b/setuptools/tests/contexts.py
@@ -10,7 +10,7 @@ import pkg_resources
@contextlib.contextmanager
-def tempdir(cd=lambda dir:None, **kwargs):
+def tempdir(cd=lambda dir: None, **kwargs):
temp_dir = tempfile.mkdtemp(**kwargs)
orig_dir = os.getcwd()
try:
diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py
index a23c0504..b0e3bd36 100644
--- a/setuptools/tests/environment.py
+++ b/setuptools/tests/environment.py
@@ -25,11 +25,11 @@ def run_setup_py(cmd, pypath=None, path=None,
for envname in os.environ:
env[envname] = os.environ[envname]
- #override the python path if needed
+ # override the python path if needed
if pypath is not None:
env["PYTHONPATH"] = pypath
- #overide the execution path if needed
+ # overide the execution path if needed
if path is not None:
env["PATH"] = path
if not env.get("PATH", ""):
@@ -50,11 +50,11 @@ def run_setup_py(cmd, pypath=None, path=None,
except OSError:
return 1, ''
- #decode the console string if needed
- if hasattr(data, "decode"):
+ # decode the console string if needed
+ if hasattr(data, "decode"):
# use the default encoding
data = data.decode()
data = unicodedata.normalize('NFC', data)
- #communciate calls wait()
+ # communciate calls wait()
return proc.returncode, data
diff --git a/setuptools/tests/fixtures.py b/setuptools/tests/fixtures.py
index c70c38cb..5204c8d1 100644
--- a/setuptools/tests/fixtures.py
+++ b/setuptools/tests/fixtures.py
@@ -1,24 +1,20 @@
-try:
- from unittest import mock
-except ImportError:
- import mock
import pytest
from . import contexts
@pytest.yield_fixture
-def user_override():
+def user_override(monkeypatch):
"""
Override site.USER_BASE and site.USER_SITE with temporary directories in
a context.
"""
with contexts.tempdir() as user_base:
- with mock.patch('site.USER_BASE', user_base):
- with contexts.tempdir() as user_site:
- with mock.patch('site.USER_SITE', user_site):
- with contexts.save_user_site_setting():
- yield
+ monkeypatch.setattr('site.USER_BASE', user_base)
+ with contexts.tempdir() as user_site:
+ monkeypatch.setattr('site.USER_SITE', user_site)
+ with contexts.save_user_site_setting():
+ yield
@pytest.yield_fixture
diff --git a/setuptools/tests/py26compat.py b/setuptools/tests/py26compat.py
index 7211f275..18cece05 100644
--- a/setuptools/tests/py26compat.py
+++ b/setuptools/tests/py26compat.py
@@ -2,12 +2,14 @@ import sys
import tarfile
import contextlib
+
def _tarfile_open_ex(*args, **kwargs):
"""
Extend result as a context manager.
"""
return contextlib.closing(tarfile.open(*args, **kwargs))
+
if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 2):
tarfile_open = _tarfile_open_ex
else:
diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py
index 6a687937..9e5fefb7 100644
--- a/setuptools/tests/server.py
+++ b/setuptools/tests/server.py
@@ -18,6 +18,7 @@ class IndexServer(BaseHTTPServer.HTTPServer):
# The index files should be located in setuptools/tests/indexes
s.stop()
"""
+
def __init__(self, server_address=('', 0),
RequestHandlerClass=SimpleHTTPServer.SimpleHTTPRequestHandler):
BaseHTTPServer.HTTPServer.__init__(self, server_address,
@@ -42,16 +43,20 @@ class IndexServer(BaseHTTPServer.HTTPServer):
port = self.server_port
return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port
+
class RequestRecorder(BaseHTTPServer.BaseHTTPRequestHandler):
+
def do_GET(self):
requests = vars(self.server).setdefault('requests', [])
requests.append(self)
self.send_response(200, 'OK')
+
class MockServer(BaseHTTPServer.HTTPServer, threading.Thread):
"""
A simple HTTP Server that records the requests made to it.
"""
+
def __init__(self, server_address=('', 0),
RequestHandlerClass=RequestRecorder):
BaseHTTPServer.HTTPServer.__init__(self, server_address,
diff --git a/setuptools/tests/test_archive_util.py b/setuptools/tests/test_archive_util.py
new file mode 100644
index 00000000..b789e9ac
--- /dev/null
+++ b/setuptools/tests/test_archive_util.py
@@ -0,0 +1,42 @@
+# coding: utf-8
+
+import tarfile
+import io
+
+from setuptools.extern import six
+
+import pytest
+
+from setuptools import archive_util
+
+
+@pytest.fixture
+def tarfile_with_unicode(tmpdir):
+ """
+ Create a tarfile containing only a file whose name is
+ a zero byte file called testimäge.png.
+ """
+ tarobj = io.BytesIO()
+
+ with tarfile.open(fileobj=tarobj, mode="w:gz") as tgz:
+ data = b""
+
+ filename = "testimäge.png"
+ if six.PY2:
+ filename = filename.decode('utf-8')
+
+ t = tarfile.TarInfo(filename)
+ t.size = len(data)
+
+ tgz.addfile(t, io.BytesIO(data))
+
+ target = tmpdir / 'unicode-pkg-1.0.tar.gz'
+ with open(str(target), mode='wb') as tf:
+ tf.write(tarobj.getvalue())
+ return str(target)
+
+
+@pytest.mark.xfail(reason="#710 and #712")
+def test_unicode_files(tarfile_with_unicode, tmpdir):
+ target = tmpdir / 'out'
+ archive_util.unpack_archive(tarfile_with_unicode, six.text_type(target))
diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py
index ccfb2ea7..c77aa226 100644
--- a/setuptools/tests/test_bdist_egg.py
+++ b/setuptools/tests/test_bdist_egg.py
@@ -9,30 +9,33 @@ from setuptools.dist import Distribution
from . import contexts
+
SETUP_PY = """\
from setuptools import setup
setup(name='foo', py_modules=['hi'])
"""
+
@pytest.yield_fixture
def setup_context(tmpdir):
- with (tmpdir/'setup.py').open('w') as f:
+ with (tmpdir / 'setup.py').open('w') as f:
f.write(SETUP_PY)
- with (tmpdir/'hi.py').open('w') as f:
+ with (tmpdir / 'hi.py').open('w') as f:
f.write('1\n')
with tmpdir.as_cwd():
yield tmpdir
class Test:
+
def test_bdist_egg(self, setup_context, user_override):
dist = Distribution(dict(
script_name='setup.py',
script_args=['bdist_egg'],
name='foo',
py_modules=['hi']
- ))
+ ))
os.makedirs(os.path.join('build', 'src'))
with contexts.quiet():
dist.parse_command_line()
diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py
index 0719ba44..ac002f44 100644
--- a/setuptools/tests/test_build_ext.py
+++ b/setuptools/tests/test_build_ext.py
@@ -1,9 +1,16 @@
+import sys
import distutils.command.build_ext as orig
+from distutils.sysconfig import get_config_var
-from setuptools.command.build_ext import build_ext
+from setuptools.extern import six
+
+from setuptools.command.build_ext import build_ext, get_abi3_suffix
from setuptools.dist import Distribution
+from setuptools.extension import Extension
+
class TestBuildExt:
+
def test_get_ext_filename(self):
"""
Setuptools needs to give back the same
@@ -16,3 +23,24 @@ class TestBuildExt:
res = cmd.get_ext_filename('foo')
wanted = orig.build_ext.get_ext_filename(cmd, 'foo')
assert res == wanted
+
+ def test_abi3_filename(self):
+ """
+ Filename needs to be loadable by several versions
+ of Python 3 if 'is_abi3' is truthy on Extension()
+ """
+ print(get_abi3_suffix())
+
+ extension = Extension('spam.eggs', ['eggs.c'], py_limited_api=True)
+ dist = Distribution(dict(ext_modules=[extension]))
+ cmd = build_ext(dist)
+ cmd.finalize_options()
+ assert 'spam.eggs' in cmd.ext_map
+ res = cmd.get_ext_filename('spam.eggs')
+
+ if six.PY2 or not get_abi3_suffix():
+ assert res.endswith(get_config_var('SO'))
+ elif sys.platform == 'win32':
+ assert res.endswith('eggs.pyd')
+ else:
+ assert 'abi3' in res
diff --git a/setuptools/tests/test_build_py.py b/setuptools/tests/test_build_py.py
index ed1703ac..cc701ae6 100644
--- a/setuptools/tests/test_build_py.py
+++ b/setuptools/tests/test_build_py.py
@@ -26,6 +26,5 @@ def test_directories_in_package_data_glob(tmpdir_as_cwd):
package_data={'': ['path/*']},
))
os.makedirs('path/subpath')
- #with contexts.quiet():
dist.parse_command_line()
dist.run_commands()
diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py
index 1b844499..f1580785 100644
--- a/setuptools/tests/test_develop.py
+++ b/setuptools/tests/test_develop.py
@@ -26,6 +26,7 @@ setup(name='foo',
INIT_PY = """print "foo"
"""
+
@pytest.yield_fixture
def temp_user(monkeypatch):
with contexts.tempdir() as user_base:
@@ -54,6 +55,7 @@ def test_env(tmpdir, temp_user):
class TestDevelop:
in_virtualenv = hasattr(sys, 'real_prefix')
in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix
+
@pytest.mark.skipif(in_virtualenv or in_venv,
reason="Cannot run when invoked in a virtualenv or venv")
def test_2to3_user_mode(self, test_env):
@@ -112,4 +114,4 @@ class TestDevelop:
cmd.ensure_finalized()
cmd.install_dir = tmpdir
cmd.run()
- #assert '0.0' not in foocmd_text
+ # assert '0.0' not in foocmd_text
diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py
index 9f226a55..f7e7d2bf 100644
--- a/setuptools/tests/test_dist_info.py
+++ b/setuptools/tests/test_dist_info.py
@@ -1,8 +1,7 @@
"""Test .dist-info style distributions.
"""
-import os
-import shutil
-import tempfile
+
+from __future__ import unicode_literals
from setuptools.extern.six.moves import map
@@ -14,10 +13,48 @@ from .textwrap import DALS
class TestDistInfo:
- def test_distinfo(self):
+ metadata_base = DALS("""
+ Metadata-Version: 1.2
+ Requires-Dist: splort (==4)
+ Provides-Extra: baz
+ Requires-Dist: quux (>=1.1); extra == 'baz'
+ """)
+
+ @classmethod
+ def build_metadata(cls, **kwargs):
+ lines = (
+ '{key}: {value}\n'.format(**locals())
+ for key, value in kwargs.items()
+ )
+ return cls.metadata_base + ''.join(lines)
+
+ @pytest.fixture
+ def metadata(self, tmpdir):
+ dist_info_name = 'VersionedDistribution-2.718.dist-info'
+ versioned = tmpdir / dist_info_name
+ versioned.mkdir()
+ filename = versioned / 'METADATA'
+ content = self.build_metadata(
+ Name='VersionedDistribution',
+ )
+ filename.write_text(content, encoding='utf-8')
+
+ dist_info_name = 'UnversionedDistribution.dist-info'
+ unversioned = tmpdir / dist_info_name
+ unversioned.mkdir()
+ filename = unversioned / 'METADATA'
+ content = self.build_metadata(
+ Name='UnversionedDistribution',
+ Version='0.3',
+ )
+ filename.write_text(content, encoding='utf-8')
+
+ return str(tmpdir)
+
+ def test_distinfo(self, metadata):
dists = dict(
(d.project_name, d)
- for d in pkg_resources.find_distributions(self.tmpdir)
+ for d in pkg_resources.find_distributions(metadata)
)
assert len(dists) == 2, dists
@@ -25,49 +62,17 @@ class TestDistInfo:
unversioned = dists['UnversionedDistribution']
versioned = dists['VersionedDistribution']
- assert versioned.version == '2.718' # from filename
- assert unversioned.version == '0.3' # from METADATA
+ assert versioned.version == '2.718' # from filename
+ assert unversioned.version == '0.3' # from METADATA
- def test_conditional_dependencies(self):
+ def test_conditional_dependencies(self, metadata):
specs = 'splort==4', 'quux>=1.1'
requires = list(map(pkg_resources.Requirement.parse, specs))
- for d in pkg_resources.find_distributions(self.tmpdir):
+ for d in pkg_resources.find_distributions(metadata):
assert d.requires() == requires[:1]
assert d.requires(extras=('baz',)) == [
requires[0],
- pkg_resources.Requirement.parse('quux>=1.1;extra=="baz"')]
+ pkg_resources.Requirement.parse('quux>=1.1;extra=="baz"'),
+ ]
assert d.extras == ['baz']
-
- metadata_template = DALS("""
- Metadata-Version: 1.2
- Name: {name}
- {version}
- Requires-Dist: splort (==4)
- Provides-Extra: baz
- Requires-Dist: quux (>=1.1); extra == 'baz'
- """)
-
- def setup_method(self, method):
- self.tmpdir = tempfile.mkdtemp()
- dist_info_name = 'VersionedDistribution-2.718.dist-info'
- versioned = os.path.join(self.tmpdir, dist_info_name)
- os.mkdir(versioned)
- with open(os.path.join(versioned, 'METADATA'), 'w+') as metadata_file:
- metadata = self.metadata_template.format(
- name='VersionedDistribution',
- version='',
- ).replace('\n\n', '\n')
- metadata_file.write(metadata)
- dist_info_name = 'UnversionedDistribution.dist-info'
- unversioned = os.path.join(self.tmpdir, dist_info_name)
- os.mkdir(unversioned)
- with open(os.path.join(unversioned, 'METADATA'), 'w+') as metadata_file:
- metadata = self.metadata_template.format(
- name='UnversionedDistribution',
- version='Version: 0.3',
- )
- metadata_file.write(metadata)
-
- def teardown_method(self, method):
- shutil.rmtree(self.tmpdir)
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index fd06b6ef..82e1d7e8 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -14,9 +14,10 @@ import logging
import itertools
import distutils.errors
import io
+import zipfile
-from setuptools.extern.six.moves import urllib
import time
+from setuptools.extern.six.moves import urllib
import pytest
try:
@@ -30,7 +31,7 @@ import setuptools.command.easy_install as ei
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
+from pkg_resources import normalize_path, working_set
from pkg_resources import Distribution as PRDistribution
import setuptools.tests.server
import pkg_resources
@@ -41,6 +42,7 @@ from .textwrap import DALS
class FakeDist(object):
+
def get_entry_map(self, group):
if group != 'console_scripts':
return {}
@@ -49,12 +51,14 @@ class FakeDist(object):
def as_requirement(self):
return 'spec'
+
SETUP_PY = DALS("""
from setuptools import setup
setup(name='foo')
""")
+
class TestEasyInstallTest:
def test_install_site_py(self, tmpdir):
@@ -70,10 +74,12 @@ class TestEasyInstallTest:
expected = header + DALS("""
# EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name'
__requires__ = 'spec'
+ import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
+ sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('spec', 'console_scripts', 'name')()
)
@@ -123,16 +129,72 @@ class TestEasyInstallTest:
get_site_dirs should always return site dirs reported by
site.getsitepackages.
"""
- mock_gsp = lambda: ['/setuptools/test/site-packages']
+ path = normalize_path('/setuptools/test/site-packages')
+ mock_gsp = lambda: [path]
monkeypatch.setattr(site, 'getsitepackages', mock_gsp, raising=False)
- assert '/setuptools/test/site-packages' in ei.get_site_dirs()
+ assert path in ei.get_site_dirs()
def test_all_site_dirs_works_without_getsitepackages(self, monkeypatch):
monkeypatch.delattr(site, 'getsitepackages', raising=False)
assert ei.get_site_dirs()
+ @pytest.fixture
+ def sdist_unicode(self, tmpdir):
+ files = [
+ (
+ 'setup.py',
+ DALS("""
+ import setuptools
+ setuptools.setup(
+ name="setuptools-test-unicode",
+ version="1.0",
+ packages=["mypkg"],
+ include_package_data=True,
+ )
+ """),
+ ),
+ (
+ 'mypkg/__init__.py',
+ "",
+ ),
+ (
+ u'mypkg/\u2603.txt',
+ "",
+ ),
+ ]
+ sdist_name = 'setuptools-test-unicode-1.0.zip'
+ sdist = tmpdir / sdist_name
+ # can't use make_sdist, because the issue only occurs
+ # with zip sdists.
+ sdist_zip = zipfile.ZipFile(str(sdist), 'w')
+ for filename, content in files:
+ sdist_zip.writestr(filename, content)
+ sdist_zip.close()
+ return str(sdist)
+
+ @pytest.mark.xfail(reason="#709 and #710")
+ # also
+ #@pytest.mark.xfail(setuptools.tests.is_ascii,
+ # reason="https://github.com/pypa/setuptools/issues/706")
+ def test_unicode_filename_in_sdist(self, sdist_unicode, tmpdir, monkeypatch):
+ """
+ The install command should execute correctly even if
+ the package has unicode filenames.
+ """
+ dist = Distribution({'script_args': ['easy_install']})
+ target = (tmpdir / 'target').ensure_dir()
+ cmd = ei.easy_install(
+ dist,
+ install_dir=str(target),
+ args=['x'],
+ )
+ monkeypatch.setitem(os.environ, 'PYTHONPATH', str(target))
+ cmd.ensure_finalized()
+ cmd.easy_install(sdist_unicode)
+
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
@@ -154,7 +216,7 @@ class TestPTHFileWriter:
@pytest.yield_fixture
def setup_context(tmpdir):
- with (tmpdir/'setup.py').open('w') as f:
+ with (tmpdir / 'setup.py').open('w') as f:
f.write(SETUP_PY)
with tmpdir.as_cwd():
yield tmpdir
@@ -266,6 +328,7 @@ def distutils_package():
class TestDistutilsPackage:
+
def test_bdist_egg_available_on_distutils_pkg(self, distutils_package):
run_setup('setup.py', ['bdist_egg'])
@@ -527,36 +590,40 @@ def make_trivial_sdist(dist_path, setup_py):
dist.addfile(setup_py_file, fileobj=setup_py_bytes)
+@pytest.mark.skipif(
+ sys.platform.startswith('java') and ei.is_sh(sys.executable),
+ reason="Test cannot run under java when executable is sh"
+)
class TestScriptHeader:
non_ascii_exe = '/Users/José/bin/python'
exe_with_spaces = r'C:\Program Files\Python33\python.exe'
- @pytest.mark.skipif(
- sys.platform.startswith('java') and ei.is_sh(sys.executable),
- reason="Test cannot run under java when executable is sh"
- )
def test_get_script_header(self):
expected = '#!%s\n' % ei.nt_quote_arg(os.path.normpath(sys.executable))
actual = ei.ScriptWriter.get_script_header('#!/usr/local/bin/python')
assert actual == expected
+ def test_get_script_header_args(self):
expected = '#!%s -x\n' % ei.nt_quote_arg(os.path.normpath
(sys.executable))
actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x')
assert actual == expected
+ def test_get_script_header_non_ascii_exe(self):
actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe)
expected = '#!%s -x\n' % self.non_ascii_exe
assert actual == expected
+ def test_get_script_header_exe_with_spaces(self):
actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python',
- executable='"'+self.exe_with_spaces+'"')
+ executable='"' + self.exe_with_spaces + '"')
expected = '#!"%s"\n' % self.exe_with_spaces
assert actual == expected
class TestCommandSpec:
+
def test_custom_launch_command(self):
"""
Show how a custom CommandSpec could be used to specify a #! executable
@@ -590,17 +657,9 @@ class TestCommandSpec:
assert len(cmd) == 2
assert '"' not in cmd.as_header()
- def test_sys_executable(self):
- """
- CommandSpec.from_string(sys.executable) should contain just that param.
- """
- writer = ei.ScriptWriter.best()
- cmd = writer.command_spec_class.from_string(sys.executable)
- assert len(cmd) == 1
- assert cmd[0] == sys.executable
-
class TestWindowsScriptWriter:
+
def test_header(self):
hdr = ei.WindowsScriptWriter.get_script_header('')
assert hdr.startswith('#!')
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index 3a0db58f..dff2a8c8 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -179,7 +179,7 @@ class TestEggInfo(object):
""" % requires_line)
build_files({
'setup.py': setup_script,
- })
+ })
def test_install_requires_with_markers(self, tmpdir_cwd, env):
self._setup_script_with_requires(
@@ -210,6 +210,32 @@ class TestEggInfo(object):
self._run_install_command(tmpdir_cwd, env)
assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
+ def test_python_requires_egg_info(self, tmpdir_cwd, env):
+ self._setup_script_with_requires(
+ """python_requires='>=2.7.12',""")
+ environ = os.environ.copy().update(
+ HOME=env.paths['home'],
+ )
+ code, data = environment.run_setup_py(
+ cmd=['egg_info'],
+ pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+ data_stream=1,
+ env=environ,
+ )
+ egg_info_dir = os.path.join('.', 'foo.egg-info')
+ with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+ pkg_info_lines = pkginfo_file.read().split('\n')
+ assert 'Requires-Python: >=2.7.12' in pkg_info_lines
+ assert 'Metadata-Version: 1.2' in pkg_info_lines
+
+ def test_python_requires_install(self, tmpdir_cwd, env):
+ self._setup_script_with_requires(
+ """python_requires='>=1.2.3',""")
+ self._run_install_command(tmpdir_cwd, env)
+ egg_info_dir = self._find_egg_info_files(env.paths['lib']).base
+ pkginfo = os.path.join(egg_info_dir, 'PKG-INFO')
+ assert 'Requires-Python: >=1.2.3' in open(pkginfo).read().split('\n')
+
def _run_install_command(self, tmpdir_cwd, env, cmd=None, output=None):
environ = os.environ.copy().update(
HOME=env.paths['home'],
@@ -235,6 +261,7 @@ class TestEggInfo(object):
def _find_egg_info_files(self, root):
class DirList(list):
+
def __init__(self, files, base):
super(DirList, self).__init__(files)
self.base = base
diff --git a/setuptools/tests/test_find_packages.py b/setuptools/tests/test_find_packages.py
index 06a7c02e..9d31ccd7 100644
--- a/setuptools/tests/test_find_packages.py
+++ b/setuptools/tests/test_find_packages.py
@@ -13,6 +13,8 @@ from setuptools import find_packages
find_420_packages = setuptools.PEP420PackageFinder.find
# modeled after CPython's test.support.can_symlink
+
+
def can_symlink():
TESTFN = tempfile.mktemp()
symlink_path = TESTFN + "can_symlink"
@@ -26,13 +28,15 @@ def can_symlink():
globals().update(can_symlink=lambda: can)
return can
+
def has_symlink():
bad_symlink = (
# Windows symlink directory detection is broken on Python 3.2
- platform.system() == 'Windows' and sys.version_info[:2] == (3,2)
+ platform.system() == 'Windows' and sys.version_info[:2] == (3, 2)
)
return can_symlink() and not bad_symlink
+
class TestFindPackages:
def setup_method(self, method):
@@ -94,6 +98,15 @@ class TestFindPackages:
packages = find_packages(self.dist_dir, exclude=('pkg.*',))
assert packages == ['pkg']
+ def test_exclude_recursive(self):
+ """
+ Excluding a parent package should exclude all child packages as well.
+ """
+ self._touch('__init__.py', self.pkg_dir)
+ self._touch('__init__.py', self.sub_pkg_dir)
+ packages = find_packages(self.dist_dir, exclude=('pkg',))
+ assert packages == []
+
def test_include_excludes_other(self):
"""
If include is specified, other packages should be excluded.
diff --git a/setuptools/tests/test_install_scripts.py b/setuptools/tests/test_install_scripts.py
new file mode 100644
index 00000000..7393241f
--- /dev/null
+++ b/setuptools/tests/test_install_scripts.py
@@ -0,0 +1,88 @@
+"""install_scripts tests
+"""
+
+import io
+import sys
+
+import pytest
+
+from setuptools.command.install_scripts import install_scripts
+from setuptools.dist import Distribution
+from . import contexts
+
+
+class TestInstallScripts:
+ settings = dict(
+ name='foo',
+ entry_points={'console_scripts': ['foo=foo:foo']},
+ version='0.0',
+ )
+ unix_exe = '/usr/dummy-test-path/local/bin/python'
+ unix_spaces_exe = '/usr/bin/env dummy-test-python'
+ win32_exe = 'C:\\Dummy Test Path\\Program Files\\Python 3.3\\python.exe'
+
+ def _run_install_scripts(self, install_dir, executable=None):
+ dist = Distribution(self.settings)
+ dist.script_name = 'setup.py'
+ cmd = install_scripts(dist)
+ cmd.install_dir = install_dir
+ if executable is not None:
+ bs = cmd.get_finalized_command('build_scripts')
+ bs.executable = executable
+ cmd.ensure_finalized()
+ with contexts.quiet():
+ cmd.run()
+
+ @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only')
+ def test_sys_executable_escaping_unix(self, tmpdir, monkeypatch):
+ """
+ Ensure that shebang is not quoted on Unix when getting the Python exe
+ from sys.executable.
+ """
+ expected = '#!%s\n' % self.unix_exe
+ monkeypatch.setattr('sys.executable', self.unix_exe)
+ with tmpdir.as_cwd():
+ self._run_install_scripts(str(tmpdir))
+ with io.open(str(tmpdir.join('foo')), 'r') as f:
+ actual = f.readline()
+ assert actual == expected
+
+ @pytest.mark.skipif(sys.platform != 'win32', reason='Windows only')
+ def test_sys_executable_escaping_win32(self, tmpdir, monkeypatch):
+ """
+ Ensure that shebang is quoted on Windows when getting the Python exe
+ from sys.executable and it contains a space.
+ """
+ expected = '#!"%s"\n' % self.win32_exe
+ monkeypatch.setattr('sys.executable', self.win32_exe)
+ with tmpdir.as_cwd():
+ self._run_install_scripts(str(tmpdir))
+ with io.open(str(tmpdir.join('foo-script.py')), 'r') as f:
+ actual = f.readline()
+ assert actual == expected
+
+ @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only')
+ def test_executable_with_spaces_escaping_unix(self, tmpdir):
+ """
+ Ensure that shebang on Unix is not quoted, even when a value with spaces
+ is specified using --executable.
+ """
+ expected = '#!%s\n' % self.unix_spaces_exe
+ with tmpdir.as_cwd():
+ self._run_install_scripts(str(tmpdir), self.unix_spaces_exe)
+ with io.open(str(tmpdir.join('foo')), 'r') as f:
+ actual = f.readline()
+ assert actual == expected
+
+ @pytest.mark.skipif(sys.platform != 'win32', reason='Windows only')
+ def test_executable_arg_escaping_win32(self, tmpdir):
+ """
+ Ensure that shebang on Windows is quoted when getting a path with spaces
+ from --executable, that is itself properly quoted.
+ """
+ expected = '#!"%s"\n' % self.win32_exe
+ with tmpdir.as_cwd():
+ self._run_install_scripts(str(tmpdir), '"' + self.win32_exe + '"')
+ with io.open(str(tmpdir.join('foo-script.py')), 'r') as f:
+ actual = f.readline()
+ assert actual == expected
diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py
new file mode 100644
index 00000000..6360270d
--- /dev/null
+++ b/setuptools/tests/test_manifest.py
@@ -0,0 +1,476 @@
+# -*- coding: utf-8 -*-
+"""sdist tests"""
+
+import contextlib
+import os
+import shutil
+import sys
+import tempfile
+from distutils import log
+from distutils.errors import DistutilsTemplateError
+
+from setuptools.command.egg_info import FileList, egg_info
+from setuptools.dist import Distribution
+from setuptools.extern import six
+from setuptools.tests.textwrap import DALS
+
+import pytest
+
+py3_only = pytest.mark.xfail(six.PY2, reason="Test runs on Python 3 only")
+
+
+def make_local_path(s):
+ """Converts '/' in a string to os.sep"""
+ return s.replace('/', os.sep)
+
+
+SETUP_ATTRS = {
+ 'name': 'app',
+ 'version': '0.0',
+ 'packages': ['app'],
+}
+
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(**%r)
+""" % SETUP_ATTRS
+
+
+@contextlib.contextmanager
+def quiet():
+ old_stdout, old_stderr = sys.stdout, sys.stderr
+ sys.stdout, sys.stderr = six.StringIO(), six.StringIO()
+ try:
+ yield
+ finally:
+ sys.stdout, sys.stderr = old_stdout, old_stderr
+
+
+def touch(filename):
+ open(filename, 'w').close()
+
+
+# The set of files always in the manifest, including all files in the
+# .egg-info directory
+default_files = frozenset(map(make_local_path, [
+ 'README.rst',
+ 'MANIFEST.in',
+ 'setup.py',
+ 'app.egg-info/PKG-INFO',
+ 'app.egg-info/SOURCES.txt',
+ 'app.egg-info/dependency_links.txt',
+ 'app.egg-info/top_level.txt',
+ 'app/__init__.py',
+]))
+
+
+class TempDirTestCase(object):
+
+ def setup_method(self, method):
+ self.temp_dir = tempfile.mkdtemp()
+ self.old_cwd = os.getcwd()
+ os.chdir(self.temp_dir)
+
+ def teardown_method(self, method):
+ os.chdir(self.old_cwd)
+ shutil.rmtree(self.temp_dir)
+
+
+class TestManifestTest(TempDirTestCase):
+
+ def setup_method(self, method):
+ super(TestManifestTest, self).setup_method(method)
+
+ f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
+ f.write(SETUP_PY)
+ f.close()
+
+ """
+ Create a file tree like:
+ - LICENSE
+ - README.rst
+ - testing.rst
+ - .hidden.rst
+ - app/
+ - __init__.py
+ - a.txt
+ - b.txt
+ - c.rst
+ - static/
+ - app.js
+ - app.js.map
+ - app.css
+ - app.css.map
+ """
+
+ for fname in ['README.rst', '.hidden.rst', 'testing.rst', 'LICENSE']:
+ touch(os.path.join(self.temp_dir, fname))
+
+ # Set up the rest of the test package
+ test_pkg = os.path.join(self.temp_dir, 'app')
+ os.mkdir(test_pkg)
+ for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
+ touch(os.path.join(test_pkg, fname))
+
+ # Some compiled front-end assets to include
+ static = os.path.join(test_pkg, 'static')
+ os.mkdir(static)
+ for fname in ['app.js', 'app.js.map', 'app.css', 'app.css.map']:
+ touch(os.path.join(static, fname))
+
+ def make_manifest(self, contents):
+ """Write a MANIFEST.in."""
+ with open(os.path.join(self.temp_dir, 'MANIFEST.in'), 'w') as f:
+ f.write(DALS(contents))
+
+ def get_files(self):
+ """Run egg_info and get all the files to include, as a set"""
+ dist = Distribution(SETUP_ATTRS)
+ dist.script_name = 'setup.py'
+ cmd = egg_info(dist)
+ cmd.ensure_finalized()
+
+ cmd.run()
+
+ return set(cmd.filelist.files)
+
+ def test_no_manifest(self):
+ """Check a missing MANIFEST.in includes only the standard files."""
+ assert (default_files - set(['MANIFEST.in'])) == self.get_files()
+
+ def test_empty_files(self):
+ """Check an empty MANIFEST.in includes only the standard files."""
+ self.make_manifest("")
+ assert default_files == self.get_files()
+
+ def test_include(self):
+ """Include extra rst files in the project root."""
+ self.make_manifest("include *.rst")
+ files = default_files | set([
+ 'testing.rst', '.hidden.rst'])
+ assert files == self.get_files()
+
+ def test_exclude(self):
+ """Include everything in app/ except the text files"""
+ l = make_local_path
+ self.make_manifest(
+ """
+ include app/*
+ exclude app/*.txt
+ """)
+ files = default_files | set([l('app/c.rst')])
+ assert files == self.get_files()
+
+ def test_include_multiple(self):
+ """Include with multiple patterns."""
+ l = make_local_path
+ self.make_manifest("include app/*.txt app/static/*")
+ files = default_files | set([
+ l('app/a.txt'), l('app/b.txt'),
+ l('app/static/app.js'), l('app/static/app.js.map'),
+ l('app/static/app.css'), l('app/static/app.css.map')])
+ assert files == self.get_files()
+
+ def test_graft(self):
+ """Include the whole app/static/ directory."""
+ l = make_local_path
+ self.make_manifest("graft app/static")
+ files = default_files | set([
+ l('app/static/app.js'), l('app/static/app.js.map'),
+ l('app/static/app.css'), l('app/static/app.css.map')])
+ assert files == self.get_files()
+
+ def test_graft_global_exclude(self):
+ """Exclude all *.map files in the project."""
+ l = make_local_path
+ self.make_manifest(
+ """
+ graft app/static
+ global-exclude *.map
+ """)
+ files = default_files | set([
+ l('app/static/app.js'), l('app/static/app.css')])
+ assert files == self.get_files()
+
+ def test_global_include(self):
+ """Include all *.rst, *.js, and *.css files in the whole tree."""
+ l = make_local_path
+ self.make_manifest(
+ """
+ global-include *.rst *.js *.css
+ """)
+ files = default_files | set([
+ '.hidden.rst', 'testing.rst', l('app/c.rst'),
+ l('app/static/app.js'), l('app/static/app.css')])
+ assert files == self.get_files()
+
+ def test_graft_prune(self):
+ """Include all files in app/, except for the whole app/static/ dir."""
+ l = make_local_path
+ self.make_manifest(
+ """
+ graft app
+ prune app/static
+ """)
+ files = default_files | set([
+ l('app/a.txt'), l('app/b.txt'), l('app/c.rst')])
+ assert files == self.get_files()
+
+
+class TestFileListTest(TempDirTestCase):
+ """
+ A copy of the relevant bits of distutils/tests/test_filelist.py,
+ to ensure setuptools' version of FileList keeps parity with distutils.
+ """
+
+ def setup_method(self, method):
+ super(TestFileListTest, self).setup_method(method)
+ self.threshold = log.set_threshold(log.FATAL)
+ self._old_log = log.Log._log
+ log.Log._log = self._log
+ self.logs = []
+
+ def teardown_method(self, method):
+ log.set_threshold(self.threshold)
+ log.Log._log = self._old_log
+ super(TestFileListTest, self).teardown_method(method)
+
+ def _log(self, level, msg, args):
+ if level not in (log.DEBUG, log.INFO, log.WARN, log.ERROR, log.FATAL):
+ raise ValueError('%s wrong log level' % str(level))
+ self.logs.append((level, msg, args))
+
+ def get_logs(self, *levels):
+ def _format(msg, args):
+ if len(args) == 0:
+ return msg
+ return msg % args
+ return [_format(msg, args) for level, msg, args
+ in self.logs if level in levels]
+
+ def clear_logs(self):
+ self.logs = []
+
+ def assertNoWarnings(self):
+ assert self.get_logs(log.WARN) == []
+ self.clear_logs()
+
+ def assertWarnings(self):
+ assert len(self.get_logs(log.WARN)) > 0
+ self.clear_logs()
+
+ def make_files(self, files):
+ for file in files:
+ file = os.path.join(self.temp_dir, file)
+ dirname, basename = os.path.split(file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ open(file, 'w').close()
+
+ def test_process_template_line(self):
+ # testing all MANIFEST.in template patterns
+ file_list = FileList()
+ l = make_local_path
+
+ # simulated file list
+ self.make_files([
+ 'foo.tmp', 'ok', 'xo', 'four.txt',
+ 'buildout.cfg',
+ # filelist does not filter out VCS directories,
+ # it's sdist that does
+ l('.hg/last-message.txt'),
+ l('global/one.txt'),
+ l('global/two.txt'),
+ l('global/files.x'),
+ l('global/here.tmp'),
+ l('f/o/f.oo'),
+ l('dir/graft-one'),
+ l('dir/dir2/graft2'),
+ l('dir3/ok'),
+ l('dir3/sub/ok.txt'),
+ ])
+
+ MANIFEST_IN = DALS("""\
+ include ok
+ include xo
+ exclude xo
+ include foo.tmp
+ include buildout.cfg
+ global-include *.x
+ global-include *.txt
+ global-exclude *.tmp
+ recursive-include f *.oo
+ recursive-exclude global *.x
+ graft dir
+ prune dir3
+ """)
+
+ for line in MANIFEST_IN.split('\n'):
+ if not line:
+ continue
+ file_list.process_template_line(line)
+
+ wanted = [
+ 'buildout.cfg',
+ 'four.txt',
+ 'ok',
+ l('.hg/last-message.txt'),
+ l('dir/graft-one'),
+ l('dir/dir2/graft2'),
+ l('f/o/f.oo'),
+ l('global/one.txt'),
+ l('global/two.txt'),
+ ]
+ file_list.sort()
+
+ assert file_list.files == wanted
+
+ def test_exclude_pattern(self):
+ # return False if no match
+ file_list = FileList()
+ assert not file_list.exclude_pattern('*.py')
+
+ # return True if files match
+ file_list = FileList()
+ file_list.files = ['a.py', 'b.py']
+ assert file_list.exclude_pattern('*.py')
+
+ # test excludes
+ file_list = FileList()
+ file_list.files = ['a.py', 'a.txt']
+ file_list.exclude_pattern('*.py')
+ assert file_list.files == ['a.txt']
+
+ def test_include_pattern(self):
+ # return False if no match
+ file_list = FileList()
+ file_list.set_allfiles([])
+ assert not file_list.include_pattern('*.py')
+
+ # return True if files match
+ file_list = FileList()
+ file_list.set_allfiles(['a.py', 'b.txt'])
+ assert file_list.include_pattern('*.py')
+
+ # test * matches all files
+ file_list = FileList()
+ assert file_list.allfiles is None
+ file_list.set_allfiles(['a.py', 'b.txt'])
+ file_list.include_pattern('*')
+ assert file_list.allfiles == ['a.py', 'b.txt']
+
+ def test_process_template(self):
+ l = make_local_path
+ # invalid lines
+ file_list = FileList()
+ for action in ('include', 'exclude', 'global-include',
+ 'global-exclude', 'recursive-include',
+ 'recursive-exclude', 'graft', 'prune', 'blarg'):
+ try:
+ file_list.process_template_line(action)
+ except DistutilsTemplateError:
+ pass
+ except Exception:
+ assert False, "Incorrect error thrown"
+ else:
+ assert False, "Should have thrown an error"
+
+ # include
+ file_list = FileList()
+ file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
+
+ file_list.process_template_line('include *.py')
+ assert file_list.files == ['a.py']
+ self.assertNoWarnings()
+
+ file_list.process_template_line('include *.rb')
+ assert file_list.files == ['a.py']
+ self.assertWarnings()
+
+ # exclude
+ file_list = FileList()
+ file_list.files = ['a.py', 'b.txt', l('d/c.py')]
+
+ file_list.process_template_line('exclude *.py')
+ assert file_list.files == ['b.txt', l('d/c.py')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('exclude *.rb')
+ assert file_list.files == ['b.txt', l('d/c.py')]
+ self.assertWarnings()
+
+ # global-include
+ file_list = FileList()
+ file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
+
+ file_list.process_template_line('global-include *.py')
+ assert file_list.files == ['a.py', l('d/c.py')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('global-include *.rb')
+ assert file_list.files == ['a.py', l('d/c.py')]
+ self.assertWarnings()
+
+ # global-exclude
+ file_list = FileList()
+ file_list.files = ['a.py', 'b.txt', l('d/c.py')]
+
+ file_list.process_template_line('global-exclude *.py')
+ assert file_list.files == ['b.txt']
+ self.assertNoWarnings()
+
+ file_list.process_template_line('global-exclude *.rb')
+ assert file_list.files == ['b.txt']
+ self.assertWarnings()
+
+ # recursive-include
+ file_list = FileList()
+ file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'),
+ l('d/d/e.py')])
+
+ file_list.process_template_line('recursive-include d *.py')
+ assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('recursive-include e *.py')
+ assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+ self.assertWarnings()
+
+ # recursive-exclude
+ file_list = FileList()
+ file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')]
+
+ file_list.process_template_line('recursive-exclude d *.py')
+ assert file_list.files == ['a.py', l('d/c.txt')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('recursive-exclude e *.py')
+ assert file_list.files == ['a.py', l('d/c.txt')]
+ self.assertWarnings()
+
+ # graft
+ file_list = FileList()
+ file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'),
+ l('f/f.py')])
+
+ file_list.process_template_line('graft d')
+ assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('graft e')
+ assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+ self.assertWarnings()
+
+ # prune
+ file_list = FileList()
+ file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')]
+
+ file_list.process_template_line('prune d')
+ assert file_list.files == ['a.py', l('f/f.py')]
+ self.assertNoWarnings()
+
+ file_list.process_template_line('prune e')
+ assert file_list.files == ['a.py', l('f/f.py')]
+ self.assertWarnings()
diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc.py
index 09e0460c..a0c76ea0 100644
--- a/setuptools/tests/test_msvc9compiler.py
+++ b/setuptools/tests/test_msvc.py
@@ -1,5 +1,5 @@
"""
-Tests for msvc9compiler.
+Tests for msvc support module.
"""
import os
@@ -69,9 +69,9 @@ class TestModulePatch:
def test_patched(self):
"Test the module is actually patched"
mod_name = distutils.msvc9compiler.find_vcvarsall.__module__
- assert mod_name == "setuptools.msvc9_support", "find_vcvarsall unpatched"
+ assert mod_name == "setuptools.msvc", "find_vcvarsall unpatched"
- def test_no_registry_entryies_means_nothing_found(self):
+ def test_no_registry_entries_means_nothing_found(self):
"""
No registry entries or environment variable should lead to an error
directing the user to download vcpython27.
@@ -83,10 +83,12 @@ class TestModulePatch:
with mock_reg():
assert find_vcvarsall(9.0) is None
- expected = distutils.errors.DistutilsPlatformError
- with pytest.raises(expected) as exc:
+ try:
query_vcvarsall(9.0)
- assert 'aka.ms/vcpython27' in str(exc)
+ except Exception as exc:
+ expected = distutils.errors.DistutilsPlatformError
+ assert isinstance(exc, expected)
+ assert 'aka.ms/vcpython27' in str(exc)
@pytest.yield_fixture
def user_preferred_setting(self):
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
index 6a76b5fc..f9bf895b 100644
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -7,14 +7,24 @@ import distutils.errors
from setuptools.extern import six
from setuptools.extern.six.moves import urllib, http_client
-from .textwrap import DALS
import pkg_resources
import setuptools.package_index
from setuptools.tests.server import IndexServer
+from .textwrap import DALS
class TestPackageIndex:
+ def test_regex(self):
+ hash_url = 'http://other_url?:action=show_md5&amp;'
+ hash_url += 'digest=0123456789abcdef0123456789abcdef'
+ doc = """
+ <a href="http://some_url">Name</a>
+ (<a title="MD5 hash"
+ href="{hash_url}">md5</a>)
+ """.lstrip().format(**locals())
+ assert setuptools.package_index.PYPI_MD5.match(doc)
+
def test_bad_url_bad_port(self):
index = setuptools.package_index.PackageIndex()
url = 'http://127.0.0.1:0/nonesuch/test_package_index'
@@ -129,7 +139,7 @@ class TestPackageIndex:
# the distribution has been found
assert 'foobar' in pi
# we have only one link, because links are compared without md5
- assert len(pi['foobar'])==1
+ assert len(pi['foobar']) == 1
# the link should be from the index
assert 'correct_md5' in pi['foobar'][0].location
@@ -209,6 +219,7 @@ class TestContentCheckers:
class TestPyPIConfig:
+
def test_percent_in_password(self, tmpdir, monkeypatch):
monkeypatch.setitem(os.environ, 'HOME', str(tmpdir))
pypirc = tmpdir / '.pypirc'
diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py
index fefd46f7..aa6138e4 100644
--- a/setuptools/tests/test_sandbox.py
+++ b/setuptools/tests/test_sandbox.py
@@ -57,6 +57,7 @@ class TestSandbox:
class TestExceptionSaver:
+
def test_exception_trapped(self):
with setuptools.sandbox.ExceptionSaver():
raise ValueError("details")
diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py
index d2a1f1bb..16d0eb07 100644
--- a/setuptools/tests/test_sdist.py
+++ b/setuptools/tests/test_sdist.py
@@ -132,7 +132,6 @@ class TestSdistTest:
assert os.path.join('sdist_test', 'b.txt') in manifest
assert os.path.join('sdist_test', 'c.rst') not in manifest
-
def test_defaults_case_sensitivity(self):
"""
Make sure default files (README.*, etc.) are added in a case-sensitive