aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools')
-rw-r--r--setuptools/__init__.py1
-rwxr-xr-xsetuptools/archive_util.py40
-rw-r--r--setuptools/command/build_ext.py58
-rwxr-xr-xsetuptools/command/easy_install.py67
-rwxr-xr-xsetuptools/command/egg_info.py50
-rwxr-xr-xsetuptools/command/sdist.py60
-rw-r--r--setuptools/command/test.py2
-rw-r--r--setuptools/dist.py27
-rwxr-xr-xsetuptools/sandbox.py170
-rw-r--r--setuptools/svn_utils.py582
-rw-r--r--setuptools/tests/__init__.py282
-rw-r--r--setuptools/tests/contexts.py93
-rw-r--r--setuptools/tests/entries-v10615
-rw-r--r--setuptools/tests/environment.py58
-rw-r--r--setuptools/tests/fixtures.py24
-rw-r--r--setuptools/tests/py26compat.py23
-rw-r--r--setuptools/tests/server.py26
-rw-r--r--setuptools/tests/svn_data/dummy.zipbin1771 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy13.zipbin9243 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy14.zipbin7496 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy15.zipbin7506 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy16.zipbin7155 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy17.zipbin7512 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/dummy18.zipbin7639 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn13_example.zipbin48818 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn13_ext_list.txt3
-rw-r--r--setuptools/tests/svn_data/svn13_ext_list.xml0
-rw-r--r--setuptools/tests/svn_data/svn13_info.xml121
-rw-r--r--setuptools/tests/svn_data/svn14_example.zipbin31077 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn14_ext_list.txt4
-rw-r--r--setuptools/tests/svn_data/svn14_ext_list.xml0
-rw-r--r--setuptools/tests/svn_data/svn14_info.xml119
-rw-r--r--setuptools/tests/svn_data/svn15_example.zipbin31143 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn15_ext_list.txt4
-rw-r--r--setuptools/tests/svn_data/svn15_ext_list.xml19
-rw-r--r--setuptools/tests/svn_data/svn15_info.xml125
-rw-r--r--setuptools/tests/svn_data/svn16_example.zipbin29418 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn16_ext_list.txt4
-rw-r--r--setuptools/tests/svn_data/svn16_ext_list.xml19
-rw-r--r--setuptools/tests/svn_data/svn16_info.xml125
-rw-r--r--setuptools/tests/svn_data/svn17_example.zipbin46954 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn17_ext_list.txt4
-rw-r--r--setuptools/tests/svn_data/svn17_ext_list.xml19
-rw-r--r--setuptools/tests/svn_data/svn17_info.xml130
-rw-r--r--setuptools/tests/svn_data/svn18_example.zipbin47477 -> 0 bytes
-rw-r--r--setuptools/tests/svn_data/svn18_ext_list.txt4
-rw-r--r--setuptools/tests/svn_data/svn18_ext_list.xml19
-rw-r--r--setuptools/tests/svn_data/svn18_info.xml136
-rw-r--r--setuptools/tests/test_bdist_egg.py54
-rw-r--r--setuptools/tests/test_build_ext.py19
-rw-r--r--setuptools/tests/test_develop.py37
-rw-r--r--setuptools/tests/test_dist_info.py93
-rw-r--r--setuptools/tests/test_easy_install.py326
-rw-r--r--setuptools/tests/test_egg_info.py300
-rw-r--r--setuptools/tests/test_find_packages.py24
-rw-r--r--setuptools/tests/test_integration.py3
-rw-r--r--setuptools/tests/test_markerlib.py79
-rw-r--r--setuptools/tests/test_msvc9compiler.py286
-rw-r--r--setuptools/tests/test_packageindex.py84
-rw-r--r--setuptools/tests/test_resources.py448
-rw-r--r--setuptools/tests/test_sandbox.py81
-rw-r--r--setuptools/tests/test_sdist.py214
-rw-r--r--setuptools/tests/test_svn.py246
-rw-r--r--setuptools/tests/test_test.py152
-rw-r--r--setuptools/tests/test_upload_docs.py93
-rw-r--r--setuptools/tests/test_windows_wrappers.py183
-rw-r--r--setuptools/tests/textwrap.py8
-rw-r--r--setuptools/tests/win_script_wrapper.txt154
-rw-r--r--setuptools/version.py2
69 files changed, 1741 insertions, 4178 deletions
diff --git a/setuptools/__init__.py b/setuptools/__init__.py
index c885555d..57236a5b 100644
--- a/setuptools/__init__.py
+++ b/setuptools/__init__.py
@@ -3,7 +3,6 @@
__import__('setuptools.bootstrap').bootstrap.ensure_deps()
import os
-import sys
import distutils.core
import distutils.filelist
from distutils.core import Command as _Command
diff --git a/setuptools/archive_util.py b/setuptools/archive_util.py
index 67a67e23..b3c9fa56 100755
--- a/setuptools/archive_util.py
+++ b/setuptools/archive_util.py
@@ -64,20 +64,23 @@ def unpack_directory(filename, extract_dir, progress_filter=default_filter):
Raises ``UnrecognizedFormat`` if `filename` is not a directory
"""
if not os.path.isdir(filename):
- raise UnrecognizedFormat("%s is not a directory" % (filename,))
+ raise UnrecognizedFormat("%s is not a directory" % filename)
- paths = {filename:('',extract_dir)}
+ paths = {
+ filename: ('', extract_dir),
+ }
for base, dirs, files in os.walk(filename):
- src,dst = paths[base]
+ src, dst = paths[base]
for d in dirs:
- paths[os.path.join(base,d)] = src+d+'/', os.path.join(dst,d)
+ paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d)
for f in files:
- target = os.path.join(dst,f)
- target = progress_filter(src+f, target)
+ target = os.path.join(dst, f)
+ target = progress_filter(src + f, target)
if not target:
- continue # skip non-files
+ # skip non-files
+ continue
ensure_directory(target)
- f = os.path.join(base,f)
+ f = os.path.join(base, f)
shutil.copyfile(f, target)
shutil.copystat(f, target)
@@ -112,12 +115,8 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter):
# file
ensure_directory(target)
data = z.read(info.filename)
- f = open(target,'wb')
- try:
+ with open(target, 'wb') as f:
f.write(data)
- finally:
- f.close()
- del data
unix_attributes = info.external_attr >> 16
if unix_attributes:
os.chmod(target, unix_attributes)
@@ -137,18 +136,21 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter):
"%s is not a compressed or uncompressed tar file" % (filename,)
)
with contextlib.closing(tarobj):
- tarobj.chown = lambda *args: None # don't do any chowning!
+ # don't do any chowning!
+ tarobj.chown = lambda *args: None
for member in tarobj:
name = member.name
# don't extract absolute paths or ones with .. in them
if not name.startswith('/') and '..' not in name.split('/'):
prelim_dst = os.path.join(extract_dir, *name.split('/'))
- # resolve any links and to extract the link targets as normal files
+ # resolve any links and to extract the link targets as normal
+ # files
while member is not None and (member.islnk() or member.issym()):
linkpath = member.linkname
if member.issym():
- linkpath = posixpath.join(posixpath.dirname(member.name), linkpath)
+ base = posixpath.dirname(member.name)
+ linkpath = posixpath.join(base, linkpath)
linkpath = posixpath.normpath(linkpath)
member = tarobj._getmember(linkpath)
@@ -158,9 +160,11 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter):
if final_dst.endswith(os.sep):
final_dst = final_dst[:-1]
try:
- tarobj._extract_member(member, final_dst) # XXX Ugh
+ # XXX Ugh
+ tarobj._extract_member(member, final_dst)
except tarfile.ExtractError:
- pass # chown/chmod/mkfifo/mknode/makedev failed
+ # chown/chmod/mkfifo/mknode/makedev failed
+ pass
return True
extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile
diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py
index 53bf9cd3..e4b2c593 100644
--- a/setuptools/command/build_ext.py
+++ b/setuptools/command/build_ext.py
@@ -6,6 +6,7 @@ from distutils.errors import DistutilsError
from distutils import log
import os
import sys
+import itertools
from setuptools.extension import Library
@@ -33,18 +34,13 @@ if sys.platform == "darwin":
use_stubs = True
elif os.name != 'nt':
try:
- from dl import RTLD_NOW
-
- have_rtld = True
- use_stubs = True
+ import dl
+ use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW')
except ImportError:
pass
-def if_dl(s):
- if have_rtld:
- return s
- return ''
+if_dl = lambda s: s if have_rtld else ''
class build_ext(_build_ext):
@@ -123,10 +119,10 @@ class build_ext(_build_ext):
# XXX what to do with conflicts?
self.ext_map[fullname.split('.')[-1]] = ext
- ltd = ext._links_to_dynamic = \
- self.shlibs and self.links_to_dynamic(ext) or False
- ext._needs_stub = ltd and use_stubs and not isinstance(ext,
- Library)
+ ltd = self.shlibs and self.links_to_dynamic(ext) or False
+ ns = ltd and use_stubs and not isinstance(ext, Library)
+ ext._links_to_dynamic = ltd
+ ext._needs_stub = ns
filename = ext._file_name = self.get_ext_filename(fullname)
libdir = os.path.dirname(os.path.join(self.build_lib, filename))
if ltd and libdir not in ext.library_dirs:
@@ -186,9 +182,8 @@ class build_ext(_build_ext):
self.compiler = self.shlib_compiler
_build_ext.build_extension(self, ext)
if ext._needs_stub:
- self.write_stub(
- self.get_finalized_command('build_py').build_lib, ext
- )
+ cmd = self.get_finalized_command('build_py').build_lib
+ self.write_stub(cmd, ext)
finally:
self.compiler = _compiler
@@ -199,22 +194,27 @@ class build_ext(_build_ext):
# XXX static-compiled version
libnames = dict.fromkeys([lib._full_name for lib in self.shlibs])
pkg = '.'.join(ext._full_name.split('.')[:-1] + [''])
- for libname in ext.libraries:
- if pkg + libname in libnames:
- return True
- return False
+ return any(pkg + libname in libnames for libname in ext.libraries)
def get_outputs(self):
- outputs = _build_ext.get_outputs(self)
- optimize = self.get_finalized_command('build_py').optimize
- for ext in self.extensions:
- if ext._needs_stub:
- base = os.path.join(self.build_lib, *ext._full_name.split('.'))
- outputs.append(base + '.py')
- outputs.append(base + '.pyc')
- if optimize:
- outputs.append(base + '.pyo')
- return outputs
+ return _build_ext.get_outputs(self) + self.__get_stubs_outputs()
+
+ def __get_stubs_outputs(self):
+ # assemble the base name for each extension that needs a stub
+ ns_ext_bases = (
+ os.path.join(self.build_lib, *ext._full_name.split('.'))
+ for ext in self.extensions
+ if ext._needs_stub
+ )
+ # pair each base with the extension
+ pairs = itertools.product(ns_ext_bases, self.__get_output_extensions())
+ return list(base + fnext for base, fnext in pairs)
+
+ def __get_output_extensions(self):
+ yield '.py'
+ yield '.pyc'
+ if self.get_finalized_command('build_py').optimize:
+ yield '.pyo'
def write_stub(self, output_dir, ext, compile=False):
log.info("writing stub loader for %s to %s", ext._full_name,
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 5444ba53..a24e3b59 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -34,6 +34,7 @@ import textwrap
import warnings
import site
import struct
+import contextlib
import six
from six.moves import configparser
@@ -55,9 +56,14 @@ from pkg_resources import (
import pkg_resources
+# Turn on PEP440Warnings
+warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
+
+
sys_executable = os.environ.get('__PYVENV_LAUNCHER__',
os.path.normpath(sys.executable))
+
__all__ = [
'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
'main', 'get_exe_prefixes',
@@ -1541,10 +1547,14 @@ class PthDistributions(Environment):
def add(self, dist):
"""Add `dist` to the distribution map"""
- if (dist.location not in self.paths and (
- dist.location not in self.sitedirs or
- dist.location == os.getcwd() # account for '.' being in PYTHONPATH
- )):
+ new_path = (
+ dist.location not in self.paths and (
+ dist.location not in self.sitedirs or
+ # account for '.' being in PYTHONPATH
+ dist.location == os.getcwd()
+ )
+ )
+ if new_path:
self.paths.append(dist.location)
self.dirty = True
Environment.add(self, dist)
@@ -2112,39 +2122,42 @@ def bootstrap():
def main(argv=None, **kw):
from setuptools import setup
from setuptools.dist import Distribution
- import distutils.core
-
- USAGE = """\
-usage: %(script)s [options] requirement_or_url ...
- or: %(script)s --help
-"""
-
- def gen_usage(script_name):
- return USAGE % dict(
- script=os.path.basename(script_name),
- )
-
- def with_ei_usage(f):
- old_gen_usage = distutils.core.gen_usage
- try:
- distutils.core.gen_usage = gen_usage
- return f()
- finally:
- distutils.core.gen_usage = old_gen_usage
class DistributionWithoutHelpCommands(Distribution):
common_usage = ""
def _show_help(self, *args, **kw):
- with_ei_usage(lambda: Distribution._show_help(self, *args, **kw))
+ with _patch_usage():
+ Distribution._show_help(self, *args, **kw)
if argv is None:
argv = sys.argv[1:]
- with_ei_usage(
- lambda: setup(
+ with _patch_usage():
+ setup(
script_args=['-q', 'easy_install', '-v'] + argv,
script_name=sys.argv[0] or 'easy_install',
distclass=DistributionWithoutHelpCommands, **kw
)
- )
+
+
+@contextlib.contextmanager
+def _patch_usage():
+ import distutils.core
+ USAGE = textwrap.dedent("""
+ usage: %(script)s [options] requirement_or_url ...
+ or: %(script)s --help
+ """).lstrip()
+
+ def gen_usage(script_name):
+ return USAGE % dict(
+ script=os.path.basename(script_name),
+ )
+
+ saved = distutils.core.gen_usage
+ distutils.core.gen_usage = gen_usage
+ try:
+ yield
+ finally:
+ distutils.core.gen_usage = saved
+
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 14ff0763..3f1db996 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -6,21 +6,27 @@ from distutils.filelist import FileList as _FileList
from distutils.util import convert_path
from distutils import log
import distutils.errors
+import distutils.filelist
import os
import re
import sys
import six
+try:
+ from setuptools_svn import svn_utils
+except ImportError:
+ pass
+
from setuptools import Command
from setuptools.command.sdist import sdist
-from setuptools import svn_utils
from setuptools.command.sdist import walk_revctrl
from pkg_resources import (
parse_requirements, safe_name, parse_version,
safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
import setuptools.unicode_utils as unicode_utils
+from pkg_resources import packaging
class egg_info(Command):
description = "create a distribution's .egg-info directory"
@@ -69,10 +75,15 @@ class egg_info(Command):
self.vtags = self.tags()
self.egg_version = self.tagged_version()
+ parsed_version = parse_version(self.egg_version)
+
try:
+ is_version = isinstance(parsed_version, packaging.version.Version)
+ spec = (
+ "%s==%s" if is_version else "%s===%s"
+ )
list(
- parse_requirements('%s==%s' % (self.egg_name,
- self.egg_version))
+ parse_requirements(spec % (self.egg_name, self.egg_version))
)
except ValueError:
raise distutils.errors.DistutilsOptionError(
@@ -184,6 +195,8 @@ class egg_info(Command):
@staticmethod
def get_svn_revision():
+ if 'svn_utils' not in globals():
+ return "0"
return str(svn_utils.SvnInfo.load(os.curdir).get_revision())
def find_sources(self):
@@ -313,8 +326,33 @@ class manifest_maker(sdist):
elif os.path.exists(self.manifest):
self.read_manifest()
ei_cmd = self.get_finalized_command('egg_info')
+ self._add_egg_info(cmd=ei_cmd)
self.filelist.include_pattern("*", prefix=ei_cmd.egg_info)
+ def _add_egg_info(self, cmd):
+ """
+ Add paths for egg-info files for an external egg-base.
+
+ The egg-info files are written to egg-base. If egg-base is
+ outside the current working directory, this method
+ searchs the egg-base directory for files to include
+ in the manifest. Uses distutils.filelist.findall (which is
+ really the version monkeypatched in by setuptools/__init__.py)
+ to perform the search.
+
+ Since findall records relative paths, prefix the returned
+ paths with cmd.egg_base, so add_default's include_pattern call
+ (which is looking for the absolute cmd.egg_info) will match
+ them.
+ """
+ if cmd.egg_base == os.curdir:
+ # egg-info files were already added by something else
+ return
+
+ discovered = distutils.filelist.findall(cmd.egg_base)
+ resolved = (os.path.join(cmd.egg_base, path) for path in discovered)
+ self.filelist.allfiles.extend(resolved)
+
def prune_file_list(self):
build = self.get_finalized_command('build')
base_dir = self.distribution.get_fullname()
@@ -383,6 +421,12 @@ def write_requirements(cmd, basename, filename):
cmd.write_or_delete_file("requirements", filename, data.getvalue())
+def write_setup_requirements(cmd, basename, filename):
+ data = StringIO()
+ _write_requirements(data, cmd.distribution.setup_requires)
+ cmd.write_or_delete_file("setup-requirements", filename, data.getvalue())
+
+
def write_toplevel_names(cmd, basename, filename):
pkgs = dict.fromkeys(
[
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index a15582c3..4ec7ec91 100755
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -1,20 +1,18 @@
from glob import glob
-from distutils.util import convert_path
from distutils import log
import distutils.command.sdist as orig
import os
-import re
import sys
import six
-from setuptools import svn_utils
from setuptools.utils import cs_path_exists
import pkg_resources
-READMES = ('README', 'README.rst', 'README.txt')
+READMES = 'README', 'README.rst', 'README.txt'
+_default_revctrl = list
def walk_revctrl(dirname=''):
"""Find all files under revision control"""
@@ -23,60 +21,6 @@ def walk_revctrl(dirname=''):
yield item
-# TODO will need test case
-class re_finder(object):
- """
- Finder that locates files based on entries in a file matched by a
- regular expression.
- """
-
- def __init__(self, path, pattern, postproc=lambda x: x):
- self.pattern = pattern
- self.postproc = postproc
- self.entries_path = convert_path(path)
-
- def _finder(self, dirname, filename):
- f = open(filename, 'rU')
- try:
- data = f.read()
- finally:
- f.close()
- for match in self.pattern.finditer(data):
- path = match.group(1)
- # postproc was formerly used when the svn finder
- # was an re_finder for calling unescape
- path = self.postproc(path)
- yield svn_utils.joinpath(dirname, path)
-
- def find(self, dirname=''):
- path = svn_utils.joinpath(dirname, self.entries_path)
-
- if not os.path.isfile(path):
- # entries file doesn't exist
- return
- for path in self._finder(dirname, path):
- if os.path.isfile(path):
- yield path
- elif os.path.isdir(path):
- for item in self.find(path):
- yield item
-
- __call__ = find
-
-
-def _default_revctrl(dirname=''):
- 'Primary svn_cvs entry point'
- for finder in finders:
- for item in finder(dirname):
- yield item
-
-
-finders = [
- re_finder('CVS/Entries', re.compile(r"^\w?/([^/]+)/", re.M)),
- svn_utils.svn_finder,
-]
-
-
class sdist(orig.sdist):
"""Smart sdist that finds anything supported by revision control"""
diff --git a/setuptools/command/test.py b/setuptools/command/test.py
index 14dd2600..c5644530 100644
--- a/setuptools/command/test.py
+++ b/setuptools/command/test.py
@@ -173,4 +173,4 @@ class test(Command):
if val is None:
return
parsed = EntryPoint.parse("x=" + val)
- return parsed.load(require=False)()
+ return parsed._load()()
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 99939f45..cdc15e46 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -19,6 +19,9 @@ from setuptools.depends import Require
from setuptools import windows_support
import pkg_resources
+packaging = pkg_resources.packaging
+
+
def _get_unpatched(cls):
"""Protect against re-patching the distutils if reloaded
@@ -270,6 +273,27 @@ class Distribution(_Distribution):
# Some people apparently take "version number" too literally :)
self.metadata.version = str(self.metadata.version)
+ if self.metadata.version is not None:
+ try:
+ ver = packaging.version.Version(self.metadata.version)
+ normalized_version = str(ver)
+ if self.metadata.version != normalized_version:
+ warnings.warn(
+ "The version specified requires normalization, "
+ "consider using '%s' instead of '%s'." % (
+ normalized_version,
+ self.metadata.version,
+ )
+ )
+ self.metadata.version = normalized_version
+ except (packaging.version.InvalidVersion, TypeError):
+ warnings.warn(
+ "The version specified (%r) is an invalid version, this "
+ "may not work as expected with newer versions of "
+ "setuptools, pip, and PyPI. Please see PEP 440 for more "
+ "details." % self.metadata.version
+ )
+
def parse_command_line(self):
"""Process features after parsing command line options"""
result = _Distribution.parse_command_line(self)
@@ -411,7 +435,8 @@ class Distribution(_Distribution):
def print_commands(self):
for ep in pkg_resources.iter_entry_points('distutils.commands'):
if ep.name not in self.cmdclass:
- cmdclass = ep.load(False) # don't require extras, we're not running
+ # don't require extras as the commands won't be invoked
+ cmdclass = ep._load()
self.cmdclass[ep.name] = cmdclass
return _Distribution.print_commands(self)
diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py
index 1d23ba98..f99532f6 100755
--- a/setuptools/sandbox.py
+++ b/setuptools/sandbox.py
@@ -5,7 +5,10 @@ import operator
import functools
import itertools
import re
+import contextlib
+import pickle
+import six
from six.moves import builtins
import pkg_resources
@@ -42,20 +45,150 @@ def _execfile(filename, globals, locals=None):
code = compile(script, filename, 'exec')
exec(code, globals, locals)
+
+@contextlib.contextmanager
+def save_argv():
+ saved = sys.argv[:]
+ try:
+ yield saved
+ finally:
+ sys.argv[:] = saved
+
+
+@contextlib.contextmanager
+def save_path():
+ saved = sys.path[:]
+ try:
+ yield saved
+ finally:
+ sys.path[:] = saved
+
+
+@contextlib.contextmanager
+def override_temp(replacement):
+ """
+ Monkey-patch tempfile.tempdir with replacement, ensuring it exists
+ """
+ if not os.path.isdir(replacement):
+ os.makedirs(replacement)
+
+ saved = tempfile.tempdir
+
+ tempfile.tempdir = replacement
+
+ try:
+ yield
+ finally:
+ tempfile.tempdir = saved
+
+
+@contextlib.contextmanager
+def pushd(target):
+ saved = os.getcwd()
+ os.chdir(target)
+ try:
+ yield saved
+ finally:
+ os.chdir(saved)
+
+
+@contextlib.contextmanager
+def save_modules():
+ """
+ Context in which imported modules are saved.
+
+ Translates exceptions internal to the context into the equivalent exception
+ outside the context.
+ """
+ saved = sys.modules.copy()
+ try:
+ try:
+ yield saved
+ except:
+ # dump any exception
+ class_, exc, tb = sys.exc_info()
+ saved_cls = pickle.dumps(class_)
+ saved_exc = pickle.dumps(exc)
+ raise
+ finally:
+ sys.modules.update(saved)
+ # remove any modules imported since
+ del_modules = (
+ mod_name for mod_name in sys.modules
+ if mod_name not in saved
+ # exclude any encodings modules. See #285
+ and not mod_name.startswith('encodings.')
+ )
+ _clear_modules(del_modules)
+ except:
+ # reload and re-raise any exception, using restored modules
+ class_, exc, tb = sys.exc_info()
+ new_cls = pickle.loads(saved_cls)
+ new_exc = pickle.loads(saved_exc)
+ six.reraise(new_cls, new_exc, tb)
+
+
+def _clear_modules(module_names):
+ for mod_name in list(module_names):
+ del sys.modules[mod_name]
+
+
+@contextlib.contextmanager
+def save_pkg_resources_state():
+ saved = pkg_resources.__getstate__()
+ try:
+ yield saved
+ finally:
+ pkg_resources.__setstate__(saved)
+
+
+@contextlib.contextmanager
+def setup_context(setup_dir):
+ temp_dir = os.path.join(setup_dir, 'temp')
+ with save_pkg_resources_state():
+ with save_modules():
+ hide_setuptools()
+ with save_path():
+ with save_argv():
+ with override_temp(temp_dir):
+ with pushd(setup_dir):
+ # ensure setuptools commands are available
+ __import__('setuptools')
+ yield
+
+
+def _needs_hiding(mod_name):
+ """
+ >>> _needs_hiding('setuptools')
+ True
+ >>> _needs_hiding('pkg_resources')
+ True
+ >>> _needs_hiding('setuptools_plugin')
+ False
+ >>> _needs_hiding('setuptools.__init__')
+ True
+ >>> _needs_hiding('distutils')
+ True
+ """
+ pattern = re.compile('(setuptools|pkg_resources|distutils)(\.|$)')
+ return bool(pattern.match(mod_name))
+
+
+def hide_setuptools():
+ """
+ Remove references to setuptools' modules from sys.modules to allow the
+ invocation to import the most appropriate setuptools. This technique is
+ necessary to avoid issues such as #315 where setuptools upgrading itself
+ would fail to find a function declared in the metadata.
+ """
+ modules = filter(_needs_hiding, sys.modules)
+ _clear_modules(modules)
+
+
def run_setup(setup_script, args):
"""Run a distutils setup script, sandboxed in its directory"""
- old_dir = os.getcwd()
- save_argv = sys.argv[:]
- save_path = sys.path[:]
setup_dir = os.path.abspath(os.path.dirname(setup_script))
- temp_dir = os.path.join(setup_dir,'temp')
- if not os.path.isdir(temp_dir): os.makedirs(temp_dir)
- save_tmp = tempfile.tempdir
- save_modules = sys.modules.copy()
- pr_state = pkg_resources.__getstate__()
- try:
- tempfile.tempdir = temp_dir
- os.chdir(setup_dir)
+ with setup_context(setup_dir):
try:
sys.argv[:] = [setup_script]+list(args)
sys.path.insert(0, setup_dir)
@@ -71,21 +204,6 @@ def run_setup(setup_script, args):
if v.args and v.args[0]:
raise
# Normal exit, just return
- finally:
- pkg_resources.__setstate__(pr_state)
- sys.modules.update(save_modules)
- # remove any modules imported within the sandbox
- del_modules = [
- mod_name for mod_name in sys.modules
- if mod_name not in save_modules
- # exclude any encodings modules. See #285
- and not mod_name.startswith('encodings.')
- ]
- list(map(sys.modules.__delitem__, del_modules))
- os.chdir(old_dir)
- sys.path[:] = save_path
- sys.argv[:] = save_argv
- tempfile.tempdir = save_tmp
class AbstractSandbox:
diff --git a/setuptools/svn_utils.py b/setuptools/svn_utils.py
deleted file mode 100644
index f80fd9f3..00000000
--- a/setuptools/svn_utils.py
+++ /dev/null
@@ -1,582 +0,0 @@
-from __future__ import absolute_import
-
-import os
-import re
-import sys
-from distutils import log
-import xml.dom.pulldom
-import shlex
-import locale
-import codecs
-import unicodedata
-import warnings
-from setuptools.py31compat import TemporaryDirectory
-from xml.sax.saxutils import unescape
-
-import six
-from six.moves import urllib
-
-from subprocess import Popen as _Popen, PIPE as _PIPE
-
-#NOTE: Use of the command line options require SVN 1.3 or newer (December 2005)
-# and SVN 1.3 hasn't been supported by the developers since mid 2008.
-
-#subprocess is called several times with shell=(sys.platform=='win32')
-#see the follow for more information:
-# http://bugs.python.org/issue8557
-# http://stackoverflow.com/questions/5658622/
-# python-subprocess-popen-environment-path
-
-def _run_command(args, stdout=_PIPE, stderr=_PIPE, encoding=None, stream=0):
- #regarding the shell argument, see: http://bugs.python.org/issue8557
- try:
- proc = _Popen(args, stdout=stdout, stderr=stderr,
- shell=(sys.platform == 'win32'))
-
- data = proc.communicate()[stream]
- except OSError:
- return 1, ''
-
- #doubled checked and
- data = decode_as_string(data, encoding)
-
- #communciate calls wait()
- return proc.returncode, data
-
-
-def _get_entry_schedule(entry):
- schedule = entry.getElementsByTagName('schedule')[0]
- return "".join([t.nodeValue
- for t in schedule.childNodes
- if t.nodeType == t.TEXT_NODE])
-
-
-def _get_target_property(target):
- property_text = target.getElementsByTagName('property')[0]
- return "".join([t.nodeValue
- for t in property_text.childNodes
- if t.nodeType == t.TEXT_NODE])
-
-
-def _get_xml_data(decoded_str):
- if six.PY2:
- #old versions want an encoded string
- data = decoded_str.encode('utf-8')
- else:
- data = decoded_str
- return data
-
-
-def joinpath(prefix, *suffix):
- if not prefix or prefix == '.':
- return os.path.join(*suffix)
- return os.path.join(prefix, *suffix)
-
-def determine_console_encoding():
- try:
- #try for the preferred encoding
- encoding = locale.getpreferredencoding()
-
- #see if the locale.getdefaultlocale returns null
- #some versions of python\platforms return US-ASCII
- #when it cannot determine an encoding
- if not encoding or encoding == "US-ASCII":
- encoding = locale.getdefaultlocale()[1]
-
- if encoding:
- codecs.lookup(encoding) # make sure a lookup error is not made
-
- except (locale.Error, LookupError):
- encoding = None
-
- is_osx = sys.platform == "darwin"
- if not encoding:
- return ["US-ASCII", "utf-8"][is_osx]
- elif encoding.startswith("mac-") and is_osx:
- #certain versions of python would return mac-roman as default
- #OSX as a left over of earlier mac versions.
- return "utf-8"
- else:
- return encoding
-
-_console_encoding = determine_console_encoding()
-
-def decode_as_string(text, encoding=None):
- """
- Decode the console or file output explicitly using getpreferredencoding.
- The text paraemeter should be a encoded string, if not no decode occurs
- If no encoding is given, getpreferredencoding is used. If encoding is
- specified, that is used instead. This would be needed for SVN --xml
- output. Unicode is explicitly put in composed NFC form.
-
- --xml should be UTF-8 (SVN Issue 2938) the discussion on the Subversion
- DEV List from 2007 seems to indicate the same.
- """
- #text should be a byte string
-
- if encoding is None:
- encoding = _console_encoding
-
- if not isinstance(text, six.text_type):
- text = text.decode(encoding)
-
- text = unicodedata.normalize('NFC', text)
-
- return text
-
-
-def parse_dir_entries(decoded_str):
- '''Parse the entries from a recursive info xml'''
- doc = xml.dom.pulldom.parseString(_get_xml_data(decoded_str))
- entries = list()
-
- for event, node in doc:
- if event == 'START_ELEMENT' and node.nodeName == 'entry':
- doc.expandNode(node)
- if not _get_entry_schedule(node).startswith('delete'):
- entries.append((node.getAttribute('path'),
- node.getAttribute('kind')))
-
- return entries[1:] # do not want the root directory
-
-
-def parse_externals_xml(decoded_str, prefix=''):
- '''Parse a propget svn:externals xml'''
- prefix = os.path.normpath(prefix)
- prefix = os.path.normcase(prefix)
-
- doc = xml.dom.pulldom.parseString(_get_xml_data(decoded_str))
- externals = list()
-
- for event, node in doc:
- if event == 'START_ELEMENT' and node.nodeName == 'target':
- doc.expandNode(node)
- path = os.path.normpath(node.getAttribute('path'))
-
- if os.path.normcase(path).startswith(prefix):
- path = path[len(prefix)+1:]
-
- data = _get_target_property(node)
- #data should be decoded already
- for external in parse_external_prop(data):
- externals.append(joinpath(path, external))
-
- return externals # do not want the root directory
-
-
-def parse_external_prop(lines):
- """
- Parse the value of a retrieved svn:externals entry.
-
- possible token setups (with quotng and backscaping in laters versions)
- URL[@#] EXT_FOLDERNAME
- [-r#] URL EXT_FOLDERNAME
- EXT_FOLDERNAME [-r#] URL
- """
- externals = []
- for line in lines.splitlines():
- line = line.lstrip() # there might be a "\ "
- if not line:
- continue
-
- if six.PY2:
- #shlex handles NULLs just fine and shlex in 2.7 tries to encode
- #as ascii automatiically
- line = line.encode('utf-8')
- line = shlex.split(line)
- if six.PY2:
- line = [x.decode('utf-8') for x in line]
-
- #EXT_FOLDERNAME is either the first or last depending on where
- #the URL falls
- if urllib.parse.urlsplit(line[-1])[0]:
- external = line[0]
- else:
- external = line[-1]
-
- external = decode_as_string(external, encoding="utf-8")
- externals.append(os.path.normpath(external))
-
- return externals
-
-
-def parse_prop_file(filename, key):
- found = False
- f = open(filename, 'rt')
- data = ''
- try:
- for line in iter(f.readline, ''): # can't use direct iter!
- parts = line.split()
- if len(parts) == 2:
- kind, length = parts
- data = f.read(int(length))
- if kind == 'K' and data == key:
- found = True
- elif kind == 'V' and found:
- break
- finally:
- f.close()
-
- return data
-
-
-class SvnInfo(object):
- '''
- Generic svn_info object. No has little knowledge of how to extract
- information. Use cls.load to instatiate according svn version.
-
- Paths are not filesystem encoded.
- '''
-
- @staticmethod
- def get_svn_version():
- # Temp config directory should be enough to check for repository
- # This is needed because .svn always creates .subversion and
- # some operating systems do not handle dot directory correctly.
- # Real queries in real svn repos with be concerned with it creation
- with TemporaryDirectory() as tempdir:
- code, data = _run_command(['svn',
- '--config-dir', tempdir,
- '--version',
- '--quiet'])
-
- if code == 0 and data:
- return data.strip()
- else:
- return ''
-
- #svnversion return values (previous implementations return max revision)
- # 4123:4168 mixed revision working copy
- # 4168M modified working copy
- # 4123S switched working copy
- # 4123:4168MS mixed revision, modified, switched working copy
- revision_re = re.compile(r'(?:([\-0-9]+):)?(\d+)([a-z]*)\s*$', re.I)
-
- @classmethod
- def load(cls, dirname=''):
- normdir = os.path.normpath(dirname)
-
- # Temp config directory should be enough to check for repository
- # This is needed because .svn always creates .subversion and
- # some operating systems do not handle dot directory correctly.
- # Real queries in real svn repos with be concerned with it creation
- with TemporaryDirectory() as tempdir:
- code, data = _run_command(['svn',
- '--config-dir', tempdir,
- 'info', normdir])
-
- # Must check for some contents, as some use empty directories
- # in testcases, however only enteries is needed also the info
- # command above MUST have worked
- svn_dir = os.path.join(normdir, '.svn')
- is_svn_wd = (not code or
- os.path.isfile(os.path.join(svn_dir, 'entries')))
-
- svn_version = tuple(cls.get_svn_version().split('.'))
-
- try:
- base_svn_version = tuple(int(x) for x in svn_version[:2])
- except ValueError:
- base_svn_version = tuple()
-
- if not is_svn_wd:
- #return an instance of this NO-OP class
- return SvnInfo(dirname)
-
- if code or not base_svn_version or base_svn_version < (1, 3):
- warnings.warn(("No SVN 1.3+ command found: falling back "
- "on pre 1.7 .svn parsing"), DeprecationWarning)
- return SvnFileInfo(dirname)
-
- if base_svn_version < (1, 5):
- return Svn13Info(dirname)
-
- return Svn15Info(dirname)
-
- def __init__(self, path=''):
- self.path = path
- self._entries = None
- self._externals = None
-
- def get_revision(self):
- 'Retrieve the directory revision information using svnversion'
- code, data = _run_command(['svnversion', '-c', self.path])
- if code:
- log.warn("svnversion failed")
- return 0
-
- parsed = self.revision_re.match(data)
- if parsed:
- return int(parsed.group(2))
- else:
- return 0
-
- @property
- def entries(self):
- if self._entries is None:
- self._entries = self.get_entries()
- return self._entries
-
- @property
- def externals(self):
- if self._externals is None:
- self._externals = self.get_externals()
- return self._externals
-
- def iter_externals(self):
- '''
- Iterate over the svn:external references in the repository path.
- '''
- for item in self.externals:
- yield item
-
- def iter_files(self):
- '''
- Iterate over the non-deleted file entries in the repository path
- '''
- for item, kind in self.entries:
- if kind.lower() == 'file':
- yield item
-
- def iter_dirs(self, include_root=True):
- '''
- Iterate over the non-deleted file entries in the repository path
- '''
- if include_root:
- yield self.path
- for item, kind in self.entries:
- if kind.lower() == 'dir':
- yield item
-
- def get_entries(self):
- return []
-
- def get_externals(self):
- return []
-
-
-class Svn13Info(SvnInfo):
- def get_entries(self):
- code, data = _run_command(['svn', 'info', '-R', '--xml', self.path],
- encoding="utf-8")
-
- if code:
- log.debug("svn info failed")
- return []
-
- return parse_dir_entries(data)
-
- def get_externals(self):
- #Previous to 1.5 --xml was not supported for svn propget and the -R
- #output format breaks the shlex compatible semantics.
- cmd = ['svn', 'propget', 'svn:externals']
- result = []
- for folder in self.iter_dirs():
- code, lines = _run_command(cmd + [folder], encoding="utf-8")
- if code != 0:
- log.warn("svn propget failed")
- return []
- #lines should a str
- for external in parse_external_prop(lines):
- if folder:
- external = os.path.join(folder, external)
- result.append(os.path.normpath(external))
-
- return result
-
-
-class Svn15Info(Svn13Info):
- def get_externals(self):
- cmd = ['svn', 'propget', 'svn:externals', self.path, '-R', '--xml']
- code, lines = _run_command(cmd, encoding="utf-8")
- if code:
- log.debug("svn propget failed")
- return []
- return parse_externals_xml(lines, prefix=os.path.abspath(self.path))
-
-
-class SvnFileInfo(SvnInfo):
-
- def __init__(self, path=''):
- super(SvnFileInfo, self).__init__(path)
- self._directories = None
- self._revision = None
-
- def _walk_svn(self, base):
- entry_file = joinpath(base, '.svn', 'entries')
- if os.path.isfile(entry_file):
- entries = SVNEntriesFile.load(base)
- yield (base, False, entries.parse_revision())
- for path in entries.get_undeleted_records():
- path = decode_as_string(path)
- path = joinpath(base, path)
- if os.path.isfile(path):
- yield (path, True, None)
- elif os.path.isdir(path):
- for item in self._walk_svn(path):
- yield item
-
- def _build_entries(self):
- entries = list()
-
- rev = 0
- for path, isfile, dir_rev in self._walk_svn(self.path):
- if isfile:
- entries.append((path, 'file'))
- else:
- entries.append((path, 'dir'))
- rev = max(rev, dir_rev)
-
- self._entries = entries
- self._revision = rev
-
- def get_entries(self):
- if self._entries is None:
- self._build_entries()
- return self._entries
-
- def get_revision(self):
- if self._revision is None:
- self._build_entries()
- return self._revision
-
- def get_externals(self):
- prop_files = [['.svn', 'dir-prop-base'],
- ['.svn', 'dir-props']]
- externals = []
-
- for dirname in self.iter_dirs():
- prop_file = None
- for rel_parts in prop_files:
- filename = joinpath(dirname, *rel_parts)
- if os.path.isfile(filename):
- prop_file = filename
-
- if prop_file is not None:
- ext_prop = parse_prop_file(prop_file, 'svn:externals')
- #ext_prop should be utf-8 coming from svn:externals
- ext_prop = decode_as_string(ext_prop, encoding="utf-8")
- externals.extend(parse_external_prop(ext_prop))
-
- return externals
-
-
-def svn_finder(dirname=''):
- #combined externals due to common interface
- #combined externals and entries due to lack of dir_props in 1.7
- info = SvnInfo.load(dirname)
- for path in info.iter_files():
- yield path
-
- for path in info.iter_externals():
- sub_info = SvnInfo.load(path)
- for sub_path in sub_info.iter_files():
- yield sub_path
-
-
-class SVNEntriesFile(object):
- def __init__(self, data):
- self.data = data
-
- @classmethod
- def load(class_, base):
- filename = os.path.join(base, '.svn', 'entries')
- f = open(filename)
- try:
- result = SVNEntriesFile.read(f)
- finally:
- f.close()
- return result
-
- @classmethod
- def read(class_, fileobj):
- data = fileobj.read()
- is_xml = data.startswith('<?xml')
- class_ = [SVNEntriesFileText, SVNEntriesFileXML][is_xml]
- return class_(data)
-
- def parse_revision(self):
- all_revs = self.parse_revision_numbers() + [0]
- return max(all_revs)
-
-
-class SVNEntriesFileText(SVNEntriesFile):
- known_svn_versions = {
- '1.4.x': 8,
- '1.5.x': 9,
- '1.6.x': 10,
- }
-
- def __get_cached_sections(self):
- return self.sections
-
- def get_sections(self):
- SECTION_DIVIDER = '\f\n'
- sections = self.data.split(SECTION_DIVIDER)
- sections = [x for x in map(str.splitlines, sections)]
- try:
- # remove the SVN version number from the first line
- svn_version = int(sections[0].pop(0))
- if not svn_version in self.known_svn_versions.values():
- log.warn("Unknown subversion verson %d", svn_version)
- except ValueError:
- return
- self.sections = sections
- self.get_sections = self.__get_cached_sections
- return self.sections
-
- def is_valid(self):
- return bool(self.get_sections())
-
- def get_url(self):
- return self.get_sections()[0][4]
-
- def parse_revision_numbers(self):
- revision_line_number = 9
- rev_numbers = [
- int(section[revision_line_number])
- for section in self.get_sections()
- if (len(section) > revision_line_number
- and section[revision_line_number])
- ]
- return rev_numbers
-
- def get_undeleted_records(self):
- undeleted = lambda s: s and s[0] and (len(s) < 6 or s[5] != 'delete')
- result = [
- section[0]
- for section in self.get_sections()
- if undeleted(section)
- ]
- return result
-
-
-class SVNEntriesFileXML(SVNEntriesFile):
- def is_valid(self):
- return True
-
- def get_url(self):
- "Get repository URL"
- urlre = re.compile('url="([^"]+)"')
- return urlre.search(self.data).group(1)
-
- def parse_revision_numbers(self):
- revre = re.compile(r'committed-rev="(\d+)"')
- return [
- int(m.group(1))
- for m in revre.finditer(self.data)
- ]
-
- def get_undeleted_records(self):
- entries_pattern = \
- re.compile(r'name="([^"]+)"(?![^>]+deleted="true")', re.I)
- results = [
- unescape(match.group(1))
- for match in entries_pattern.finditer(self.data)
- ]
- return results
-
-
-if __name__ == '__main__':
- for name in svn_finder(sys.argv[1]):
- print(name)
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py
index 823cf937..8cde6f60 100644
--- a/setuptools/tests/__init__.py
+++ b/setuptools/tests/__init__.py
@@ -1,8 +1,6 @@
"""Tests for the 'setuptools' package"""
import sys
import os
-import unittest
-import doctest
import distutils.core
import distutils.cmd
from distutils.errors import DistutilsOptionError, DistutilsPlatformError
@@ -11,23 +9,13 @@ from distutils.core import Extension
from distutils.version import LooseVersion
import six
+import pytest
import setuptools.dist
import setuptools.depends as dep
from setuptools import Feature
from setuptools.depends import Require
-def additional_tests():
- suite = unittest.TestSuite((
- doctest.DocFileSuite(
- os.path.join('tests', 'api_tests.txt'),
- optionflags=doctest.ELLIPSIS, package='pkg_resources',
- ),
- ))
- if sys.platform == 'win32':
- suite.addTest(doctest.DocFileSuite('win_script_wrapper.txt'))
- return suite
-
def makeSetup(**args):
"""Return distribution from 'setup(**args)', without executing commands"""
@@ -42,7 +30,12 @@ def makeSetup(**args):
distutils.core._setup_stop_after = None
-class DependsTests(unittest.TestCase):
+needs_bytecode = pytest.mark.skipif(
+ not hasattr(dep, 'get_module_constant'),
+ reason="bytecode support not available",
+)
+
+class TestDepends:
def testExtractConst(self):
if not hasattr(dep, 'extract_constant'):
@@ -55,86 +48,77 @@ class DependsTests(unittest.TestCase):
y = z
fc = six.get_function_code(f1)
+
# unrecognized name
- self.assertEqual(dep.extract_constant(fc,'q', -1), None)
+ assert dep.extract_constant(fc,'q', -1) is None
# constant assigned
- self.assertEqual(dep.extract_constant(fc,'x', -1), "test")
+ dep.extract_constant(fc,'x', -1) == "test"
# expression assigned
- self.assertEqual(dep.extract_constant(fc,'y', -1), -1)
+ dep.extract_constant(fc,'y', -1) == -1
# recognized name, not assigned
- self.assertEqual(dep.extract_constant(fc,'z', -1), None)
+ dep.extract_constant(fc,'z', -1) is None
def testFindModule(self):
- self.assertRaises(ImportError, dep.find_module, 'no-such.-thing')
- self.assertRaises(ImportError, dep.find_module, 'setuptools.non-existent')
+ 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.close()
+ @needs_bytecode
def testModuleExtract(self):
- if not hasattr(dep, 'get_module_constant'):
- # skip on non-bytecode platforms
- return
-
from email import __version__
- self.assertEqual(
- dep.get_module_constant('email','__version__'), __version__
- )
- self.assertEqual(
- dep.get_module_constant('sys','version'), sys.version
- )
- self.assertEqual(
- 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):
- if not hasattr(dep, 'extract_constant'):
- # skip on non-bytecode platformsh
- return
-
req = Require('Email','1.0.3','email')
- self.assertEqual(req.name, 'Email')
- self.assertEqual(req.module, 'email')
- self.assertEqual(req.requested_version, '1.0.3')
- self.assertEqual(req.attribute, '__version__')
- self.assertEqual(req.full_name(), 'Email-1.0.3')
+ assert req.name == 'Email'
+ assert req.module == 'email'
+ assert req.requested_version == '1.0.3'
+ assert req.attribute == '__version__'
+ assert req.full_name() == 'Email-1.0.3'
from email import __version__
- self.assertEqual(req.get_version(), __version__)
- self.assertTrue(req.version_ok('1.0.9'))
- self.assertTrue(not req.version_ok('0.9.1'))
- self.assertTrue(not req.version_ok('unknown'))
+ assert req.get_version() == __version__
+ assert req.version_ok('1.0.9')
+ assert not req.version_ok('0.9.1')
+ assert not req.version_ok('unknown')
- self.assertTrue(req.is_present())
- self.assertTrue(req.is_current())
+ assert req.is_present()
+ assert req.is_current()
req = Require('Email 3000','03000','email',format=LooseVersion)
- self.assertTrue(req.is_present())
- self.assertTrue(not req.is_current())
- self.assertTrue(not req.version_ok('unknown'))
+ 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')
- self.assertTrue(not req.is_present())
- self.assertTrue(not req.is_current())
+ assert not req.is_present()
+ assert not req.is_current()
req = Require('Tests', None, 'tests', homepage="http://example.com")
- self.assertEqual(req.format, None)
- self.assertEqual(req.attribute, None)
- self.assertEqual(req.requested_version, None)
- self.assertEqual(req.full_name(), 'Tests')
- self.assertEqual(req.homepage, 'http://example.com')
+ assert req.format is None
+ assert req.attribute is None
+ assert req.requested_version is None
+ assert req.full_name() == 'Tests'
+ assert req.homepage == 'http://example.com'
paths = [os.path.dirname(p) for p in __path__]
- self.assertTrue(req.is_present(paths))
- self.assertTrue(req.is_current(paths))
+ assert req.is_present(paths)
+ assert req.is_current(paths)
-class DistroTests(unittest.TestCase):
+class TestDistro:
- def setUp(self):
+ def setup_method(self, method):
self.e1 = Extension('bar.ext',['bar.c'])
self.e2 = Extension('c.y', ['y.c'])
@@ -146,21 +130,21 @@ class DistroTests(unittest.TestCase):
)
def testDistroType(self):
- self.assertTrue(isinstance(self.dist,setuptools.dist.Distribution))
+ assert isinstance(self.dist,setuptools.dist.Distribution)
def testExcludePackage(self):
self.dist.exclude_package('a')
- self.assertEqual(self.dist.packages, ['b','c'])
+ assert self.dist.packages == ['b','c']
self.dist.exclude_package('b')
- self.assertEqual(self.dist.packages, ['c'])
- self.assertEqual(self.dist.py_modules, ['x'])
- self.assertEqual(self.dist.ext_modules, [self.e1, self.e2])
+ assert self.dist.packages == ['c']
+ assert self.dist.py_modules == ['x']
+ assert self.dist.ext_modules == [self.e1, self.e2]
self.dist.exclude_package('c')
- self.assertEqual(self.dist.packages, [])
- self.assertEqual(self.dist.py_modules, ['x'])
- self.assertEqual(self.dist.ext_modules, [self.e1])
+ assert self.dist.packages == []
+ assert self.dist.py_modules == ['x']
+ assert self.dist.ext_modules == [self.e1]
# test removals from unspecified options
makeSetup().exclude_package('x')
@@ -168,21 +152,21 @@ class DistroTests(unittest.TestCase):
def testIncludeExclude(self):
# remove an extension
self.dist.exclude(ext_modules=[self.e1])
- self.assertEqual(self.dist.ext_modules, [self.e2])
+ assert self.dist.ext_modules == [self.e2]
# add it back in
self.dist.include(ext_modules=[self.e1])
- self.assertEqual(self.dist.ext_modules, [self.e2, self.e1])
+ assert self.dist.ext_modules == [self.e2, self.e1]
# should not add duplicate
self.dist.include(ext_modules=[self.e1])
- self.assertEqual(self.dist.ext_modules, [self.e2, self.e1])
+ assert self.dist.ext_modules == [self.e2, self.e1]
def testExcludePackages(self):
self.dist.exclude(packages=['c','b','a'])
- self.assertEqual(self.dist.packages, [])
- self.assertEqual(self.dist.py_modules, ['x'])
- self.assertEqual(self.dist.ext_modules, [self.e1])
+ assert self.dist.packages == []
+ assert self.dist.py_modules == ['x']
+ assert self.dist.ext_modules == [self.e1]
def testEmpty(self):
dist = makeSetup()
@@ -191,49 +175,41 @@ class DistroTests(unittest.TestCase):
dist.exclude(packages=['a'], py_modules=['b'], ext_modules=[self.e2])
def testContents(self):
- self.assertTrue(self.dist.has_contents_for('a'))
+ assert self.dist.has_contents_for('a')
self.dist.exclude_package('a')
- self.assertTrue(not self.dist.has_contents_for('a'))
+ assert not self.dist.has_contents_for('a')
- self.assertTrue(self.dist.has_contents_for('b'))
+ assert self.dist.has_contents_for('b')
self.dist.exclude_package('b')
- self.assertTrue(not self.dist.has_contents_for('b'))
+ assert not self.dist.has_contents_for('b')
- self.assertTrue(self.dist.has_contents_for('c'))
+ assert self.dist.has_contents_for('c')
self.dist.exclude_package('c')
- self.assertTrue(not self.dist.has_contents_for('c'))
+ assert not self.dist.has_contents_for('c')
def testInvalidIncludeExclude(self):
- self.assertRaises(DistutilsSetupError,
- self.dist.include, nonexistent_option='x'
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.exclude, nonexistent_option='x'
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.include, packages={'x':'y'}
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.exclude, packages={'x':'y'}
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.include, ext_modules={'x':'y'}
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.exclude, ext_modules={'x':'y'}
- )
-
- self.assertRaises(DistutilsSetupError,
- self.dist.include, package_dir=['q']
- )
- self.assertRaises(DistutilsSetupError,
- self.dist.exclude, package_dir=['q']
- )
-
-
-class FeatureTests(unittest.TestCase):
-
- def setUp(self):
+ with pytest.raises(DistutilsSetupError):
+ self.dist.include(nonexistent_option='x')
+ with pytest.raises(DistutilsSetupError):
+ self.dist.exclude(nonexistent_option='x')
+ with pytest.raises(DistutilsSetupError):
+ self.dist.include(packages={'x':'y'})
+ with pytest.raises(DistutilsSetupError):
+ self.dist.exclude(packages={'x':'y'})
+ with pytest.raises(DistutilsSetupError):
+ self.dist.include(ext_modules={'x':'y'})
+ with pytest.raises(DistutilsSetupError):
+ self.dist.exclude(ext_modules={'x':'y'})
+
+ with pytest.raises(DistutilsSetupError):
+ self.dist.include(package_dir=['q'])
+ with pytest.raises(DistutilsSetupError):
+ self.dist.exclude(package_dir=['q'])
+
+
+class TestFeatures:
+
+ def setup_method(self, method):
self.req = Require('Distutils','1.0.3','distutils')
self.dist = makeSetup(
features={
@@ -255,80 +231,75 @@ class FeatureTests(unittest.TestCase):
)
def testDefaults(self):
- self.assertTrue(not
- Feature(
- "test",standard=True,remove='x',available=False
- ).include_by_default()
- )
- self.assertTrue(
- Feature("test",standard=True,remove='x').include_by_default()
- )
+ assert not Feature(
+ "test",standard=True,remove='x',available=False
+ ).include_by_default()
+ assert Feature("test",standard=True,remove='x').include_by_default()
# Feature must have either kwargs, removes, or require_features
- self.assertRaises(DistutilsSetupError, Feature, "test")
+ with pytest.raises(DistutilsSetupError):
+ Feature("test")
def testAvailability(self):
- self.assertRaises(
- DistutilsPlatformError,
- self.dist.features['dwim'].include_in, self.dist
- )
+ with pytest.raises(DistutilsPlatformError):
+ self.dist.features['dwim'].include_in(self.dist)
def testFeatureOptions(self):
dist = self.dist
- self.assertTrue(
+ assert (
('with-dwim',None,'include DWIM') in dist.feature_options
)
- self.assertTrue(
+ assert (
('without-dwim',None,'exclude DWIM (default)') in dist.feature_options
)
- self.assertTrue(
+ assert (
('with-bar',None,'include bar (default)') in dist.feature_options
)
- self.assertTrue(
+ assert (
('without-bar',None,'exclude bar') in dist.feature_options
)
- self.assertEqual(dist.feature_negopt['without-foo'],'with-foo')
- self.assertEqual(dist.feature_negopt['without-bar'],'with-bar')
- self.assertEqual(dist.feature_negopt['without-dwim'],'with-dwim')
- self.assertTrue(not 'without-baz' in dist.feature_negopt)
+ 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)
def testUseFeatures(self):
dist = self.dist
- self.assertEqual(dist.with_foo,1)
- self.assertEqual(dist.with_bar,0)
- self.assertEqual(dist.with_baz,1)
- self.assertTrue(not 'bar_et' in dist.py_modules)
- self.assertTrue(not 'pkg.bar' in dist.packages)
- self.assertTrue('pkg.baz' in dist.packages)
- self.assertTrue('scripts/baz_it' in dist.scripts)
- self.assertTrue(('libfoo','foo/foofoo.c') in dist.libraries)
- self.assertEqual(dist.ext_modules,[])
- self.assertEqual(dist.require_features, [self.req])
+ 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 ('pkg.baz' in dist.packages)
+ assert ('scripts/baz_it' in dist.scripts)
+ assert (('libfoo','foo/foofoo.c') in dist.libraries)
+ assert dist.ext_modules == []
+ assert dist.require_features == [self.req]
# If we ask for bar, it should fail because we explicitly disabled
# it on the command line
- self.assertRaises(DistutilsOptionError, dist.include_feature, 'bar')
+ with pytest.raises(DistutilsOptionError):
+ dist.include_feature('bar')
def testFeatureWithInvalidRemove(self):
- self.assertRaises(
- SystemExit, makeSetup, features = {'x':Feature('x', remove='y')}
- )
+ with pytest.raises(SystemExit):
+ makeSetup(features={'x':Feature('x', remove='y')})
-class TestCommandTests(unittest.TestCase):
+class TestCommandTests:
def testTestIsCommand(self):
test_cmd = makeSetup().get_command_obj('test')
- self.assertTrue(isinstance(test_cmd, distutils.cmd.Command))
+ assert (isinstance(test_cmd, distutils.cmd.Command))
def testLongOptSuiteWNoDefault(self):
ts1 = makeSetup(script_args=['test','--test-suite=foo.tests.suite'])
ts1 = ts1.get_command_obj('test')
ts1.ensure_finalized()
- self.assertEqual(ts1.test_suite, 'foo.tests.suite')
+ assert ts1.test_suite == 'foo.tests.suite'
def testDefaultSuite(self):
ts2 = makeSetup(test_suite='bar.tests.suite').get_command_obj('test')
ts2.ensure_finalized()
- self.assertEqual(ts2.test_suite, 'bar.tests.suite')
+ assert ts2.test_suite == 'bar.tests.suite'
def testDefaultWModuleOnCmdLine(self):
ts3 = makeSetup(
@@ -336,16 +307,17 @@ class TestCommandTests(unittest.TestCase):
script_args=['test','-m','foo.tests']
).get_command_obj('test')
ts3.ensure_finalized()
- self.assertEqual(ts3.test_module, 'foo.tests')
- self.assertEqual(ts3.test_suite, 'foo.tests.test_suite')
+ assert ts3.test_module == 'foo.tests'
+ assert ts3.test_suite == 'foo.tests.test_suite'
def testConflictingOptions(self):
ts4 = makeSetup(
script_args=['test','-m','bar.tests', '-s','foo.tests.suite']
).get_command_obj('test')
- self.assertRaises(DistutilsOptionError, ts4.ensure_finalized)
+ with pytest.raises(DistutilsOptionError):
+ ts4.ensure_finalized()
def testNoSuite(self):
ts5 = makeSetup().get_command_obj('test')
ts5.ensure_finalized()
- self.assertEqual(ts5.test_suite, None)
+ assert ts5.test_suite == None
diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py
new file mode 100644
index 00000000..fabab071
--- /dev/null
+++ b/setuptools/tests/contexts.py
@@ -0,0 +1,93 @@
+import tempfile
+import os
+import shutil
+import sys
+import contextlib
+import site
+
+import six
+
+
+@contextlib.contextmanager
+def tempdir(cd=lambda dir:None, **kwargs):
+ temp_dir = tempfile.mkdtemp(**kwargs)
+ orig_dir = os.getcwd()
+ try:
+ cd(temp_dir)
+ yield temp_dir
+ finally:
+ cd(orig_dir)
+ shutil.rmtree(temp_dir)
+
+
+@contextlib.contextmanager
+def environment(**replacements):
+ """
+ In a context, patch the environment with replacements. Pass None values
+ to clear the values.
+ """
+ saved = dict(
+ (key, os.environ['key'])
+ for key in replacements
+ if key in os.environ
+ )
+
+ # remove values that are null
+ remove = (key for (key, value) in replacements.items() if value is None)
+ for key in list(remove):
+ os.environ.pop(key, None)
+ replacements.pop(key)
+
+ os.environ.update(replacements)
+
+ try:
+ yield saved
+ finally:
+ for key in replacements:
+ os.environ.pop(key, None)
+ os.environ.update(saved)
+
+
+@contextlib.contextmanager
+def argv(repl):
+ old_argv = sys.argv[:]
+ sys.argv[:] = repl
+ yield
+ sys.argv[:] = old_argv
+
+
+@contextlib.contextmanager
+def quiet():
+ """
+ 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
+
+
+@contextlib.contextmanager
+def save_user_site_setting():
+ saved = site.ENABLE_USER_SITE
+ try:
+ yield saved
+ finally:
+ site.ENABLE_USER_SITE = saved
+
+
+@contextlib.contextmanager
+def suppress_exceptions(*excs):
+ try:
+ yield
+ except excs:
+ pass
diff --git a/setuptools/tests/entries-v10 b/setuptools/tests/entries-v10
deleted file mode 100644
index 4446c501..00000000
--- a/setuptools/tests/entries-v10
+++ /dev/null
@@ -1,615 +0,0 @@
-10
-
-dir
-89001
-http://svn.python.org/projects/sandbox/branches/setuptools-0.6
-http://svn.python.org/projects
-
-
-
-2013-06-03T17:26:03.052972Z
-89000
-phillip.eby
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6015fed2-1504-0410-9fe1-9d1591cc4771
-
-api_tests.txt
-file
-
-
-
-
-2013-06-19T13:20:47.948712Z
-dec366372ca14fbeaeb26f492bcf5725
-2013-05-15T22:04:59.389374Z
-88997
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-12312
-
-setuptools.egg-info
-dir
-
-README.txt
-file
-
-
-
-
-2013-06-19T13:20:47.948712Z
-26f0dd5d095522ba3ad999b6b6777b92
-2011-05-31T20:10:56.416725Z
-88846
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7615
-
-easy_install.py
-file
-
-
-
-
-2013-06-19T13:20:47.948712Z
-97b52fe7253bf4683f9f626f015eb72e
-2006-09-20T20:48:18.716070Z
-51935
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-126
-
-setuptools
-dir
-
-launcher.c
-file
-
-
-
-
-2013-06-19T13:20:47.924700Z
-e5a8e77de9022688b80f77fc6d742fee
-2009-10-19T21:03:29.785400Z
-75544
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7476
-
-ez_setup.py
-file
-
-
-
-
-2013-06-19T13:20:47.924700Z
-17e8ec5e08faccfcb08b5f8d5167ca14
-2011-01-20T18:50:00.815420Z
-88124
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-8350
-
-version
-file
-
-
-
-
-2013-06-19T13:20:47.924700Z
-e456da09e0c9e224a56302f8316b6dbf
-2007-01-09T19:21:05.921317Z
-53317
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1143
-
-setup.py
-file
-
-
-
-
-2013-06-19T13:20:47.924700Z
-d4e5b3c16bd61bfef6c0bb9377a3a3ea
-2013-05-15T22:04:59.389374Z
-88997
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5228
-
-release.sh
-file
-
-
-
-
-2013-06-19T13:20:47.932704Z
-b1fd4054a1c107ff0f27baacd97be94c
-2009-10-28T17:12:45.227140Z
-75925
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1044
-
-pkg_resources.txt
-file
-
-
-
-
-2013-06-19T13:20:47.928702Z
-f497e7c92a4de207cbd9ab1943f93388
-2009-10-12T20:00:02.336146Z
-75385
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-94518
-
-site.py
-file
-
-
-
-
-2013-06-19T13:20:47.932704Z
-ebaac6fb6525f77ca950d22e6f8315df
-2006-03-11T00:39:09.666740Z
-42965
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2362
-
-version.dat
-file
-
-
-
-
-2013-06-19T13:20:47.932704Z
-8e14ecea32b9874cd7d29277494554c0
-2009-10-28T17:12:45.227140Z
-75925
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-80
-
-virtual-python.py
-file
-
-
-
-
-2013-06-19T13:20:47.932704Z
-aa857add3b5563238f0a904187f5ded9
-2005-10-17T02:26:39.000000Z
-41262
-pje
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3898
-
-setup.cfg
-file
-
-
-
-
-2013-06-19T13:20:47.932704Z
-eda883e744fce83f8107ad8dc8303536
-2006-09-21T22:26:48.050256Z
-51965
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-296
-
-setuptools.txt
-file
-
-
-
-
-2013-06-19T13:20:47.940708Z
-11926256f06046b196eaf814772504e7
-2013-05-15T22:04:59.389374Z
-88997
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-149832
-
-pkg_resources.py
-file
-
-
-
-
-2013-06-19T13:20:47.940708Z
-b63a30f5f0f0225a788c2c0e3430b3cf
-2013-05-15T22:04:59.389374Z
-88997
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-90397
-
-tests
-dir
-
-wikiup.cfg
-file
-
-
-
-
-2013-06-19T13:20:47.944710Z
-34ad845a5e0a0b46458557fa910bf429
-2008-08-21T17:23:50.797633Z
-65935
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-136
-
-EasyInstall.txt
-file
-
-
-
-
-2013-06-19T13:20:47.944710Z
-e97387c517f70fc18a377e42d19d64d4
-2013-05-15T22:04:59.389374Z
-88997
-phillip.eby
-has-props
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-82495
-
diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py
index c8d0e669..a23c0504 100644
--- a/setuptools/tests/environment.py
+++ b/setuptools/tests/environment.py
@@ -1,68 +1,10 @@
import os
-import zipfile
import sys
-import tempfile
-import unittest
-import shutil
-import stat
import unicodedata
from subprocess import Popen as _Popen, PIPE as _PIPE
-def _remove_dir(target):
-
- #on windows this seems to a problem
- for dir_path, dirs, files in os.walk(target):
- os.chmod(dir_path, stat.S_IWRITE)
- for filename in files:
- os.chmod(os.path.join(dir_path, filename), stat.S_IWRITE)
- shutil.rmtree(target)
-
-
-class ZippedEnvironment(unittest.TestCase):
-
- datafile = None
- dataname = None
- old_cwd = None
-
- def setUp(self):
- if self.datafile is None or self.dataname is None:
- return
-
- if not os.path.isfile(self.datafile):
- self.old_cwd = None
- return
-
- self.old_cwd = os.getcwd()
-
- self.temp_dir = tempfile.mkdtemp()
- zip_file, source, target = [None, None, None]
- try:
- zip_file = zipfile.ZipFile(self.datafile)
- for files in zip_file.namelist():
- zip_file.extract(files, self.temp_dir)
- finally:
- if zip_file:
- zip_file.close()
- del zip_file
-
- os.chdir(os.path.join(self.temp_dir, self.dataname))
-
- def tearDown(self):
- #Assume setUp was never completed
- if self.dataname is None or self.datafile is None:
- return
-
- try:
- if self.old_cwd:
- os.chdir(self.old_cwd)
- _remove_dir(self.temp_dir)
- except OSError:
- #sigh?
- pass
-
-
def _which_dirs(cmd):
result = set()
for path in os.environ.get('PATH', '').split(os.pathsep):
diff --git a/setuptools/tests/fixtures.py b/setuptools/tests/fixtures.py
new file mode 100644
index 00000000..0b1eaf5f
--- /dev/null
+++ b/setuptools/tests/fixtures.py
@@ -0,0 +1,24 @@
+import mock
+import pytest
+
+from . import contexts
+
+
+@pytest.yield_fixture
+def user_override():
+ """
+ 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
+
+
+@pytest.yield_fixture
+def tmpdir_cwd(tmpdir):
+ with tmpdir.as_cwd() as orig:
+ yield orig
diff --git a/setuptools/tests/py26compat.py b/setuptools/tests/py26compat.py
index d4fb891a..c53b4809 100644
--- a/setuptools/tests/py26compat.py
+++ b/setuptools/tests/py26compat.py
@@ -1,14 +1,11 @@
-import unittest
+import sys
+import tarfile
+import contextlib
-try:
- # provide skipIf for Python 2.4-2.6
- skipIf = unittest.skipIf
-except AttributeError:
- def skipIf(condition, reason):
- def skipper(func):
- def skip(*args, **kwargs):
- return
- if condition:
- return skip
- return func
- return skipper
+def _tarfile_open_ex(*args, **kwargs):
+ """
+ Extend result as a context manager.
+ """
+ return contextlib.closing(tarfile.open(*args, **kwargs))
+
+tarfile_open = _tarfile_open_ex if sys.version_info < (2,7) else tarfile.open
diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py
index 099e8b19..1fee0563 100644
--- a/setuptools/tests/server.py
+++ b/setuptools/tests/server.py
@@ -1,10 +1,10 @@
"""Basic http server for tests to simulate PyPI or custom indexes
"""
-import sys
+
import time
import threading
-from six.moves import BaseHTTPServer, SimpleHTTPServer, urllib
+from six.moves import BaseHTTPServer, SimpleHTTPServer
class IndexServer(BaseHTTPServer.HTTPServer):
"""Basic single-threaded http server simulating a package index
@@ -23,12 +23,8 @@ class IndexServer(BaseHTTPServer.HTTPServer):
RequestHandlerClass)
self._run = True
- def serve(self):
- while self._run:
- self.handle_request()
-
def start(self):
- self.thread = threading.Thread(target=self.serve)
+ self.thread = threading.Thread(target=self.serve_forever)
self.thread.start()
def stop(self):
@@ -37,19 +33,7 @@ class IndexServer(BaseHTTPServer.HTTPServer):
# Let the server finish the last request and wait for a new one.
time.sleep(0.1)
- # self.shutdown is not supported on python < 2.6, so just
- # set _run to false, and make a request, causing it to
- # terminate.
- self._run = False
- url = 'http://127.0.0.1:%(server_port)s/' % vars(self)
- try:
- if sys.version_info >= (2, 6):
- urllib.request.urlopen(url, timeout=5)
- else:
- urllib.request.urlopen(url)
- except urllib.error.URLError:
- # ignore any errors; all that's important is the request
- pass
+ self.shutdown()
self.thread.join()
self.socket.close()
@@ -78,6 +62,6 @@ class MockServer(BaseHTTPServer.HTTPServer, threading.Thread):
def run(self):
self.serve_forever()
+ @property
def url(self):
return 'http://localhost:%(server_port)s/' % vars(self)
- url = property(url)
diff --git a/setuptools/tests/svn_data/dummy.zip b/setuptools/tests/svn_data/dummy.zip
deleted file mode 100644
index 1347be53..00000000
--- a/setuptools/tests/svn_data/dummy.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy13.zip b/setuptools/tests/svn_data/dummy13.zip
deleted file mode 100644
index 47764342..00000000
--- a/setuptools/tests/svn_data/dummy13.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy14.zip b/setuptools/tests/svn_data/dummy14.zip
deleted file mode 100644
index 02ed8cf0..00000000
--- a/setuptools/tests/svn_data/dummy14.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy15.zip b/setuptools/tests/svn_data/dummy15.zip
deleted file mode 100644
index ed8daeeb..00000000
--- a/setuptools/tests/svn_data/dummy15.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy16.zip b/setuptools/tests/svn_data/dummy16.zip
deleted file mode 100644
index b6e98d6c..00000000
--- a/setuptools/tests/svn_data/dummy16.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy17.zip b/setuptools/tests/svn_data/dummy17.zip
deleted file mode 100644
index d96e1513..00000000
--- a/setuptools/tests/svn_data/dummy17.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/dummy18.zip b/setuptools/tests/svn_data/dummy18.zip
deleted file mode 100644
index a7267838..00000000
--- a/setuptools/tests/svn_data/dummy18.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn13_example.zip b/setuptools/tests/svn_data/svn13_example.zip
deleted file mode 100644
index d85fb84f..00000000
--- a/setuptools/tests/svn_data/svn13_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn13_ext_list.txt b/setuptools/tests/svn_data/svn13_ext_list.txt
deleted file mode 100644
index 0bb0f438..00000000
--- a/setuptools/tests/svn_data/svn13_ext_list.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party3 file:///C:/development/svn_example/repos/svn13/extra1
-third_party2 -r3 file:///C:/development/svn_example/repos/svn13/extra1
-third_party -r1 file:///C:/development/svn_example/repos/svn13/extra1
diff --git a/setuptools/tests/svn_data/svn13_ext_list.xml b/setuptools/tests/svn_data/svn13_ext_list.xml
deleted file mode 100644
index e69de29b..00000000
--- a/setuptools/tests/svn_data/svn13_ext_list.xml
+++ /dev/null
diff --git a/setuptools/tests/svn_data/svn13_info.xml b/setuptools/tests/svn_data/svn13_info.xml
deleted file mode 100644
index 5c96520a..00000000
--- a/setuptools/tests/svn_data/svn13_info.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<info>
-<entry
- kind="dir"
- path="svn13_example"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<prop-updated>2013-07-13T15:33:23.187500Z</prop-updated>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:33:28.359375Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn13_example\a file"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main/a%20file</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:33:21.109375Z</text-updated>
-<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:33:21.312500Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn13_example\to_delete"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main/to_delete</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>delete</schedule>
-<text-updated>2013-07-13T15:33:28.140625Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:33:28.359375Z</date>
-</commit>
-</entry>
-<entry
- kind="dir"
- path="svn13_example\folder"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main/folder</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<prop-updated>2013-07-13T15:33:26.187500Z</prop-updated>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:33:26.312500Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn13_example\folder\quest.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main/folder/quest.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:33:20.109375Z</text-updated>
-<checksum>795240c6a830c14f83961e57e07dad12</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:33:20.312500Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn13_example\folder\lalala.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn13/main/folder/lalala.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn13/main</root>
-<uuid>d2996769-47b0-9946-b618-da1aa3eceda3</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:33:19.375000Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:33:19.609375Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/svn_data/svn14_example.zip b/setuptools/tests/svn_data/svn14_example.zip
deleted file mode 100644
index 57093c0b..00000000
--- a/setuptools/tests/svn_data/svn14_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn14_ext_list.txt b/setuptools/tests/svn_data/svn14_ext_list.txt
deleted file mode 100644
index 800a0965..00000000
--- a/setuptools/tests/svn_data/svn14_ext_list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-third_party3 file:///C:/development/svn_example/repos/svn13/extra1
-third_party2 -r3 file:///C:/development/svn_example/repos/svn13/extra1
-third_party -r1 file:///C:/development/svn_example/repos/svn13/extra1
-
diff --git a/setuptools/tests/svn_data/svn14_ext_list.xml b/setuptools/tests/svn_data/svn14_ext_list.xml
deleted file mode 100644
index e69de29b..00000000
--- a/setuptools/tests/svn_data/svn14_ext_list.xml
+++ /dev/null
diff --git a/setuptools/tests/svn_data/svn14_info.xml b/setuptools/tests/svn_data/svn14_info.xml
deleted file mode 100644
index a896a77f..00000000
--- a/setuptools/tests/svn_data/svn14_info.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="svn14_example"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:34:14.406250Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn14_example\a file"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main/a%20file</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:34:08.109375Z</text-updated>
-<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:34:08.390625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn14_example\to_delete"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main/to_delete</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>delete</schedule>
-<text-updated>2013-07-13T15:34:14.125000Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:34:14.406250Z</date>
-</commit>
-</entry>
-<entry
- kind="dir"
- path="svn14_example\folder"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main/folder</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:34:12.390625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn14_example\folder\quest.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main/folder/quest.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:34:07.109375Z</text-updated>
-<checksum>795240c6a830c14f83961e57e07dad12</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:34:07.390625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn14_example\folder\lalala.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn14/main/folder/lalala.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn14/main</root>
-<uuid>c75942e5-8b7a-354d-b1cf-73dee23fa94f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<text-updated>2013-07-13T15:34:06.250000Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:34:06.531250Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/svn_data/svn15_example.zip b/setuptools/tests/svn_data/svn15_example.zip
deleted file mode 100644
index 52a1d45b..00000000
--- a/setuptools/tests/svn_data/svn15_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn15_ext_list.txt b/setuptools/tests/svn_data/svn15_ext_list.txt
deleted file mode 100644
index 75fde4e6..00000000
--- a/setuptools/tests/svn_data/svn15_ext_list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-third_party3 file:///C:/development/svn_example/repos/svn15/extra1
--r3 file:///C:/development/svn_example/repos/svn15/extra1 third_party2
-file:///C:/development/svn_example/repos/svn15/extra1@r1 third_party
-
diff --git a/setuptools/tests/svn_data/svn15_ext_list.xml b/setuptools/tests/svn_data/svn15_ext_list.xml
deleted file mode 100644
index 6950b3c5..00000000
--- a/setuptools/tests/svn_data/svn15_ext_list.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<properties>
-<target
- path="C:/development/svn_example/svn15_example/folder">
-<property
- name="svn:externals">third_party3 file:///C:/development/svn_example/repos/svn15/extra2
--r3 file:///C:/development/svn_example/repos/svn15/extra2 third_party2
-file:///C:/development/svn_example/repos/svn15/extra2@r1 third_party大介
-</property>
-</target>
-<target
- path="C:/development/svn_example/svn15_example">
-<property
- name="svn:externals">third_party3 file:///C:/development/svn_example/repos/svn15/extra1
--r3 file:///C:/development/svn_example/repos/svn15/extra1 third_party2
-file:///C:/development/svn_example/repos/svn15/extra1@r1 third_party大介
-</property>
-</target>
-</properties>
diff --git a/setuptools/tests/svn_data/svn15_info.xml b/setuptools/tests/svn_data/svn15_info.xml
deleted file mode 100644
index 0b3550af..00000000
--- a/setuptools/tests/svn_data/svn15_info.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="svn15_example"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:34:49.562500Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn15_example\a file"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main/a%20file</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:34:43.109375Z</text-updated>
-<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:34:43.484375Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn15_example\to_delete"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main/to_delete</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>delete</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:34:49.125000Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:34:49.562500Z</date>
-</commit>
-</entry>
-<entry
- kind="dir"
- path="svn15_example\folder"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main/folder</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:34:47.515625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn15_example\folder\quest.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main/folder/quest.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:34:42.109375Z</text-updated>
-<checksum>795240c6a830c14f83961e57e07dad12</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:34:42.484375Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn15_example\folder\lalala.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn15/main/folder/lalala.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn15/main</root>
-<uuid>4eab6983-54fe-384b-a282-9306f52d948f</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:34:41.375000Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:34:41.734375Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/svn_data/svn16_example.zip b/setuptools/tests/svn_data/svn16_example.zip
deleted file mode 100644
index e886b2af..00000000
--- a/setuptools/tests/svn_data/svn16_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn16_ext_list.txt b/setuptools/tests/svn_data/svn16_ext_list.txt
deleted file mode 100644
index 3ca54893..00000000
--- a/setuptools/tests/svn_data/svn16_ext_list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-"third party3" file:///C:/development/svn_example/repos/svn16/extra1
-'third party3b' file:///C:/development/svn_example/repos/svn16/extra1
--r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party
diff --git a/setuptools/tests/svn_data/svn16_ext_list.xml b/setuptools/tests/svn_data/svn16_ext_list.xml
deleted file mode 100644
index 8ddaed0a..00000000
--- a/setuptools/tests/svn_data/svn16_ext_list.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<properties>
-<target
- path="C:/development/svn_example/svn16_example/folder">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra2
--r3 file:///C:/development/svn_example/repos/svn16/extra2 third\ party2
-file:///C:/development/svn_example/repos/svn16/extra2@r1 third_party大介
-</property>
-</target>
-<target
- path="C:/development/svn_example/svn16_example">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
--r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
-</property>
-</target>
-</properties>
diff --git a/setuptools/tests/svn_data/svn16_info.xml b/setuptools/tests/svn_data/svn16_info.xml
deleted file mode 100644
index 745469c9..00000000
--- a/setuptools/tests/svn_data/svn16_info.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="svn16_example"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:17.390625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn16_example\a file"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main/a%20file</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:14.578125Z</text-updated>
-<checksum>a6166e5e98a5a503089cde9bc8031293</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:35:14.906250Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn16_example\to_delete"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main/to_delete</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>delete</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:17.046875Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:17.390625Z</date>
-</commit>
-</entry>
-<entry
- kind="dir"
- path="svn16_example\folder"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main/folder</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:35:16.406250Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn16_example\folder\quest.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main/folder/quest.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:14.078125Z</text-updated>
-<checksum>795240c6a830c14f83961e57e07dad12</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:35:14.421875Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn16_example\folder\lalala.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn16/main/folder/lalala.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn16/main</root>
-<uuid>bd8d2cfc-1a74-de45-b166-262010c17c0a</uuid>
-</repository>
-<wc-info>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:12.171875Z</text-updated>
-<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:35:13.906250Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/svn_data/svn17_example.zip b/setuptools/tests/svn_data/svn17_example.zip
deleted file mode 100644
index ba0e8823..00000000
--- a/setuptools/tests/svn_data/svn17_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn17_ext_list.txt b/setuptools/tests/svn_data/svn17_ext_list.txt
deleted file mode 100644
index a8b832a8..00000000
--- a/setuptools/tests/svn_data/svn17_ext_list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-"third party3" file:///C:/development/svn_example/repos/svn17/extra1
-'third party3b' file:///C:/development/svn_example/repos/svn17/extra1
--r3 file:///C:/development/svn_example/repos/svn17/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn17/extra1@r1 third_party
diff --git a/setuptools/tests/svn_data/svn17_ext_list.xml b/setuptools/tests/svn_data/svn17_ext_list.xml
deleted file mode 100644
index 2879bb65..00000000
--- a/setuptools/tests/svn_data/svn17_ext_list.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<properties>
-<target
- path="C:/development/svn_example/svn17_example">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
--r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
-</property>
-</target>
-<target
- path="C:/development/svn_example/svn17_example/folder">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn17/extra2
--r3 file:///C:/development/svn_example/repos/svn17/extra2 third\ party2
-file:///C:/development/svn_example/repos/svn17/extra2@r1 third_party大介
-</property>
-</target>
-</properties>
diff --git a/setuptools/tests/svn_data/svn17_info.xml b/setuptools/tests/svn_data/svn17_info.xml
deleted file mode 100644
index 6cffeffd..00000000
--- a/setuptools/tests/svn_data/svn17_info.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<info>
-<entry
- kind="dir"
- path="svn17_example"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn17/main</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:36.171875Z</date>
-</commit>
-</entry>
-<entry
- path="svn17_example\folder"
- revision="6"
- kind="dir">
-<url>file:///C:/development/svn_example/repos/svn17/main/folder</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:35:34.859375Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn17_example\folder\quest.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn17/main/folder/quest.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:32.812500Z</text-updated>
-<checksum>bc80eba9e7a10c0a571a4678c520bc9683f3bac2</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:35:33.109375Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn17_example\folder\lalala.txt"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn17/main/folder/lalala.txt</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:32.343750Z</text-updated>
-<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:35:32.687500Z</date>
-</commit>
-</entry>
-<entry
- path="svn17_example\a file"
- revision="6"
- kind="file">
-<url>file:///C:/development/svn_example/repos/svn17/main/a%20file</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:33.187500Z</text-updated>
-<checksum>43785ab4b1816b49f242990883292813cd4f486c</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:35:33.515625Z</date>
-</commit>
-</entry>
-<entry
- path="svn17_example\to_delete"
- revision="6"
- kind="file">
-<url>file:///C:/development/svn_example/repos/svn17/main/to_delete</url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn17/main</root>
-<uuid>5ba45434-5197-164e-afab-81923f4744f5</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn17_example</wcroot-abspath>
-<schedule>delete</schedule>
-<depth>infinity</depth>
-<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:36.171875Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/svn_data/svn18_example.zip b/setuptools/tests/svn_data/svn18_example.zip
deleted file mode 100644
index 4362f8e9..00000000
--- a/setuptools/tests/svn_data/svn18_example.zip
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/svn_data/svn18_ext_list.txt b/setuptools/tests/svn_data/svn18_ext_list.txt
deleted file mode 100644
index c90a5f11..00000000
--- a/setuptools/tests/svn_data/svn18_ext_list.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-"third party3" file:///C:/development/svn_example/repos/svn18/extra1
-'third party3b' file:///C:/development/svn_example/repos/svn18/extra1
--r3 file:///C:/development/svn_example/repos/svn18/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn18/extra1@r1 third_party
diff --git a/setuptools/tests/svn_data/svn18_ext_list.xml b/setuptools/tests/svn_data/svn18_ext_list.xml
deleted file mode 100644
index 9b5e9e96..00000000
--- a/setuptools/tests/svn_data/svn18_ext_list.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<properties>
-<target
- path="C:/development/svn_example/svn18_example">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn16/extra1
--r3 file:///C:/development/svn_example/repos/svn16/extra1 third\ party2
-file:///C:/development/svn_example/repos/svn16/extra1@r1 third_party大介
-</property>
-</target>
-<target
- path="C:/development/svn_example/svn18_example/folder">
-<property
- name="svn:externals">"third party3" file:///C:/development/svn_example/repos/svn18/extra2
--r3 file:///C:/development/svn_example/repos/svn18/extra2 third\ party2
-file:///C:/development/svn_example/repos/svn18/extra2@r1 third_party大介
-</property>
-</target>
-</properties>
diff --git a/setuptools/tests/svn_data/svn18_info.xml b/setuptools/tests/svn_data/svn18_info.xml
deleted file mode 100644
index 7ca55995..00000000
--- a/setuptools/tests/svn_data/svn18_info.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<info>
-<entry
- path="svn18_example"
- revision="6"
- kind="dir">
-<url>file:///C:/development/svn_example/repos/svn18/main</url>
-<relative-url>^/</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:57.796875Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn18_example\a file"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn18/main/a%20file</url>
-<relative-url>^/a%20file</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:54.906250Z</text-updated>
-<checksum>43785ab4b1816b49f242990883292813cd4f486c</checksum>
-</wc-info>
-<commit
- revision="3">
-<author>ptt</author>
-<date>2013-07-13T15:35:55.265625Z</date>
-</commit>
-</entry>
-<entry
- kind="file"
- path="svn18_example\to_delete"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn18/main/to_delete</url>
-<relative-url>^/to_delete</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>delete</schedule>
-<depth>infinity</depth>
-<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
-</wc-info>
-<commit
- revision="6">
-<author>ptt</author>
-<date>2013-07-13T15:35:57.796875Z</date>
-</commit>
-</entry>
-<entry
- kind="dir"
- path="svn18_example\folder"
- revision="6">
-<url>file:///C:/development/svn_example/repos/svn18/main/folder</url>
-<relative-url>^/folder</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-</wc-info>
-<commit
- revision="5">
-<author>ptt</author>
-<date>2013-07-13T15:35:56.750000Z</date>
-</commit>
-</entry>
-<entry
- path="svn18_example\folder\quest.txt"
- revision="6"
- kind="file">
-<url>file:///C:/development/svn_example/repos/svn18/main/folder/quest.txt</url>
-<relative-url>^/folder/quest.txt</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:54.484375Z</text-updated>
-<checksum>bc80eba9e7a10c0a571a4678c520bc9683f3bac2</checksum>
-</wc-info>
-<commit
- revision="2">
-<author>ptt</author>
-<date>2013-07-13T15:35:54.843750Z</date>
-</commit>
-</entry>
-<entry
- path="svn18_example\folder\lalala.txt"
- revision="6"
- kind="file">
-<url>file:///C:/development/svn_example/repos/svn18/main/folder/lalala.txt</url>
-<relative-url>^/folder/lalala.txt</relative-url>
-<repository>
-<root>file:///C:/development/svn_example/repos/svn18/main</root>
-<uuid>3c5e3929-c92b-7045-9ba9-5e65d3dd1ee9</uuid>
-</repository>
-<wc-info>
-<wcroot-abspath>C:/development/svn_example/svn18_example</wcroot-abspath>
-<schedule>normal</schedule>
-<depth>infinity</depth>
-<text-updated>2013-07-13T15:35:54.015625Z</text-updated>
-<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
-</wc-info>
-<commit
- revision="1">
-<author>ptt</author>
-<date>2013-07-13T15:35:54.375000Z</date>
-</commit>
-</entry>
-</info>
diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py
index 937e0ed0..f8a68378 100644
--- a/setuptools/tests/test_bdist_egg.py
+++ b/setuptools/tests/test_bdist_egg.py
@@ -2,53 +2,32 @@
"""
import os
import re
-import shutil
-import site
-import sys
-import tempfile
-import unittest
import six
+import pytest
-from distutils.errors import DistutilsError
-from setuptools.command.bdist_egg import bdist_egg
-from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
+from . import contexts
+
SETUP_PY = """\
from setuptools import setup
setup(name='foo', py_modules=['hi'])
"""
-class TestDevelopTest(unittest.TestCase):
-
- def setUp(self):
- self.dir = tempfile.mkdtemp()
- self.old_cwd = os.getcwd()
- os.chdir(self.dir)
- f = open('setup.py', 'w')
+@pytest.yield_fixture
+def setup_context(tmpdir):
+ with (tmpdir/'setup.py').open('w') as f:
f.write(SETUP_PY)
- f.close()
- f = open('hi.py', 'w')
+ with (tmpdir/'hi.py').open('w') as f:
f.write('1\n')
- f.close()
- if sys.version >= "2.6":
- self.old_base = site.USER_BASE
- site.USER_BASE = tempfile.mkdtemp()
- self.old_site = site.USER_SITE
- site.USER_SITE = tempfile.mkdtemp()
+ with tmpdir.as_cwd():
+ yield tmpdir
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.dir)
- if sys.version >= "2.6":
- shutil.rmtree(site.USER_BASE)
- shutil.rmtree(site.USER_SITE)
- site.USER_BASE = self.old_base
- site.USER_SITE = self.old_site
- def test_bdist_egg(self):
+class Test:
+ def test_bdist_egg(self, setup_context, user_override):
dist = Distribution(dict(
script_name='setup.py',
script_args=['bdist_egg'],
@@ -56,17 +35,10 @@ class TestDevelopTest(unittest.TestCase):
py_modules=['hi']
))
os.makedirs(os.path.join('build', 'src'))
- old_stdout = sys.stdout
- sys.stdout = o = six.StringIO()
- try:
+ with contexts.quiet():
dist.parse_command_line()
dist.run_commands()
- finally:
- sys.stdout = old_stdout
# let's see if we got our egg link at the right place
[content] = os.listdir('dist')
- self.assertTrue(re.match('foo-0.0.0-py[23].\d.egg$', content))
-
-def test_suite():
- return unittest.makeSuite(TestDevelopTest)
+ assert re.match('foo-0.0.0-py[23].\d.egg$', content)
diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py
index a92e53ae..0719ba44 100644
--- a/setuptools/tests/test_build_ext.py
+++ b/setuptools/tests/test_build_ext.py
@@ -1,19 +1,18 @@
-"""build_ext tests
-"""
-import unittest
-from distutils.command.build_ext import build_ext as distutils_build_ext
+import distutils.command.build_ext as orig
+
from setuptools.command.build_ext import build_ext
from setuptools.dist import Distribution
-class TestBuildExtTest(unittest.TestCase):
-
+class TestBuildExt:
def test_get_ext_filename(self):
- # setuptools needs to give back the same
- # result than distutils, even if the fullname
- # is not in ext_map
+ """
+ Setuptools needs to give back the same
+ result as distutils, even if the fullname
+ is not in ext_map.
+ """
dist = Distribution()
cmd = build_ext(dist)
cmd.ext_map['foo/bar'] = ''
res = cmd.get_ext_filename('foo')
- wanted = distutils_build_ext.get_ext_filename(cmd, 'foo')
+ wanted = orig.build_ext.get_ext_filename(cmd, 'foo')
assert res == wanted
diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py
index 66d182eb..ed1b194a 100644
--- a/setuptools/tests/test_develop.py
+++ b/setuptools/tests/test_develop.py
@@ -5,9 +5,7 @@ import shutil
import site
import sys
import tempfile
-import unittest
-from distutils.errors import DistutilsError
from setuptools.command.develop import develop
from setuptools.dist import Distribution
@@ -23,10 +21,10 @@ setup(name='foo',
INIT_PY = """print "foo"
"""
-class TestDevelopTest(unittest.TestCase):
+class TestDevelopTest:
- def setUp(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
+ def setup_method(self, method):
+ if hasattr(sys, 'real_prefix'):
return
# Directory structure
@@ -50,8 +48,8 @@ class TestDevelopTest(unittest.TestCase):
self.old_site = site.USER_SITE
site.USER_SITE = tempfile.mkdtemp()
- def tearDown(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
+ def teardown_method(self, method):
+ if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
return
os.chdir(self.old_cwd)
@@ -62,7 +60,7 @@ class TestDevelopTest(unittest.TestCase):
site.USER_SITE = self.old_site
def test_develop(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
+ if hasattr(sys, 'real_prefix'):
return
dist = Distribution(
dict(name='foo',
@@ -86,7 +84,7 @@ class TestDevelopTest(unittest.TestCase):
# let's see if we got our egg link at the right place
content = os.listdir(site.USER_SITE)
content.sort()
- self.assertEqual(content, ['easy-install.pth', 'foo.egg-link'])
+ assert content == ['easy-install.pth', 'foo.egg-link']
# Check that we are using the right code.
egg_link_file = open(os.path.join(site.USER_SITE, 'foo.egg-link'), 'rt')
@@ -100,23 +98,6 @@ class TestDevelopTest(unittest.TestCase):
finally:
init_file.close()
if sys.version < "3":
- self.assertEqual(init, 'print "foo"')
+ assert init == 'print "foo"'
else:
- self.assertEqual(init, 'print("foo")')
-
- def notest_develop_with_setup_requires(self):
-
- wanted = ("Could not find suitable distribution for "
- "Requirement.parse('I-DONT-EXIST')")
- old_dir = os.getcwd()
- os.chdir(self.dir)
- try:
- try:
- Distribution({'setup_requires': ['I_DONT_EXIST']})
- except DistutilsError:
- e = sys.exc_info()[1]
- error = str(e)
- if error == wanted:
- pass
- finally:
- os.chdir(old_dir)
+ assert init == 'print("foo")'
diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py
index a8adb68c..6d0ab587 100644
--- a/setuptools/tests/test_dist_info.py
+++ b/setuptools/tests/test_dist_info.py
@@ -3,28 +3,20 @@
import os
import shutil
import tempfile
-import unittest
-import textwrap
-try:
- import ast
-except:
- pass
+import pytest
import pkg_resources
+from .textwrap import DALS
-from setuptools.tests.py26compat import skipIf
-def DALS(s):
- "dedent and left-strip"
- return textwrap.dedent(s).lstrip()
-
-class TestDistInfo(unittest.TestCase):
+class TestDistInfo:
def test_distinfo(self):
- dists = {}
- for d in pkg_resources.find_distributions(self.tmpdir):
- dists[d.project_name] = d
+ dists = dict(
+ (d.project_name, d)
+ for d in pkg_resources.find_distributions(self.tmpdir)
+ )
assert len(dists) == 2, dists
@@ -34,50 +26,45 @@ class TestDistInfo(unittest.TestCase):
assert versioned.version == '2.718' # from filename
assert unversioned.version == '0.3' # from METADATA
- @skipIf('ast' not in globals(),
- "ast is used to test conditional dependencies (Python >= 2.6)")
+ @pytest.mark.importorskip('ast')
def test_conditional_dependencies(self):
- requires = [pkg_resources.Requirement.parse('splort==4'),
- pkg_resources.Requirement.parse('quux>=1.1')]
+ specs = 'splort==4', 'quux>=1.1'
+ requires = list(map(pkg_resources.Requirement.parse, specs))
for d in pkg_resources.find_distributions(self.tmpdir):
- self.assertEqual(d.requires(), requires[:1])
- self.assertEqual(d.requires(extras=('baz',)), requires)
- self.assertEqual(d.extras, ['baz'])
+ assert d.requires() == requires[:1]
+ assert d.requires(extras=('baz',)) == requires
+ 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(self):
+ def setup_method(self, method):
self.tmpdir = tempfile.mkdtemp()
- versioned = os.path.join(self.tmpdir,
- 'VersionedDistribution-2.718.dist-info')
+ dist_info_name = 'VersionedDistribution-2.718.dist-info'
+ versioned = os.path.join(self.tmpdir, dist_info_name)
os.mkdir(versioned)
- metadata_file = open(os.path.join(versioned, 'METADATA'), 'w+')
- try:
- metadata_file.write(DALS(
- """
- Metadata-Version: 1.2
- Name: VersionedDistribution
- Requires-Dist: splort (4)
- Provides-Extra: baz
- Requires-Dist: quux (>=1.1); extra == 'baz'
- """))
- finally:
- metadata_file.close()
- unversioned = os.path.join(self.tmpdir,
- 'UnversionedDistribution.dist-info')
+ 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)
- metadata_file = open(os.path.join(unversioned, 'METADATA'), 'w+')
- try:
- metadata_file.write(DALS(
- """
- Metadata-Version: 1.2
- Name: UnversionedDistribution
- Version: 0.3
- Requires-Dist: splort (==4)
- Provides-Extra: baz
- Requires-Dist: quux (>=1.1); extra == 'baz'
- """))
- finally:
- metadata_file.close()
+ 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(self):
+ 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 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
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index e803a41e..a1caf9fd 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -1,210 +1,98 @@
-
import os
-import sys
-import tempfile
-import shutil
-import unittest
-
-import pkg_resources
-import warnings
-from setuptools.command import egg_info
-from setuptools import svn_utils
-from setuptools.tests import environment, test_svn
-from setuptools.tests.py26compat import skipIf
-
-ENTRIES_V10 = pkg_resources.resource_string(__name__, 'entries-v10')
-"An entries file generated with svn 1.6.17 against the legacy Setuptools repo"
-
-
-class TestEggInfo(unittest.TestCase):
-
- def setUp(self):
- self.test_dir = tempfile.mkdtemp()
- os.mkdir(os.path.join(self.test_dir, '.svn'))
-
- self.old_cwd = os.getcwd()
- os.chdir(self.test_dir)
-
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.test_dir)
-
- def _write_entries(self, entries):
- fn = os.path.join(self.test_dir, '.svn', 'entries')
- entries_f = open(fn, 'wb')
- entries_f.write(entries)
- entries_f.close()
-
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_version_10_format(self):
- """
- """
- #keeping this set for 1.6 is a good check on the get_svn_revision
- #to ensure I return using svnversion what would had been returned
- version_str = svn_utils.SvnInfo.get_svn_version()
- version = [int(x) for x in version_str.split('.')[:2]]
- if version != [1, 6]:
- if hasattr(self, 'skipTest'):
- self.skipTest('')
- else:
- sys.stderr.write('\n Skipping due to SVN Version\n')
- return
-
- self._write_entries(ENTRIES_V10)
- rev = egg_info.egg_info.get_svn_revision()
- self.assertEqual(rev, '89000')
-
- def test_version_10_format_legacy_parser(self):
- """
- """
- path_variable = None
- for env in os.environ:
- if env.lower() == 'path':
- path_variable = env
-
- if path_variable:
- old_path = os.environ[path_variable]
- os.environ[path_variable] = ''
- #catch_warnings not available until py26
- warning_filters = warnings.filters
- warnings.filters = warning_filters[:]
- try:
- warnings.simplefilter("ignore", DeprecationWarning)
- self._write_entries(ENTRIES_V10)
- rev = egg_info.egg_info.get_svn_revision()
- finally:
- #restore the warning filters
- warnings.filters = warning_filters
- #restore the os path
- if path_variable:
- os.environ[path_variable] = old_path
-
- self.assertEqual(rev, '89000')
-
-DUMMY_SOURCE_TXT = """CHANGES.txt
-CONTRIBUTORS.txt
-HISTORY.txt
-LICENSE
-MANIFEST.in
-README.txt
-setup.py
-dummy/__init__.py
-dummy/test.txt
-dummy.egg-info/PKG-INFO
-dummy.egg-info/SOURCES.txt
-dummy.egg-info/dependency_links.txt
-dummy.egg-info/top_level.txt"""
-
-
-class TestSvnDummy(environment.ZippedEnvironment):
-
- def setUp(self):
- version = svn_utils.SvnInfo.get_svn_version()
- if not version: # None or Empty
- return None
-
- self.base_version = tuple([int(x) for x in version.split('.')][:2])
-
- if not self.base_version:
- raise ValueError('No SVN tools installed')
- elif self.base_version < (1, 3):
- raise ValueError('Insufficient SVN Version %s' % version)
- elif self.base_version >= (1, 9):
- #trying the latest version
- self.base_version = (1, 8)
-
- self.dataname = "dummy%i%i" % self.base_version
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', self.dataname + ".zip")
- super(TestSvnDummy, self).setUp()
-
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_sources(self):
- code, data = environment.run_setup_py(["sdist"],
- pypath=self.old_cwd,
- data_stream=1)
+import stat
+
+import pytest
+
+from . import environment
+from .textwrap import DALS
+from . import contexts
+
+
+class TestEggInfo:
+
+ setup_script = DALS("""
+ from setuptools import setup
+
+ setup(
+ name='foo',
+ py_modules=['hello'],
+ entry_points={'console_scripts': ['hi = hello.run']},
+ zip_safe=False,
+ )
+ """)
+
+ def _create_project(self):
+ with open('setup.py', 'w') as f:
+ f.write(self.setup_script)
+
+ with open('hello.py', 'w') as f:
+ f.write(DALS("""
+ def run():
+ print('hello')
+ """))
+
+ @pytest.yield_fixture
+ def env(self):
+ class Environment(str): pass
+
+ with contexts.tempdir(prefix='setuptools-test.') as env_dir:
+ env = Environment(env_dir)
+ os.chmod(env_dir, stat.S_IRWXU)
+ subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
+ env.paths = dict(
+ (dirname, os.path.join(env_dir, dirname))
+ for dirname in subs
+ )
+ list(map(os.mkdir, env.paths.values()))
+ config = os.path.join(env.paths['home'], '.pydistutils.cfg')
+ with open(config, 'w') as f:
+ f.write(DALS("""
+ [egg_info]
+ egg-base = %(egg-base)s
+ """ % env.paths
+ ))
+ yield env
+
+ def test_egg_base_installed_egg_info(self, tmpdir_cwd, env):
+ self._create_project()
+
+ environ = os.environ.copy().update(
+ HOME=env.paths['home'],
+ )
+ cmd = [
+ 'install',
+ '--home', env.paths['home'],
+ '--install-lib', env.paths['lib'],
+ '--install-scripts', env.paths['scripts'],
+ '--install-data', env.paths['data'],
+ ]
+ code, data = environment.run_setup_py(
+ cmd=cmd,
+ pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+ data_stream=1,
+ env=environ,
+ )
if code:
raise AssertionError(data)
- sources = os.path.join('dummy.egg-info', 'SOURCES.txt')
- infile = open(sources, 'r')
- try:
- read_contents = infile.read()
- finally:
- infile.close()
- del infile
-
- self.assertEqual(DUMMY_SOURCE_TXT, read_contents)
-
- return data
-
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_svn_tags(self):
- code, data = environment.run_setup_py(["egg_info",
- "--tag-svn-revision"],
- pypath=self.old_cwd,
- data_stream=1)
- if code:
- raise AssertionError(data)
-
- pkginfo = os.path.join('dummy.egg-info', 'PKG-INFO')
- infile = open(pkginfo, 'r')
- try:
- read_contents = infile.readlines()
- finally:
- infile.close()
- del infile
-
- self.assertTrue("Version: 0.1.1-r1\n" in read_contents)
-
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_no_tags(self):
- code, data = environment.run_setup_py(["egg_info"],
- pypath=self.old_cwd,
- data_stream=1)
- if code:
- raise AssertionError(data)
-
- pkginfo = os.path.join('dummy.egg-info', 'PKG-INFO')
- infile = open(pkginfo, 'r')
- try:
- read_contents = infile.readlines()
- finally:
- infile.close()
- del infile
-
- self.assertTrue("Version: 0.1.1\n" in read_contents)
-
-
-class TestSvnDummyLegacy(environment.ZippedEnvironment):
-
- def setUp(self):
- self.base_version = (1, 6)
- self.dataname = "dummy%i%i" % self.base_version
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', self.dataname + ".zip")
- super(TestSvnDummyLegacy, self).setUp()
-
- def test_sources(self):
- code, data = environment.run_setup_py(["sdist"],
- pypath=self.old_cwd,
- path="",
- data_stream=1)
- if code:
- raise AssertionError(data)
-
- sources = os.path.join('dummy.egg-info', 'SOURCES.txt')
- infile = open(sources, 'r')
- try:
- read_contents = infile.read()
- finally:
- infile.close()
- del infile
-
- self.assertEqual(DUMMY_SOURCE_TXT, read_contents)
-
- return data
-
-
-def test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
+ actual = self._find_egg_info_files(env.paths['lib'])
+
+ expected = [
+ 'PKG-INFO',
+ 'SOURCES.txt',
+ 'dependency_links.txt',
+ 'entry_points.txt',
+ 'not-zip-safe',
+ 'top_level.txt',
+ ]
+ assert sorted(actual) == expected
+
+ def _find_egg_info_files(self, root):
+ results = (
+ filenames
+ for dirpath, dirnames, filenames in os.walk(root)
+ if os.path.basename(dirpath) == 'EGG-INFO'
+ )
+ # expect exactly one result
+ result, = results
+ return result
diff --git a/setuptools/tests/test_find_packages.py b/setuptools/tests/test_find_packages.py
index fe390728..06a7c02e 100644
--- a/setuptools/tests/test_find_packages.py
+++ b/setuptools/tests/test_find_packages.py
@@ -3,12 +3,12 @@ import os
import sys
import shutil
import tempfile
-import unittest
import platform
+import pytest
+
import setuptools
from setuptools import find_packages
-from setuptools.tests.py26compat import skipIf
find_420_packages = setuptools.PEP420PackageFinder.find
@@ -33,13 +33,13 @@ def has_symlink():
)
return can_symlink() and not bad_symlink
-class TestFindPackages(unittest.TestCase):
+class TestFindPackages:
- def setUp(self):
+ def setup_method(self, method):
self.dist_dir = tempfile.mkdtemp()
self._make_pkg_structure()
- def tearDown(self):
+ def teardown_method(self, method):
shutil.rmtree(self.dist_dir)
def _make_pkg_structure(self):
@@ -87,7 +87,7 @@ class TestFindPackages(unittest.TestCase):
def test_regular_package(self):
self._touch('__init__.py', self.pkg_dir)
packages = find_packages(self.dist_dir)
- self.assertEqual(packages, ['pkg', 'pkg.subpkg'])
+ assert packages == ['pkg', 'pkg.subpkg']
def test_exclude(self):
self._touch('__init__.py', self.pkg_dir)
@@ -102,7 +102,7 @@ class TestFindPackages(unittest.TestCase):
alt_dir = self._mkdir('other_pkg', self.dist_dir)
self._touch('__init__.py', alt_dir)
packages = find_packages(self.dist_dir, include=['other_pkg'])
- self.assertEqual(packages, ['other_pkg'])
+ assert packages == ['other_pkg']
def test_dir_with_dot_is_skipped(self):
shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))
@@ -110,7 +110,7 @@ class TestFindPackages(unittest.TestCase):
self._touch('__init__.py', data_dir)
self._touch('file.dat', data_dir)
packages = find_packages(self.dist_dir)
- self.assertTrue('pkg.some.data' not in packages)
+ assert 'pkg.some.data' not in packages
def test_dir_with_packages_in_subdir_is_excluded(self):
"""
@@ -121,9 +121,9 @@ class TestFindPackages(unittest.TestCase):
build_pkg_dir = self._mkdir('pkg', build_dir)
self._touch('__init__.py', build_pkg_dir)
packages = find_packages(self.dist_dir)
- self.assertTrue('build.pkg' not in packages)
+ assert 'build.pkg' not in packages
- @skipIf(not has_symlink(), 'Symlink support required')
+ @pytest.mark.skipif(not has_symlink(), reason='Symlink support required')
def test_symlinked_packages_are_included(self):
"""
A symbolically-linked directory should be treated like any other
@@ -136,10 +136,10 @@ class TestFindPackages(unittest.TestCase):
os.symlink('pkg', linked_pkg)
assert os.path.isdir(linked_pkg)
packages = find_packages(self.dist_dir)
- self.assertTrue('lpkg' in packages)
+ assert 'lpkg' in packages
def _assert_packages(self, actual, expected):
- self.assertEqual(set(actual), set(expected))
+ assert set(actual) == set(expected)
def test_pep420_ns_package(self):
packages = find_420_packages(
diff --git a/setuptools/tests/test_integration.py b/setuptools/tests/test_integration.py
index 8d6c1e55..3a6abeaa 100644
--- a/setuptools/tests/test_integration.py
+++ b/setuptools/tests/test_integration.py
@@ -27,7 +27,7 @@ def install_context(request, tmpdir, monkeypatch):
def fin():
# undo the monkeypatch, particularly needed under
# windows because of kept handle on cwd
- monkeypatch.undo()
+ monkeypatch.undo()
new_cwd.remove()
user_base.remove()
user_site.remove()
@@ -71,7 +71,6 @@ def test_virtualenvwrapper(install_context):
'virtualenvwrapper', 'hook_loader.py')
-@pytest.mark.xfail
def test_pbr(install_context):
_install_one('pbr', install_context,
'pbr', 'core.py')
diff --git a/setuptools/tests/test_markerlib.py b/setuptools/tests/test_markerlib.py
index dae71cba..8197b49d 100644
--- a/setuptools/tests/test_markerlib.py
+++ b/setuptools/tests/test_markerlib.py
@@ -1,48 +1,43 @@
import os
-import unittest
-from setuptools.tests.py26compat import skipIf
-try:
- import ast
-except ImportError:
- pass
+import pytest
-class TestMarkerlib(unittest.TestCase):
- @skipIf('ast' not in globals(),
- "ast not available (Python < 2.6?)")
+class TestMarkerlib:
+
+ @pytest.mark.importorskip('ast')
def test_markers(self):
from _markerlib import interpret, default_environment, compile
-
+
os_name = os.name
-
- self.assertTrue(interpret(""))
-
- self.assertTrue(interpret("os.name != 'buuuu'"))
- self.assertTrue(interpret("os_name != 'buuuu'"))
- self.assertTrue(interpret("python_version > '1.0'"))
- self.assertTrue(interpret("python_version < '5.0'"))
- self.assertTrue(interpret("python_version <= '5.0'"))
- self.assertTrue(interpret("python_version >= '1.0'"))
- self.assertTrue(interpret("'%s' in os.name" % os_name))
- self.assertTrue(interpret("'%s' in os_name" % os_name))
- self.assertTrue(interpret("'buuuu' not in os.name"))
-
- self.assertFalse(interpret("os.name == 'buuuu'"))
- self.assertFalse(interpret("os_name == 'buuuu'"))
- self.assertFalse(interpret("python_version < '1.0'"))
- self.assertFalse(interpret("python_version > '5.0'"))
- self.assertFalse(interpret("python_version >= '5.0'"))
- self.assertFalse(interpret("python_version <= '1.0'"))
- self.assertFalse(interpret("'%s' not in os.name" % os_name))
- self.assertFalse(interpret("'buuuu' in os.name and python_version >= '5.0'"))
- self.assertFalse(interpret("'buuuu' in os_name and python_version >= '5.0'"))
-
+
+ assert interpret("")
+
+ assert interpret("os.name != 'buuuu'")
+ assert interpret("os_name != 'buuuu'")
+ assert interpret("python_version > '1.0'")
+ assert interpret("python_version < '5.0'")
+ assert interpret("python_version <= '5.0'")
+ assert interpret("python_version >= '1.0'")
+ assert interpret("'%s' in os.name" % os_name)
+ assert interpret("'%s' in os_name" % os_name)
+ assert interpret("'buuuu' not in os.name")
+
+ assert not interpret("os.name == 'buuuu'")
+ assert not interpret("os_name == 'buuuu'")
+ assert not interpret("python_version < '1.0'")
+ assert not interpret("python_version > '5.0'")
+ assert not interpret("python_version >= '5.0'")
+ assert not interpret("python_version <= '1.0'")
+ assert not interpret("'%s' not in os.name" % os_name)
+ assert not interpret("'buuuu' in os.name and python_version >= '5.0'")
+ assert not interpret("'buuuu' in os_name and python_version >= '5.0'")
+
environment = default_environment()
environment['extra'] = 'test'
- self.assertTrue(interpret("extra == 'test'", environment))
- self.assertFalse(interpret("extra == 'doc'", environment))
-
+ assert interpret("extra == 'test'", environment)
+ assert not interpret("extra == 'doc'", environment)
+
def raises_nameError():
try:
interpret("python.version == '42'")
@@ -50,9 +45,9 @@ class TestMarkerlib(unittest.TestCase):
pass
else:
raise Exception("Expected NameError")
-
+
raises_nameError()
-
+
def raises_syntaxError():
try:
interpret("(x for x in (4,))")
@@ -60,9 +55,9 @@ class TestMarkerlib(unittest.TestCase):
pass
else:
raise Exception("Expected SyntaxError")
-
+
raises_syntaxError()
-
+
statement = "python_version == '5'"
- self.assertEqual(compile(statement).__doc__, statement)
-
+ assert compile(statement).__doc__ == statement
+
diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py
index 970f7679..a0820fff 100644
--- a/setuptools/tests/test_msvc9compiler.py
+++ b/setuptools/tests/test_msvc9compiler.py
@@ -1,157 +1,173 @@
-"""msvc9compiler monkey patch test
-
-This test ensures that importing setuptools is sufficient to replace
-the standard find_vcvarsall function with our patched version that
-finds the Visual C++ for Python package.
+"""
+Tests for msvc9compiler.
"""
import os
-import shutil
-import sys
-import tempfile
-import unittest
-import distutils.errors
import contextlib
+import distutils.errors
-# importing only setuptools should apply the patch
-__import__('setuptools')
-
-class MockReg:
- """Mock for distutils.msvc9compiler.Reg. We patch it
- with an instance of this class that mocks out the
- functions that access the registry.
- """
-
- def __init__(self, hkey_local_machine={}, hkey_current_user={}):
- self.hklm = hkey_local_machine
- self.hkcu = hkey_current_user
+import pytest
+import mock
- def __enter__(self):
- self.original_read_keys = distutils.msvc9compiler.Reg.read_keys
- self.original_read_values = distutils.msvc9compiler.Reg.read_values
+from . import contexts
- _winreg = getattr(distutils.msvc9compiler, '_winreg', None)
- winreg = getattr(distutils.msvc9compiler, 'winreg', _winreg)
+# importing only setuptools should apply the patch
+__import__('setuptools')
- hives = {
- winreg.HKEY_CURRENT_USER: self.hkcu,
- winreg.HKEY_LOCAL_MACHINE: self.hklm,
- }
+pytest.importorskip("distutils.msvc9compiler")
- def read_keys(cls, base, key):
- """Return list of registry keys."""
- hive = hives.get(base, {})
- return [k.rpartition('\\')[2]
- for k in hive if k.startswith(key.lower())]
- def read_values(cls, base, key):
- """Return dict of registry keys and values."""
- hive = hives.get(base, {})
- return dict((k.rpartition('\\')[2], hive[k])
- for k in hive if k.startswith(key.lower()))
+def mock_reg(hkcu=None, hklm=None):
+ """
+ Return a mock for distutils.msvc9compiler.Reg, patched
+ to mock out the functions that access the registry.
+ """
- distutils.msvc9compiler.Reg.read_keys = classmethod(read_keys)
- distutils.msvc9compiler.Reg.read_values = classmethod(read_values)
+ _winreg = getattr(distutils.msvc9compiler, '_winreg', None)
+ winreg = getattr(distutils.msvc9compiler, 'winreg', _winreg)
+
+ hives = {
+ winreg.HKEY_CURRENT_USER: hkcu or {},
+ winreg.HKEY_LOCAL_MACHINE: hklm or {},
+ }
+
+ @classmethod
+ def read_keys(cls, base, key):
+ """Return list of registry keys."""
+ hive = hives.get(base, {})
+ return [
+ k.rpartition('\\')[2]
+ for k in hive if k.startswith(key.lower())
+ ]
+
+ @classmethod
+ def read_values(cls, base, key):
+ """Return dict of registry keys and values."""
+ hive = hives.get(base, {})
+ return dict(
+ (k.rpartition('\\')[2], hive[k])
+ for k in hive if k.startswith(key.lower())
+ )
- return self
+ return mock.patch.multiple(distutils.msvc9compiler.Reg,
+ read_keys=read_keys, read_values=read_values)
- def __exit__(self, exc_type, exc_value, exc_tb):
- distutils.msvc9compiler.Reg.read_keys = self.original_read_keys
- distutils.msvc9compiler.Reg.read_values = self.original_read_values
-@contextlib.contextmanager
-def patch_env(**replacements):
+class TestModulePatch:
"""
- In a context, patch the environment with replacements. Pass None values
- to clear the values.
+ Ensure that importing setuptools is sufficient to replace
+ the standard find_vcvarsall function with a version that
+ recognizes the "Visual C++ for Python" package.
"""
- saved = dict(
- (key, os.environ['key'])
- for key in replacements
- if key in os.environ
- )
-
- # remove values that are null
- remove = (key for (key, value) in replacements.items() if value is None)
- for key in list(remove):
- os.environ.pop(key, None)
- replacements.pop(key)
-
- os.environ.update(replacements)
-
- try:
- yield saved
- finally:
- for key in replacements:
- os.environ.pop(key, None)
- os.environ.update(saved)
-
-class TestMSVC9Compiler(unittest.TestCase):
-
- def test_find_vcvarsall_patch(self):
- if not hasattr(distutils, 'msvc9compiler'):
- # skip
- return
-
- self.assertEqual(
- "setuptools.msvc9_support",
- distutils.msvc9compiler.find_vcvarsall.__module__,
- "find_vcvarsall was not patched"
- )
+ key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
+ key_64 = r'software\wow6432node\microsoft\devdiv\vcforpython\9.0\installdir'
+
+ 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"
+
+ def test_no_registry_entryies_means_nothing_found(self):
+ """
+ No registry entries or environment variable should lead to an error
+ directing the user to download vcpython27.
+ """
find_vcvarsall = distutils.msvc9compiler.find_vcvarsall
query_vcvarsall = distutils.msvc9compiler.query_vcvarsall
- # No registry entries or environment variable means we should
- # not find anything
- with patch_env(VS90COMNTOOLS=None):
- with MockReg():
- self.assertIsNone(find_vcvarsall(9.0))
+ with contexts.environment(VS90COMNTOOLS=None):
+ with mock_reg():
+ assert find_vcvarsall(9.0) is None
- try:
+ expected = distutils.errors.DistutilsPlatformError
+ with pytest.raises(expected) as exc:
query_vcvarsall(9.0)
- self.fail('Expected DistutilsPlatformError from query_vcvarsall()')
- except distutils.errors.DistutilsPlatformError:
- exc_message = str(sys.exc_info()[1])
- self.assertIn('aka.ms/vcpython27', exc_message)
-
- key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
- key_64 = r'software\wow6432node\microsoft\devdiv\vcforpython\9.0\installdir'
-
- # Make two mock files so we can tell whether HCKU entries are
- # preferred to HKLM entries.
- mock_installdir_1 = tempfile.mkdtemp()
- mock_vcvarsall_bat_1 = os.path.join(mock_installdir_1, 'vcvarsall.bat')
- open(mock_vcvarsall_bat_1, 'w').close()
- mock_installdir_2 = tempfile.mkdtemp()
- mock_vcvarsall_bat_2 = os.path.join(mock_installdir_2, 'vcvarsall.bat')
- open(mock_vcvarsall_bat_2, 'w').close()
- try:
- # Ensure we get the current user's setting first
- with MockReg(
- hkey_current_user={key_32: mock_installdir_1},
- hkey_local_machine={
- key_32: mock_installdir_2,
- key_64: mock_installdir_2,
- }
- ):
- self.assertEqual(mock_vcvarsall_bat_1, find_vcvarsall(9.0))
-
- # Ensure we get the local machine value if it's there
- with MockReg(hkey_local_machine={key_32: mock_installdir_2}):
- self.assertEqual(mock_vcvarsall_bat_2, find_vcvarsall(9.0))
-
- # Ensure we prefer the 64-bit local machine key
- # (*not* the Wow6432Node key)
- with MockReg(
- hkey_local_machine={
- # This *should* only exist on 32-bit machines
- key_32: mock_installdir_1,
- # This *should* only exist on 64-bit machines
- key_64: mock_installdir_2,
- }
- ):
- self.assertEqual(mock_vcvarsall_bat_1, find_vcvarsall(9.0))
- finally:
- shutil.rmtree(mock_installdir_1)
- shutil.rmtree(mock_installdir_2)
+ assert 'aka.ms/vcpython27' in str(exc)
+
+ @pytest.yield_fixture
+ def user_preferred_setting(self):
+ """
+ Set up environment with different install dirs for user vs. system
+ and yield the user_install_dir for the expected result.
+ """
+ with self.mock_install_dir() as user_install_dir:
+ with self.mock_install_dir() as system_install_dir:
+ reg = mock_reg(
+ hkcu={
+ self.key_32: user_install_dir,
+ },
+ hklm={
+ self.key_32: system_install_dir,
+ self.key_64: system_install_dir,
+ },
+ )
+ with reg:
+ yield user_install_dir
+
+ def test_prefer_current_user(self, user_preferred_setting):
+ """
+ Ensure user's settings are preferred.
+ """
+ result = distutils.msvc9compiler.find_vcvarsall(9.0)
+ assert user_preferred_setting == result
+
+ @pytest.yield_fixture
+ def local_machine_setting(self):
+ """
+ Set up environment with only the system environment configured.
+ """
+ with self.mock_install_dir() as system_install_dir:
+ reg = mock_reg(
+ hklm={
+ self.key_32: system_install_dir,
+ },
+ )
+ with reg:
+ yield system_install_dir
+
+ def test_local_machine_recognized(self, local_machine_setting):
+ """
+ Ensure machine setting is honored if user settings are not present.
+ """
+ result = distutils.msvc9compiler.find_vcvarsall(9.0)
+ assert local_machine_setting == result
+
+ @pytest.yield_fixture
+ def x64_preferred_setting(self):
+ """
+ Set up environment with 64-bit and 32-bit system settings configured
+ and yield the 64-bit location.
+ """
+ with self.mock_install_dir() as x32_dir:
+ with self.mock_install_dir() as x64_dir:
+ reg = mock_reg(
+ hklm={
+ # This *should* only exist on 32-bit machines
+ self.key_32: x32_dir,
+ # This *should* only exist on 64-bit machines
+ self.key_64: x64_dir,
+ },
+ )
+ with reg:
+ yield x64_dir
+
+ def test_ensure_64_bit_preferred(self, x64_preferred_setting):
+ """
+ Ensure 64-bit system key is preferred.
+ """
+ result = distutils.msvc9compiler.find_vcvarsall(9.0)
+ assert x64_preferred_setting == result
+
+ @staticmethod
+ @contextlib.contextmanager
+ def mock_install_dir():
+ """
+ Make a mock install dir in a unique location so that tests can
+ distinguish which dir was detected in a given scenario.
+ """
+ with contexts.tempdir() as result:
+ vcvarsall = os.path.join(result, 'vcvarsall.bat')
+ with open(vcvarsall, 'w'):
+ pass
+ yield
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
index 40ae0af3..4eb98bb1 100644
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -1,8 +1,4 @@
-"""Package Index Tests
-"""
import sys
-import os
-import unittest
import distutils.errors
import six
@@ -12,7 +8,8 @@ import pkg_resources
import setuptools.package_index
from setuptools.tests.server import IndexServer
-class TestPackageIndex(unittest.TestCase):
+
+class TestPackageIndex:
def test_bad_url_bad_port(self):
index = setuptools.package_index.PackageIndex()
@@ -21,9 +18,9 @@ class TestPackageIndex(unittest.TestCase):
v = index.open_url(url)
except Exception:
v = sys.exc_info()[1]
- self.assertTrue(url in str(v))
+ assert url in str(v)
else:
- self.assertTrue(isinstance(v, urllib.error.HTTPError))
+ assert isinstance(v, urllib.error.HTTPError)
def test_bad_url_typo(self):
# issue 16
@@ -38,9 +35,9 @@ class TestPackageIndex(unittest.TestCase):
v = index.open_url(url)
except Exception:
v = sys.exc_info()[1]
- self.assertTrue(url in str(v))
+ assert url in str(v)
else:
- self.assertTrue(isinstance(v, urllib.error.HTTPError))
+ assert isinstance(v, urllib.error.HTTPError)
def test_bad_url_bad_status_line(self):
index = setuptools.package_index.PackageIndex(
@@ -56,7 +53,7 @@ class TestPackageIndex(unittest.TestCase):
v = index.open_url(url)
except Exception:
v = sys.exc_info()[1]
- self.assertTrue('line' in str(v))
+ assert 'line' in str(v)
else:
raise AssertionError('Should have raise here!')
@@ -97,7 +94,7 @@ class TestPackageIndex(unittest.TestCase):
hosts=('www.example.com',)
)
url = 'file:///tmp/test_package_index'
- self.assertTrue(index.url_ok(url, True))
+ assert index.url_ok(url, True)
def test_links_priority(self):
"""
@@ -130,21 +127,30 @@ class TestPackageIndex(unittest.TestCase):
server.stop()
# the distribution has been found
- self.assertTrue('foobar' in pi)
+ assert 'foobar' in pi
# we have only one link, because links are compared without md5
- self.assertTrue(len(pi['foobar'])==1)
+ assert len(pi['foobar'])==1
# the link should be from the index
- self.assertTrue('correct_md5' in pi['foobar'][0].location)
+ assert 'correct_md5' in pi['foobar'][0].location
def test_parse_bdist_wininst(self):
- self.assertEqual(setuptools.package_index.parse_bdist_wininst(
- 'reportlab-2.5.win32-py2.4.exe'), ('reportlab-2.5', '2.4', 'win32'))
- self.assertEqual(setuptools.package_index.parse_bdist_wininst(
- 'reportlab-2.5.win32.exe'), ('reportlab-2.5', None, 'win32'))
- self.assertEqual(setuptools.package_index.parse_bdist_wininst(
- 'reportlab-2.5.win-amd64-py2.7.exe'), ('reportlab-2.5', '2.7', 'win-amd64'))
- self.assertEqual(setuptools.package_index.parse_bdist_wininst(
- 'reportlab-2.5.win-amd64.exe'), ('reportlab-2.5', None, 'win-amd64'))
+ parse = setuptools.package_index.parse_bdist_wininst
+
+ actual = parse('reportlab-2.5.win32-py2.4.exe')
+ expected = 'reportlab-2.5', '2.4', 'win32'
+ assert actual == expected
+
+ actual = parse('reportlab-2.5.win32.exe')
+ expected = 'reportlab-2.5', None, 'win32'
+ assert actual == expected
+
+ actual = parse('reportlab-2.5.win-amd64-py2.7.exe')
+ expected = 'reportlab-2.5', '2.7', 'win-amd64'
+ assert actual == expected
+
+ actual = parse('reportlab-2.5.win-amd64.exe')
+ expected = 'reportlab-2.5', None, 'win-amd64'
+ assert actual == expected
def test__vcs_split_rev_from_url(self):
"""
@@ -152,55 +158,51 @@ class TestPackageIndex(unittest.TestCase):
"""
vsrfu = setuptools.package_index.PackageIndex._vcs_split_rev_from_url
url, rev = vsrfu('https://example.com/bar@2995')
- self.assertEqual(url, 'https://example.com/bar')
- self.assertEqual(rev, '2995')
+ assert url == 'https://example.com/bar'
+ assert rev == '2995'
- def test_local_index(self):
+ def test_local_index(self, tmpdir):
"""
local_open should be able to read an index from the file system.
"""
- f = open('index.html', 'w')
- f.write('<div>content</div>')
- f.close()
- try:
- url = 'file:' + urllib.request.pathname2url(os.getcwd()) + '/'
- res = setuptools.package_index.local_open(url)
- finally:
- os.remove('index.html')
+ index_file = tmpdir / 'index.html'
+ with index_file.open('w') as f:
+ f.write('<div>content</div>')
+ url = 'file:' + urllib.request.pathname2url(str(tmpdir)) + '/'
+ res = setuptools.package_index.local_open(url)
assert 'content' in res.read()
-class TestContentCheckers(unittest.TestCase):
+class TestContentCheckers:
def test_md5(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
checker.feed('You should probably not be using MD5'.encode('ascii'))
- self.assertEqual(checker.hash.hexdigest(),
- 'f12895fdffbd45007040d2e44df98478')
- self.assertTrue(checker.is_valid())
+ assert checker.hash.hexdigest() == 'f12895fdffbd45007040d2e44df98478'
+ assert checker.is_valid()
def test_other_fragment(self):
"Content checks should succeed silently if no hash is present"
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#something%20completely%20different')
checker.feed('anything'.encode('ascii'))
- self.assertTrue(checker.is_valid())
+ assert checker.is_valid()
def test_blank_md5(self):
"Content checks should succeed if a hash is empty"
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=')
checker.feed('anything'.encode('ascii'))
- self.assertTrue(checker.is_valid())
+ assert checker.is_valid()
def test_get_hash_name_md5(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
- self.assertEqual(checker.hash_name, 'md5')
+ assert checker.hash_name == 'md5'
def test_report(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
rep = checker.report(lambda x: x, 'My message about %s')
- self.assertEqual(rep, 'My message about md5')
+ assert rep == 'My message about md5'
diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index b688cfe0..465c9343 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -1,21 +1,23 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-# NOTE: the shebang and encoding lines are for ScriptHeaderTests do not remove
+# NOTE: the shebang and encoding lines are for TestScriptHeader do not remove
import os
import sys
import tempfile
import shutil
-from unittest import TestCase
+
+import pytest
import pkg_resources
from pkg_resources import (parse_requirements, VersionConflict, parse_version,
Distribution, EntryPoint, Requirement, safe_version, safe_name,
WorkingSet)
+packaging = pkg_resources.packaging
+
from setuptools.command.easy_install import (get_script_header, is_sh,
nt_quote_arg)
-from .py26compat import skipIf
import six
@@ -46,36 +48,32 @@ class Metadata(pkg_resources.EmptyProvider):
dist_from_fn = pkg_resources.Distribution.from_filename
-class DistroTests(TestCase):
+class TestDistro:
def testCollection(self):
# empty path should produce no distributions
ad = pkg_resources.Environment([], platform=None, python=None)
- self.assertEqual(list(ad), [])
- self.assertEqual(ad['FooPkg'],[])
+ assert list(ad) == []
+ assert ad['FooPkg'] == []
ad.add(dist_from_fn("FooPkg-1.3_1.egg"))
ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg"))
ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg"))
# Name is in there now
- self.assertTrue(ad['FooPkg'])
+ assert ad['FooPkg']
# But only 1 package
- self.assertEqual(list(ad), ['foopkg'])
+ assert list(ad) == ['foopkg']
# Distributions sort by version
- self.assertEqual(
- [dist.version for dist in ad['FooPkg']], ['1.4','1.3-1','1.2']
- )
+ assert [dist.version for dist in ad['FooPkg']] == ['1.4','1.3-1','1.2']
+
# Removing a distribution leaves sequence alone
ad.remove(ad['FooPkg'][1])
- self.assertEqual(
- [dist.version for dist in ad['FooPkg']], ['1.4','1.2']
- )
+ assert [dist.version for dist in ad['FooPkg']] == ['1.4','1.2']
+
# And inserting adds them in order
ad.add(dist_from_fn("FooPkg-1.9.egg"))
- self.assertEqual(
- [dist.version for dist in ad['FooPkg']], ['1.9','1.4','1.2']
- )
+ assert [dist.version for dist in ad['FooPkg']] == ['1.9','1.4','1.2']
ws = WorkingSet([])
foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg")
@@ -83,31 +81,32 @@ class DistroTests(TestCase):
req, = parse_requirements("FooPkg>=1.3")
# Nominal case: no distros on path, should yield all applicable
- self.assertEqual(ad.best_match(req,ws).version, '1.9')
+ assert ad.best_match(req, ws).version == '1.9'
# If a matching distro is already installed, should return only that
ws.add(foo14)
- self.assertEqual(ad.best_match(req,ws).version, '1.4')
+ assert ad.best_match(req, ws).version == '1.4'
# If the first matching distro is unsuitable, it's a version conflict
ws = WorkingSet([])
ws.add(foo12)
ws.add(foo14)
- self.assertRaises(VersionConflict, ad.best_match, req, ws)
+ with pytest.raises(VersionConflict):
+ ad.best_match(req, ws)
# If more than one match on the path, the first one takes precedence
ws = WorkingSet([])
ws.add(foo14)
ws.add(foo12)
ws.add(foo14)
- self.assertEqual(ad.best_match(req,ws).version, '1.4')
+ assert ad.best_match(req, ws).version == '1.4'
def checkFooPkg(self,d):
- self.assertEqual(d.project_name, "FooPkg")
- self.assertEqual(d.key, "foopkg")
- self.assertEqual(d.version, "1.3-1")
- self.assertEqual(d.py_version, "2.4")
- self.assertEqual(d.platform, "win32")
- self.assertEqual(d.parsed_version, parse_version("1.3-1"))
+ assert d.project_name == "FooPkg"
+ assert d.key == "foopkg"
+ assert d.version == "1.3.post1"
+ assert d.py_version == "2.4"
+ assert d.platform == "win32"
+ assert d.parsed_version == parse_version("1.3-1")
def testDistroBasics(self):
d = Distribution(
@@ -117,13 +116,13 @@ class DistroTests(TestCase):
self.checkFooPkg(d)
d = Distribution("/some/path")
- self.assertEqual(d.py_version, sys.version[:3])
- self.assertEqual(d.platform, None)
+ assert d.py_version == sys.version[:3]
+ assert d.platform == None
def testDistroParse(self):
- d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg")
+ d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg")
self.checkFooPkg(d)
- d = dist_from_fn("FooPkg-1.3_1-py2.4-win32.egg-info")
+ d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info")
self.checkFooPkg(d)
def testDistroMetadata(self):
@@ -139,10 +138,7 @@ class DistroTests(TestCase):
return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
def checkRequires(self, dist, txt, extras=()):
- self.assertEqual(
- list(dist.requires(extras)),
- list(parse_requirements(txt))
- )
+ assert list(dist.requires(extras)) == list(parse_requirements(txt))
def testDistroDependsSimple(self):
for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
@@ -152,11 +148,11 @@ class DistroTests(TestCase):
ad = pkg_resources.Environment([])
ws = WorkingSet([])
# Resolving no requirements -> nothing to install
- self.assertEqual(list(ws.resolve([],ad)), [])
+ assert list(ws.resolve([], ad)) == []
# Request something not in the collection -> DistributionNotFound
- self.assertRaises(
- pkg_resources.DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad
- )
+ with pytest.raises(pkg_resources.DistributionNotFound):
+ ws.resolve(parse_requirements("Foo"), ad)
+
Foo = Distribution.from_filename(
"/foo_dir/Foo-1.2.egg",
metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0"))
@@ -167,28 +163,25 @@ class DistroTests(TestCase):
# Request thing(s) that are available -> list to activate
for i in range(3):
targets = list(ws.resolve(parse_requirements("Foo"), ad))
- self.assertEqual(targets, [Foo])
+ assert targets == [Foo]
list(map(ws.add,targets))
- self.assertRaises(VersionConflict, ws.resolve,
- parse_requirements("Foo==0.9"), ad)
+ with pytest.raises(VersionConflict):
+ ws.resolve(parse_requirements("Foo==0.9"), ad)
ws = WorkingSet([]) # reset
# Request an extra that causes an unresolved dependency for "Baz"
- self.assertRaises(
- pkg_resources.DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad
- )
+ with pytest.raises(pkg_resources.DistributionNotFound):
+ ws.resolve(parse_requirements("Foo[bar]"), ad)
Baz = Distribution.from_filename(
"/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
)
ad.add(Baz)
# Activation list now includes resolved dependency
- self.assertEqual(
- list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz]
- )
+ assert list(ws.resolve(parse_requirements("Foo[bar]"), ad)) ==[Foo,Baz]
# Requests for conflicting versions produce VersionConflict
- self.assertRaises(VersionConflict,
- ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
+ with pytest.raises(VersionConflict):
+ ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
def testDistroDependsOptions(self):
d = self.distRequires("""
@@ -213,49 +206,55 @@ class DistroTests(TestCase):
d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
["fastcgi", "docgen"]
)
- self.assertRaises(pkg_resources.UnknownExtra, d.requires, ["foo"])
+ with pytest.raises(pkg_resources.UnknownExtra):
+ d.requires(["foo"])
-class EntryPointTests(TestCase):
+class TestEntryPoints:
def assertfields(self, ep):
- self.assertEqual(ep.name,"foo")
- self.assertEqual(ep.module_name,"setuptools.tests.test_resources")
- self.assertEqual(ep.attrs, ("EntryPointTests",))
- self.assertEqual(ep.extras, ("x",))
- self.assertTrue(ep.load() is EntryPointTests)
- self.assertEqual(
- str(ep),
- "foo = setuptools.tests.test_resources:EntryPointTests [x]"
+ assert ep.name == "foo"
+ assert ep.module_name == "setuptools.tests.test_resources"
+ assert ep.attrs == ("TestEntryPoints",)
+ assert ep.extras == ("x",)
+ assert ep.load() is TestEntryPoints
+ assert (
+ str(ep) ==
+ "foo = setuptools.tests.test_resources:TestEntryPoints [x]"
)
- def setUp(self):
+ def setup_method(self, method):
self.dist = Distribution.from_filename(
"FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt','[x]')))
def testBasics(self):
ep = EntryPoint(
- "foo", "setuptools.tests.test_resources", ["EntryPointTests"],
+ "foo", "setuptools.tests.test_resources", ["TestEntryPoints"],
["x"], self.dist
)
self.assertfields(ep)
def testParse(self):
- s = "foo = setuptools.tests.test_resources:EntryPointTests [x]"
+ s = "foo = setuptools.tests.test_resources:TestEntryPoints [x]"
ep = EntryPoint.parse(s, self.dist)
self.assertfields(ep)
ep = EntryPoint.parse("bar baz= spammity[PING]")
- self.assertEqual(ep.name,"bar baz")
- self.assertEqual(ep.module_name,"spammity")
- self.assertEqual(ep.attrs, ())
- self.assertEqual(ep.extras, ("ping",))
+ assert ep.name == "bar baz"
+ assert ep.module_name == "spammity"
+ assert ep.attrs == ()
+ assert ep.extras == ("ping",)
ep = EntryPoint.parse(" fizzly = wocka:foo")
- self.assertEqual(ep.name,"fizzly")
- self.assertEqual(ep.module_name,"wocka")
- self.assertEqual(ep.attrs, ("foo",))
- self.assertEqual(ep.extras, ())
+ assert ep.name == "fizzly"
+ assert ep.module_name == "wocka"
+ assert ep.attrs == ("foo",)
+ assert ep.extras == ()
+
+ # plus in the name
+ spec = "html+mako = mako.ext.pygmentplugin:MakoHtmlLexer"
+ ep = EntryPoint.parse(spec)
+ assert ep.name == 'html+mako'
def testRejects(self):
for ep in [
@@ -266,9 +265,9 @@ class EntryPointTests(TestCase):
else: raise AssertionError("Should've been bad", ep)
def checkSubMap(self, m):
- self.assertEqual(len(m), len(self.submap_expect))
+ assert len(m) == len(self.submap_expect)
for key, ep in six.iteritems(self.submap_expect):
- self.assertEqual(repr(m.get(key)), repr(ep))
+ assert repr(m.get(key)) == repr(ep)
submap_expect = dict(
feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
@@ -284,72 +283,71 @@ class EntryPointTests(TestCase):
def testParseList(self):
self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str))
- self.assertRaises(ValueError, EntryPoint.parse_group, "x a", "foo=bar")
- self.assertRaises(ValueError, EntryPoint.parse_group, "x",
- ["foo=baz", "foo=bar"])
+ with pytest.raises(ValueError):
+ EntryPoint.parse_group("x a", "foo=bar")
+ with pytest.raises(ValueError):
+ EntryPoint.parse_group("x", ["foo=baz", "foo=bar"])
def testParseMap(self):
m = EntryPoint.parse_map({'xyz':self.submap_str})
self.checkSubMap(m['xyz'])
- self.assertEqual(list(m.keys()),['xyz'])
+ assert list(m.keys()) == ['xyz']
m = EntryPoint.parse_map("[xyz]\n"+self.submap_str)
self.checkSubMap(m['xyz'])
- self.assertEqual(list(m.keys()),['xyz'])
- self.assertRaises(ValueError, EntryPoint.parse_map, ["[xyz]", "[xyz]"])
- self.assertRaises(ValueError, EntryPoint.parse_map, self.submap_str)
+ assert list(m.keys()) == ['xyz']
+ with pytest.raises(ValueError):
+ EntryPoint.parse_map(["[xyz]", "[xyz]"])
+ with pytest.raises(ValueError):
+ EntryPoint.parse_map(self.submap_str)
-class RequirementsTests(TestCase):
+class TestRequirements:
def testBasics(self):
r = Requirement.parse("Twisted>=1.2")
- self.assertEqual(str(r),"Twisted>=1.2")
- self.assertEqual(repr(r),"Requirement.parse('Twisted>=1.2')")
- self.assertEqual(r, Requirement("Twisted", [('>=','1.2')], ()))
- self.assertEqual(r, Requirement("twisTed", [('>=','1.2')], ()))
- self.assertNotEqual(r, Requirement("Twisted", [('>=','2.0')], ()))
- self.assertNotEqual(r, Requirement("Zope", [('>=','1.2')], ()))
- self.assertNotEqual(r, Requirement("Zope", [('>=','3.0')], ()))
- self.assertNotEqual(r, Requirement.parse("Twisted[extras]>=1.2"))
+ assert str(r) == "Twisted>=1.2"
+ assert repr(r) == "Requirement.parse('Twisted>=1.2')"
+ assert r == Requirement("Twisted", [('>=','1.2')], ())
+ assert r == Requirement("twisTed", [('>=','1.2')], ())
+ assert r != Requirement("Twisted", [('>=','2.0')], ())
+ assert r != Requirement("Zope", [('>=','1.2')], ())
+ assert r != Requirement("Zope", [('>=','3.0')], ())
+ assert r != Requirement.parse("Twisted[extras]>=1.2")
def testOrdering(self):
r1 = Requirement("Twisted", [('==','1.2c1'),('>=','1.2')], ())
r2 = Requirement("Twisted", [('>=','1.2'),('==','1.2c1')], ())
- self.assertEqual(r1,r2)
- self.assertEqual(str(r1),str(r2))
- self.assertEqual(str(r2),"Twisted==1.2c1,>=1.2")
+ assert r1 == r2
+ assert str(r1) == str(r2)
+ assert str(r2) == "Twisted==1.2c1,>=1.2"
def testBasicContains(self):
r = Requirement("Twisted", [('>=','1.2')], ())
foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg")
twist11 = Distribution.from_filename("Twisted-1.1.egg")
twist12 = Distribution.from_filename("Twisted-1.2.egg")
- self.assertTrue(parse_version('1.2') in r)
- self.assertTrue(parse_version('1.1') not in r)
- self.assertTrue('1.2' in r)
- self.assertTrue('1.1' not in r)
- self.assertTrue(foo_dist not in r)
- self.assertTrue(twist11 not in r)
- self.assertTrue(twist12 in r)
-
- def testAdvancedContains(self):
- r, = parse_requirements("Foo>=1.2,<=1.3,==1.9,>2.0,!=2.5,<3.0,==4.5")
- for v in ('1.2','1.2.2','1.3','1.9','2.0.1','2.3','2.6','3.0c1','4.5'):
- self.assertTrue(v in r, (v,r))
- for v in ('1.2c1','1.3.1','1.5','1.9.1','2.0','2.5','3.0','4.0'):
- self.assertTrue(v not in r, (v,r))
+ assert parse_version('1.2') in r
+ assert parse_version('1.1') not in r
+ assert '1.2' in r
+ assert '1.1' not in r
+ assert foo_dist not in r
+ assert twist11 not in r
+ assert twist12 in r
def testOptionsAndHashing(self):
r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
- r3 = Requirement.parse("Twisted[BAR,FOO]>=1.2.0")
- self.assertEqual(r1,r2)
- self.assertEqual(r1,r3)
- self.assertEqual(r1.extras, ("foo","bar"))
- self.assertEqual(r2.extras, ("bar","foo")) # extras are normalized
- self.assertEqual(hash(r1), hash(r2))
- self.assertEqual(
- hash(r1), hash(("twisted", ((">=",parse_version("1.2")),),
- frozenset(["foo","bar"])))
+ assert r1 == r2
+ assert r1.extras == ("foo","bar")
+ assert r2.extras == ("bar","foo") # extras are normalized
+ assert hash(r1) == hash(r2)
+ assert (
+ hash(r1)
+ ==
+ hash((
+ "twisted",
+ packaging.specifiers.SpecifierSet(">=1.2"),
+ frozenset(["foo","bar"]),
+ ))
)
def testVersionEquality(self):
@@ -357,42 +355,42 @@ class RequirementsTests(TestCase):
r2 = Requirement.parse("foo!=0.3a4")
d = Distribution.from_filename
- self.assertTrue(d("foo-0.3a4.egg") not in r1)
- self.assertTrue(d("foo-0.3a1.egg") not in r1)
- self.assertTrue(d("foo-0.3a4.egg") not in r2)
+ assert d("foo-0.3a4.egg") not in r1
+ assert d("foo-0.3a1.egg") not in r1
+ assert d("foo-0.3a4.egg") not in r2
- self.assertTrue(d("foo-0.3a2.egg") in r1)
- self.assertTrue(d("foo-0.3a2.egg") in r2)
- self.assertTrue(d("foo-0.3a3.egg") in r2)
- self.assertTrue(d("foo-0.3a5.egg") in r2)
+ assert d("foo-0.3a2.egg") in r1
+ assert d("foo-0.3a2.egg") in r2
+ assert d("foo-0.3a3.egg") in r2
+ assert d("foo-0.3a5.egg") in r2
def testSetuptoolsProjectName(self):
"""
The setuptools project should implement the setuptools package.
"""
- self.assertEqual(
- Requirement.parse('setuptools').project_name, 'setuptools')
+ assert (
+ Requirement.parse('setuptools').project_name == 'setuptools')
# setuptools 0.7 and higher means setuptools.
- self.assertEqual(
- Requirement.parse('setuptools == 0.7').project_name, 'setuptools')
- self.assertEqual(
- Requirement.parse('setuptools == 0.7a1').project_name, 'setuptools')
- self.assertEqual(
- Requirement.parse('setuptools >= 0.7').project_name, 'setuptools')
+ assert (
+ Requirement.parse('setuptools == 0.7').project_name == 'setuptools')
+ assert (
+ Requirement.parse('setuptools == 0.7a1').project_name == 'setuptools')
+ assert (
+ Requirement.parse('setuptools >= 0.7').project_name == 'setuptools')
-class ParseTests(TestCase):
+class TestParsing:
def testEmptyParse(self):
- self.assertEqual(list(parse_requirements('')), [])
+ assert list(parse_requirements('')) == []
def testYielding(self):
for inp,out in [
([], []), ('x',['x']), ([[]],[]), (' x\n y', ['x','y']),
(['x\n\n','y'], ['x','y']),
]:
- self.assertEqual(list(pkg_resources.yield_lines(inp)),out)
+ assert list(pkg_resources.yield_lines(inp)) == out
def testSplitting(self):
sample = """
@@ -408,64 +406,81 @@ class ParseTests(TestCase):
[q]
v
"""
- self.assertEqual(list(pkg_resources.split_sections(sample)),
- [(None,["x"]), ("Y",["z","a"]), ("b",["c"]), ("d",[]), ("q",["v"])]
+ assert (
+ list(pkg_resources.split_sections(sample))
+ ==
+ [
+ (None, ["x"]),
+ ("Y", ["z", "a"]),
+ ("b", ["c"]),
+ ("d", []),
+ ("q", ["v"]),
+ ]
)
- self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo"))
+ with pytest.raises(ValueError):
+ list(pkg_resources.split_sections("[foo"))
def testSafeName(self):
- self.assertEqual(safe_name("adns-python"), "adns-python")
- self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
- self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
- self.assertEqual(safe_name("Money$$$Maker"), "Money-Maker")
- self.assertNotEqual(safe_name("peak.web"), "peak-web")
+ assert safe_name("adns-python") == "adns-python"
+ assert safe_name("WSGI Utils") == "WSGI-Utils"
+ assert safe_name("WSGI Utils") == "WSGI-Utils"
+ assert safe_name("Money$$$Maker") == "Money-Maker"
+ assert safe_name("peak.web") != "peak-web"
def testSafeVersion(self):
- self.assertEqual(safe_version("1.2-1"), "1.2-1")
- self.assertEqual(safe_version("1.2 alpha"), "1.2.alpha")
- self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521")
- self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker")
- self.assertEqual(safe_version("peak.web"), "peak.web")
+ assert safe_version("1.2-1") == "1.2.post1"
+ assert safe_version("1.2 alpha") == "1.2.alpha"
+ assert safe_version("2.3.4 20050521") == "2.3.4.20050521"
+ assert safe_version("Money$$$Maker") == "Money-Maker"
+ assert safe_version("peak.web") == "peak.web"
def testSimpleRequirements(self):
- self.assertEqual(
- list(parse_requirements('Twis-Ted>=1.2-1')),
+ assert (
+ list(parse_requirements('Twis-Ted>=1.2-1'))
+ ==
[Requirement('Twis-Ted',[('>=','1.2-1')], ())]
)
- self.assertEqual(
- list(parse_requirements('Twisted >=1.2, \ # more\n<2.0')),
+ assert (
+ list(parse_requirements('Twisted >=1.2, \ # more\n<2.0'))
+ ==
[Requirement('Twisted',[('>=','1.2'),('<','2.0')], ())]
)
- self.assertEqual(
- Requirement.parse("FooBar==1.99a3"),
+ assert (
+ Requirement.parse("FooBar==1.99a3")
+ ==
Requirement("FooBar", [('==','1.99a3')], ())
)
- self.assertRaises(ValueError,Requirement.parse,">=2.3")
- self.assertRaises(ValueError,Requirement.parse,"x\\")
- self.assertRaises(ValueError,Requirement.parse,"x==2 q")
- self.assertRaises(ValueError,Requirement.parse,"X==1\nY==2")
- self.assertRaises(ValueError,Requirement.parse,"#")
+ with pytest.raises(ValueError):
+ Requirement.parse(">=2.3")
+ with pytest.raises(ValueError):
+ Requirement.parse("x\\")
+ with pytest.raises(ValueError):
+ Requirement.parse("x==2 q")
+ with pytest.raises(ValueError):
+ Requirement.parse("X==1\nY==2")
+ with pytest.raises(ValueError):
+ Requirement.parse("#")
def testVersionEquality(self):
def c(s1,s2):
p1, p2 = parse_version(s1),parse_version(s2)
- self.assertEqual(p1,p2, (s1,s2,p1,p2))
+ assert p1 == p2, (s1,s2,p1,p2)
c('1.2-rc1', '1.2rc1')
c('0.4', '0.4.0')
c('0.4.0.0', '0.4.0')
c('0.4.0-0', '0.4-0')
- c('0pl1', '0.0pl1')
+ c('0post1', '0.0post1')
c('0pre1', '0.0c1')
c('0.0.0preview1', '0c1')
c('0.0c1', '0-rc1')
c('1.2a1', '1.2.a.1')
- c('1.2...a', '1.2a')
+ c('1.2.a', '1.2a')
def testVersionOrdering(self):
def c(s1,s2):
p1, p2 = parse_version(s1),parse_version(s2)
- self.assertTrue(p1<p2, (s1,s2,p1,p2))
+ assert p1<p2, (s1,s2,p1,p2)
c('2.1','2.1.1')
c('2a1','2b0')
@@ -473,16 +488,14 @@ class ParseTests(TestCase):
c('2.3a1', '2.3')
c('2.1-1', '2.1-2')
c('2.1-1', '2.1.1')
- c('2.1', '2.1pl4')
+ c('2.1', '2.1post4')
c('2.1a0-20040501', '2.1')
c('1.1', '02.1')
- c('A56','B27')
- c('3.2', '3.2.pl0')
- c('3.2-1', '3.2pl1')
- c('3.2pl1', '3.2pl1-1')
+ c('3.2', '3.2.post0')
+ c('3.2post1', '3.2post2')
c('0.4', '4.0')
c('0.0.4', '0.4.0')
- c('0pl1', '0.4pl1')
+ c('0post1', '0.4post1')
c('2.1.0-rc1','2.1.0')
c('2.1dev','2.1a0')
@@ -496,8 +509,59 @@ class ParseTests(TestCase):
for v2 in torture[p+1:]:
c(v2,v1)
+ def testVersionBuildout(self):
+ """
+ Buildout has a function in it's bootstrap.py that inspected the return
+ value of parse_version. The new parse_version returns a Version class
+ which needs to support this behavior, at least for now.
+ """
+ def buildout(parsed_version):
+ _final_parts = '*final-', '*final'
+
+ def _final_version(parsed_version):
+ for part in parsed_version:
+ if (part[:1] == '*') and (part not in _final_parts):
+ return False
+ return True
+ return _final_version(parsed_version)
+
+ assert buildout(parse_version("1.0"))
+ assert not buildout(parse_version("1.0a1"))
+
+ def testVersionIndexable(self):
+ """
+ Some projects were doing things like parse_version("v")[0], so we'll
+ support indexing the same as we support iterating.
+ """
+ assert parse_version("1.0")[0] == "00000001"
-class ScriptHeaderTests(TestCase):
+ def testVersionTupleSort(self):
+ """
+ Some projects expected to be able to sort tuples against the return
+ value of parse_version. So again we'll add a warning enabled shim to
+ make this possible.
+ """
+ assert parse_version("1.0") < tuple(parse_version("2.0"))
+ assert parse_version("1.0") <= tuple(parse_version("2.0"))
+ assert parse_version("1.0") == tuple(parse_version("1.0"))
+ assert parse_version("3.0") > tuple(parse_version("2.0"))
+ assert parse_version("3.0") >= tuple(parse_version("2.0"))
+ assert parse_version("3.0") != tuple(parse_version("2.0"))
+ assert not (parse_version("3.0") != tuple(parse_version("3.0")))
+
+ def testVersionHashable(self):
+ """
+ Ensure that our versions stay hashable even though we've subclassed
+ them and added some shim code to them.
+ """
+ assert (
+ hash(parse_version("1.0"))
+ ==
+ hash(parse_version("1.0"))
+ )
+
+
+class TestScriptHeader:
non_ascii_exe = '/Users/José/bin/python'
exe_with_spaces = r'C:\Program Files\Python33\python.exe'
@@ -505,17 +569,15 @@ class ScriptHeaderTests(TestCase):
if not sys.platform.startswith('java') or not is_sh(sys.executable):
# This test is for non-Jython platforms
expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable))
- self.assertEqual(get_script_header('#!/usr/local/bin/python'),
- expected)
+ assert get_script_header('#!/usr/local/bin/python') == expected
expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable))
- self.assertEqual(get_script_header('#!/usr/bin/python -x'),
- expected)
- self.assertEqual(get_script_header('#!/usr/bin/python',
- executable=self.non_ascii_exe),
- '#!%s -x\n' % self.non_ascii_exe)
+ assert get_script_header('#!/usr/bin/python -x') == expected
+ candidate = get_script_header('#!/usr/bin/python',
+ executable=self.non_ascii_exe)
+ assert candidate == '#!%s -x\n' % self.non_ascii_exe
candidate = get_script_header('#!/usr/bin/python',
executable=self.exe_with_spaces)
- self.assertEqual(candidate, '#!"%s"\n' % self.exe_with_spaces)
+ assert candidate == '#!"%s"\n' % self.exe_with_spaces
def test_get_script_header_jython_workaround(self):
# This test doesn't work with Python 3 in some locales
@@ -536,44 +598,46 @@ class ScriptHeaderTests(TestCase):
try:
# A mock sys.executable that uses a shebang line (this file)
exe = os.path.normpath(os.path.splitext(__file__)[0] + '.py')
- self.assertEqual(
- get_script_header('#!/usr/local/bin/python', executable=exe),
- '#!/usr/bin/env %s\n' % exe)
+ assert (
+ get_script_header('#!/usr/local/bin/python', executable=exe)
+ ==
+ '#!/usr/bin/env %s\n' % exe
+ )
# Ensure we generate what is basically a broken shebang line
# when there's options, with a warning emitted
sys.stdout = sys.stderr = six.StringIO()
- self.assertEqual(get_script_header('#!/usr/bin/python -x',
- executable=exe),
- '#!%s -x\n' % exe)
- self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue())
+ candidate = get_script_header('#!/usr/bin/python -x',
+ executable=exe)
+ assert candidate == '#!%s -x\n' % exe
+ assert 'Unable to adapt shebang line' in sys.stdout.getvalue()
sys.stdout = sys.stderr = six.StringIO()
- self.assertEqual(get_script_header('#!/usr/bin/python',
- executable=self.non_ascii_exe),
- '#!%s -x\n' % self.non_ascii_exe)
- self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue())
+ candidate = get_script_header('#!/usr/bin/python',
+ executable=self.non_ascii_exe)
+ assert candidate == '#!%s -x\n' % self.non_ascii_exe
+ assert 'Unable to adapt shebang line' in sys.stdout.getvalue()
finally:
del sys.modules["java"]
sys.platform = platform
sys.stdout, sys.stderr = stdout, stderr
-class NamespaceTests(TestCase):
+class TestNamespaces:
- def setUp(self):
+ def setup_method(self, method):
self._ns_pkgs = pkg_resources._namespace_packages.copy()
self._tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-")
os.makedirs(os.path.join(self._tmpdir, "site-pkgs"))
self._prev_sys_path = sys.path[:]
sys.path.append(os.path.join(self._tmpdir, "site-pkgs"))
- def tearDown(self):
+ def teardown_method(self, method):
shutil.rmtree(self._tmpdir)
pkg_resources._namespace_packages = self._ns_pkgs.copy()
sys.path = self._prev_sys_path[:]
- msg = "Test fails when /tmp is a symlink. See #231"
- @skipIf(os.path.islink(tempfile.gettempdir()), msg)
+ @pytest.mark.skipif(os.path.islink(tempfile.gettempdir()),
+ reason="Test fails when /tmp is a symlink. See #231")
def test_two_levels_deep(self):
"""
Test nested namespace packages
diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py
index 6a890ebc..6e5ce04a 100644
--- a/setuptools/tests/test_sandbox.py
+++ b/setuptools/tests/test_sandbox.py
@@ -1,67 +1,45 @@
"""develop tests
"""
-import sys
import os
-import shutil
-import unittest
-import tempfile
import types
+import pytest
+
import pkg_resources
import setuptools.sandbox
from setuptools.sandbox import DirectorySandbox, SandboxViolation
-def has_win32com():
- """
- Run this to determine if the local machine has win32com, and if it
- does, include additional tests.
- """
- if not sys.platform.startswith('win32'):
- return False
- try:
- __import__('win32com')
- except ImportError:
- return False
- return True
-
-class TestSandbox(unittest.TestCase):
- def setUp(self):
- self.dir = tempfile.mkdtemp()
+class TestSandbox:
- def tearDown(self):
- shutil.rmtree(self.dir)
-
- def test_devnull(self):
- sandbox = DirectorySandbox(self.dir)
+ def test_devnull(self, tmpdir):
+ sandbox = DirectorySandbox(str(tmpdir))
sandbox.run(self._file_writer(os.devnull))
+ @staticmethod
def _file_writer(path):
def do_write():
- f = open(path, 'w')
- f.write('xxx')
- f.close()
+ with open(path, 'w') as f:
+ f.write('xxx')
return do_write
- _file_writer = staticmethod(_file_writer)
-
- if has_win32com():
- def test_win32com(self):
- """
- win32com should not be prevented from caching COM interfaces
- in gen_py.
- """
- import win32com
- gen_py = win32com.__gen_path__
- target = os.path.join(gen_py, 'test_write')
- sandbox = DirectorySandbox(self.dir)
+ def test_win32com(self, tmpdir):
+ """
+ win32com should not be prevented from caching COM interfaces
+ in gen_py.
+ """
+ win32com = pytest.importorskip('win32com')
+ gen_py = win32com.__gen_path__
+ target = os.path.join(gen_py, 'test_write')
+ sandbox = DirectorySandbox(str(tmpdir))
+ try:
try:
- try:
- sandbox.run(self._file_writer(target))
- except SandboxViolation:
- self.fail("Could not create gen_py file due to SandboxViolation")
- finally:
- if os.path.exists(target): os.remove(target)
+ sandbox.run(self._file_writer(target))
+ except SandboxViolation:
+ self.fail("Could not create gen_py file due to SandboxViolation")
+ finally:
+ if os.path.exists(target):
+ os.remove(target)
def test_setup_py_with_BOM(self):
"""
@@ -73,11 +51,8 @@ class TestSandbox(unittest.TestCase):
setuptools.sandbox._execfile(target, vars(namespace))
assert namespace.result == 'passed'
- def test_setup_py_with_CRLF(self):
- setup_py = os.path.join(self.dir, 'setup.py')
- with open(setup_py, 'wb') as stream:
+ def test_setup_py_with_CRLF(self, tmpdir):
+ setup_py = tmpdir / 'setup.py'
+ with setup_py.open('wb') as stream:
stream.write(b'"degenerate script"\r\n')
- setuptools.sandbox._execfile(setup_py, globals())
-
-if __name__ == '__main__':
- unittest.main()
+ setuptools.sandbox._execfile(str(setup_py), globals())
diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py
index 26b072cc..d30e21ac 100644
--- a/setuptools/tests/test_sdist.py
+++ b/setuptools/tests/test_sdist.py
@@ -6,19 +6,16 @@ import os
import shutil
import sys
import tempfile
-import unittest
import unicodedata
-import re
import contextlib
import six
+import pytest
-from setuptools.tests import environment, test_svn
-from setuptools.tests.py26compat import skipIf
-from setuptools.command.sdist import sdist, walk_revctrl
+import pkg_resources
+from setuptools.command.sdist import sdist
from setuptools.command.egg_info import manifest_maker
from setuptools.dist import Distribution
-from setuptools import svn_utils
SETUP_ATTRS = {
'name': 'sdist_test',
@@ -80,9 +77,9 @@ def decompose(path):
return path
-class TestSdistTest(unittest.TestCase):
+class TestSdistTest:
- def setUp(self):
+ def setup_method(self, method):
self.temp_dir = tempfile.mkdtemp()
f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
f.write(SETUP_PY)
@@ -100,7 +97,7 @@ class TestSdistTest(unittest.TestCase):
self.old_cwd = os.getcwd()
os.chdir(self.temp_dir)
- def tearDown(self):
+ def teardown_method(self, method):
os.chdir(self.old_cwd)
shutil.rmtree(self.temp_dir)
@@ -119,9 +116,9 @@ class TestSdistTest(unittest.TestCase):
cmd.run()
manifest = cmd.filelist.files
- self.assertTrue(os.path.join('sdist_test', 'a.txt') in manifest)
- self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest)
- self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest)
+ assert os.path.join('sdist_test', 'a.txt') in manifest
+ 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):
@@ -146,9 +143,9 @@ class TestSdistTest(unittest.TestCase):
# lowercase all names so we can test in a case-insensitive way to make sure the files are not included
manifest = map(lambda x: x.lower(), cmd.filelist.files)
- self.assertFalse('readme.rst' in manifest, manifest)
- self.assertFalse('setup.py' in manifest, manifest)
- self.assertFalse('setup.cfg' in manifest, manifest)
+ assert 'readme.rst' not in manifest, manifest
+ assert 'setup.py' not in manifest, manifest
+ assert 'setup.cfg' not in manifest, manifest
def test_manifest_is_written_with_utf8_encoding(self):
# Test for #303.
@@ -186,7 +183,7 @@ class TestSdistTest(unittest.TestCase):
fs_enc = sys.getfilesystemencoding()
filename = filename.decode(fs_enc)
- self.assertTrue(posix(filename) in u_contents)
+ assert posix(filename) in u_contents
# Python 3 only
if six.PY3:
@@ -225,10 +222,10 @@ class TestSdistTest(unittest.TestCase):
self.fail(e)
# The manifest should contain the UTF-8 filename
- self.assertTrue(posix(filename) in contents)
+ assert posix(filename) in contents
# The filelist should have been updated as well
- self.assertTrue(u_filename in mm.filelist.files)
+ assert u_filename in mm.filelist.files
def test_write_manifest_skips_non_utf8_filenames(self):
"""
@@ -266,10 +263,10 @@ class TestSdistTest(unittest.TestCase):
self.fail(e)
# The Latin-1 filename should have been skipped
- self.assertFalse(posix(filename) in contents)
+ assert posix(filename) not in contents
# The filelist should have been updated as well
- self.assertFalse(u_filename in mm.filelist.files)
+ assert u_filename not in mm.filelist.files
def test_manifest_is_read_with_utf8_encoding(self):
# Test for #303.
@@ -300,7 +297,7 @@ class TestSdistTest(unittest.TestCase):
# The filelist should contain the UTF-8 filename
if six.PY3:
filename = filename.decode('utf-8')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
# Python 3 only
if six.PY3:
@@ -337,10 +334,11 @@ class TestSdistTest(unittest.TestCase):
# The Latin-1 filename should have been skipped
filename = filename.decode('latin-1')
- self.assertFalse(filename in cmd.filelist.files)
+ assert filename not in cmd.filelist.files
- @skipIf(six.PY3 and locale.getpreferredencoding() != 'UTF-8',
- 'Unittest fails if locale is not utf-8 but the manifests is recorded correctly')
+ @pytest.mark.skipif(six.PY3 and locale.getpreferredencoding() != 'UTF-8',
+ reason='Unittest fails if locale is not utf-8 but the manifests is '
+ 'recorded correctly')
def test_sdist_with_utf8_encoded_filename(self):
# Test for #303.
dist = Distribution(SETUP_ATTRS)
@@ -365,15 +363,15 @@ class TestSdistTest(unittest.TestCase):
if fs_enc == 'cp1252':
# Python 3 mangles the UTF-8 filename
filename = filename.decode('cp1252')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
else:
filename = filename.decode('mbcs')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
else:
filename = filename.decode('utf-8')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
else:
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
def test_sdist_with_latin1_encoded_filename(self):
# Test for #303.
@@ -385,7 +383,7 @@ class TestSdistTest(unittest.TestCase):
# Latin-1 filename
filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
open(filename, 'w').close()
- self.assertTrue(os.path.isfile(filename))
+ assert os.path.isfile(filename)
with quiet():
cmd.run()
@@ -401,11 +399,11 @@ class TestSdistTest(unittest.TestCase):
else:
filename = filename.decode('latin-1')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
else:
# The Latin-1 filename should have been skipped
filename = filename.decode('latin-1')
- self.assertFalse(filename in cmd.filelist.files)
+ filename not in cmd.filelist.files
else:
# Under Python 2 there seems to be no decoded string in the
# filelist. However, due to decode and encoding of the
@@ -415,139 +413,23 @@ class TestSdistTest(unittest.TestCase):
# be proformed for the manifest output.
fs_enc = sys.getfilesystemencoding()
filename.decode(fs_enc)
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
except UnicodeDecodeError:
- self.assertFalse(filename in cmd.filelist.files)
-
-class TestDummyOutput(environment.ZippedEnvironment):
-
- def setUp(self):
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', "dummy.zip")
- self.dataname = "dummy"
- super(TestDummyOutput, self).setUp()
-
- def _run(self):
- code, data = environment.run_setup_py(["sdist"],
- pypath=self.old_cwd,
- data_stream=0)
- if code:
- info = "DIR: " + os.path.abspath('.')
- info += "\n SDIST RETURNED: %i\n\n" % code
- info += data
- raise AssertionError(info)
-
- datalines = data.splitlines()
-
- possible = (
- "running sdist",
- "running egg_info",
- "creating dummy\.egg-info",
- "writing dummy\.egg-info",
- "writing top-level names to dummy\.egg-info",
- "writing dependency_links to dummy\.egg-info",
- "writing manifest file 'dummy\.egg-info",
- "reading manifest file 'dummy\.egg-info",
- "reading manifest template 'MANIFEST\.in'",
- "writing manifest file 'dummy\.egg-info",
- "creating dummy-0.1.1",
- "making hard links in dummy-0\.1\.1",
- "copying files to dummy-0\.1\.1",
- "copying \S+ -> dummy-0\.1\.1",
- "copying dummy",
- "copying dummy\.egg-info",
- "hard linking \S+ -> dummy-0\.1\.1",
- "hard linking dummy",
- "hard linking dummy\.egg-info",
- "Writing dummy-0\.1\.1",
- "creating dist",
- "creating 'dist",
- "Creating tar archive",
- "running check",
- "adding 'dummy-0\.1\.1",
- "tar .+ dist/dummy-0\.1\.1\.tar dummy-0\.1\.1",
- "gzip .+ dist/dummy-0\.1\.1\.tar",
- "removing 'dummy-0\.1\.1' \\(and everything under it\\)",
- )
-
- print(" DIR: " + os.path.abspath('.'))
- for line in datalines:
- found = False
- for pattern in possible:
- if re.match(pattern, line):
- print(" READ: " + line)
- found = True
- break
- if not found:
- raise AssertionError("Unexpexected: %s\n-in-\n%s"
- % (line, data))
-
- return data
-
- def test_sources(self):
- self._run()
-
-
-class TestSvn(environment.ZippedEnvironment):
-
- def setUp(self):
- version = svn_utils.SvnInfo.get_svn_version()
- if not version: # None or Empty
- return
-
- self.base_version = tuple([int(x) for x in version.split('.')][:2])
-
- if not self.base_version:
- raise ValueError('No SVN tools installed')
- elif self.base_version < (1, 3):
- raise ValueError('Insufficient SVN Version %s' % version)
- elif self.base_version >= (1, 9):
- # trying the latest version
- self.base_version = (1, 8)
-
- self.dataname = "svn%i%i_example" % self.base_version
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', self.dataname + ".zip")
- super(TestSvn, self).setUp()
-
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_walksvn(self):
- if self.base_version >= (1, 6):
- folder2 = 'third party2'
- folder3 = 'third party3'
- else:
- folder2 = 'third_party2'
- folder3 = 'third_party3'
-
- # TODO is this right
- expected = set([
- os.path.join('a file'),
- os.path.join(folder2, 'Changes.txt'),
- os.path.join(folder2, 'MD5SUMS'),
- os.path.join(folder2, 'README.txt'),
- os.path.join(folder3, 'Changes.txt'),
- os.path.join(folder3, 'MD5SUMS'),
- os.path.join(folder3, 'README.txt'),
- os.path.join(folder3, 'TODO.txt'),
- os.path.join(folder3, 'fin'),
- os.path.join('third_party', 'README.txt'),
- os.path.join('folder', folder2, 'Changes.txt'),
- os.path.join('folder', folder2, 'MD5SUMS'),
- os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'),
- os.path.join('folder', folder3, 'Changes.txt'),
- os.path.join('folder', folder3, 'fin'),
- os.path.join('folder', folder3, 'MD5SUMS'),
- os.path.join('folder', folder3, 'oops'),
- os.path.join('folder', folder3, 'WatashiNiYomimasu.txt'),
- os.path.join('folder', folder3, 'ZuMachen.txt'),
- os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'),
- os.path.join('folder', 'lalala.txt'),
- os.path.join('folder', 'quest.txt'),
- # The example will have a deleted file
- # (or should) but shouldn't return it
- ])
- self.assertEqual(set(x for x in walk_revctrl()), expected)
-
-
-def test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
+ filename not in cmd.filelist.files
+
+
+def test_default_revctrl():
+ """
+ When _default_revctrl was removed from the `setuptools.command.sdist`
+ module in 10.0, it broke some systems which keep an old install of
+ setuptools (Distribute) around. Those old versions require that the
+ setuptools package continue to implement that interface, so this
+ function provides that interface, stubbed. See #320 for details.
+
+ This interface must be maintained until Ubuntu 12.04 is no longer
+ supported (by Setuptools).
+ """
+ ep_def = 'svn_cvs = setuptools.command.sdist:_default_revctrl'
+ ep = pkg_resources.EntryPoint.parse(ep_def)
+ res = ep._load()
+ assert hasattr(res, '__iter__')
diff --git a/setuptools/tests/test_svn.py b/setuptools/tests/test_svn.py
deleted file mode 100644
index 0e6c3e95..00000000
--- a/setuptools/tests/test_svn.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# -*- coding: utf-8 -*-
-"""svn tests"""
-
-import io
-import os
-import subprocess
-import sys
-import unittest
-
-import six
-
-from setuptools.tests import environment
-from setuptools import svn_utils
-from setuptools.tests.py26compat import skipIf
-
-
-def _do_svn_check():
- try:
- subprocess.check_call(["svn", "--version"],
- shell=(sys.platform == 'win32'))
- return True
- except (OSError, subprocess.CalledProcessError):
- return False
-_svn_check = _do_svn_check()
-
-
-class TestSvnVersion(unittest.TestCase):
-
- def test_no_svn_found(self):
- path_variable = None
- for env in os.environ:
- if env.lower() == 'path':
- path_variable = env
-
- if path_variable is None:
- try:
- self.skipTest('Cannot figure out how to modify path')
- except AttributeError: # PY26 doesn't have this
- return
-
- old_path = os.environ[path_variable]
- os.environ[path_variable] = ''
- try:
- version = svn_utils.SvnInfo.get_svn_version()
- self.assertEqual(version, '')
- finally:
- os.environ[path_variable] = old_path
-
- @skipIf(not _svn_check, "No SVN to text, in the first place")
- def test_svn_should_exist(self):
- version = svn_utils.SvnInfo.get_svn_version()
- self.assertNotEqual(version, '')
-
-def _read_utf8_file(path):
- fileobj = None
- try:
- fileobj = io.open(path, 'r', encoding='utf-8')
- data = fileobj.read()
- return data
- finally:
- if fileobj:
- fileobj.close()
-
-
-class ParserInfoXML(unittest.TestCase):
-
- def parse_tester(self, svn_name, ext_spaces):
- path = os.path.join('setuptools', 'tests',
- 'svn_data', svn_name + '_info.xml')
- #Remember these are pre-generated to test XML parsing
- # so these paths might not valid on your system
- example_base = "%s_example" % svn_name
-
- data = _read_utf8_file(path)
-
- expected = set([
- ("\\".join((example_base, 'a file')), 'file'),
- ("\\".join((example_base, 'folder')), 'dir'),
- ("\\".join((example_base, 'folder', 'lalala.txt')), 'file'),
- ("\\".join((example_base, 'folder', 'quest.txt')), 'file'),
- ])
- self.assertEqual(set(x for x in svn_utils.parse_dir_entries(data)),
- expected)
-
- def test_svn13(self):
- self.parse_tester('svn13', False)
-
- def test_svn14(self):
- self.parse_tester('svn14', False)
-
- def test_svn15(self):
- self.parse_tester('svn15', False)
-
- def test_svn16(self):
- self.parse_tester('svn16', True)
-
- def test_svn17(self):
- self.parse_tester('svn17', True)
-
- def test_svn18(self):
- self.parse_tester('svn18', True)
-
-class ParserExternalXML(unittest.TestCase):
-
- def parse_tester(self, svn_name, ext_spaces):
- path = os.path.join('setuptools', 'tests',
- 'svn_data', svn_name + '_ext_list.xml')
- example_base = svn_name + '_example'
- data = _read_utf8_file(path)
-
- if ext_spaces:
- folder2 = 'third party2'
- folder3 = 'third party3'
- else:
- folder2 = 'third_party2'
- folder3 = 'third_party3'
-
- expected = set([
- os.sep.join((example_base, folder2)),
- os.sep.join((example_base, folder3)),
- # folder is third_party大介
- os.sep.join((example_base,
- six.text_type('third_party') +
- six.unichr(0x5927) + six.unichr(0x4ecb))),
- os.sep.join((example_base, 'folder', folder2)),
- os.sep.join((example_base, 'folder', folder3)),
- os.sep.join((example_base, 'folder',
- six.text_type('third_party') +
- six.unichr(0x5927) + six.unichr(0x4ecb))),
- ])
-
- expected = set(os.path.normpath(x) for x in expected)
- dir_base = os.sep.join(('C:', 'development', 'svn_example'))
- self.assertEqual(set(x for x
- in svn_utils.parse_externals_xml(data, dir_base)), expected)
-
- def test_svn15(self):
- self.parse_tester('svn15', False)
-
- def test_svn16(self):
- self.parse_tester('svn16', True)
-
- def test_svn17(self):
- self.parse_tester('svn17', True)
-
- def test_svn18(self):
- self.parse_tester('svn18', True)
-
-
-class ParseExternal(unittest.TestCase):
-
- def parse_tester(self, svn_name, ext_spaces):
- path = os.path.join('setuptools', 'tests',
- 'svn_data', svn_name + '_ext_list.txt')
- data = _read_utf8_file(path)
-
- if ext_spaces:
- expected = set(['third party2', 'third party3',
- 'third party3b', 'third_party'])
- else:
- expected = set(['third_party2', 'third_party3', 'third_party'])
-
- self.assertEqual(set(x for x in svn_utils.parse_external_prop(data)),
- expected)
-
- def test_svn13(self):
- self.parse_tester('svn13', False)
-
- def test_svn14(self):
- self.parse_tester('svn14', False)
-
- def test_svn15(self):
- self.parse_tester('svn15', False)
-
- def test_svn16(self):
- self.parse_tester('svn16', True)
-
- def test_svn17(self):
- self.parse_tester('svn17', True)
-
- def test_svn18(self):
- self.parse_tester('svn18', True)
-
-
-class TestSvn(environment.ZippedEnvironment):
-
- def setUp(self):
- version = svn_utils.SvnInfo.get_svn_version()
- if not version: # empty or null
- self.dataname = None
- self.datafile = None
- return
-
- self.base_version = tuple([int(x) for x in version.split('.')[:2]])
-
- if self.base_version < (1,3):
- raise ValueError('Insufficient SVN Version %s' % version)
- elif self.base_version >= (1,9):
- #trying the latest version
- self.base_version = (1,8)
-
- self.dataname = "svn%i%i_example" % self.base_version
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', self.dataname + ".zip")
- super(TestSvn, self).setUp()
-
- @skipIf(not _svn_check, "No SVN to text, in the first place")
- def test_revision(self):
- rev = svn_utils.SvnInfo.load('.').get_revision()
- self.assertEqual(rev, 6)
-
- @skipIf(not _svn_check, "No SVN to text, in the first place")
- def test_entries(self):
- expected = set([
- (os.path.join('a file'), 'file'),
- (os.path.join('folder'), 'dir'),
- (os.path.join('folder', 'lalala.txt'), 'file'),
- (os.path.join('folder', 'quest.txt'), 'file'),
- #The example will have a deleted file (or should)
- #but shouldn't return it
- ])
- info = svn_utils.SvnInfo.load('.')
- self.assertEqual(set(x for x in info.entries), expected)
-
- @skipIf(not _svn_check, "No SVN to text, in the first place")
- def test_externals(self):
- if self.base_version >= (1,6):
- folder2 = 'third party2'
- folder3 = 'third party3'
- else:
- folder2 = 'third_party2'
- folder3 = 'third_party3'
-
- expected = set([
- os.path.join(folder2),
- os.path.join(folder3),
- os.path.join('third_party'),
- os.path.join('folder', folder2),
- os.path.join('folder', folder3),
- os.path.join('folder', 'third_party'),
- ])
- info = svn_utils.SvnInfo.load('.')
- self.assertEqual(set([x for x in info.externals]), expected)
-
-def test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py
index 67df14e5..6587dc40 100644
--- a/setuptools/tests/test_test.py
+++ b/setuptools/tests/test_test.py
@@ -1,127 +1,93 @@
# -*- coding: UTF-8 -*-
-"""develop tests
-"""
+from __future__ import unicode_literals
+
import os
-import shutil
import site
-import sys
-import tempfile
-import unittest
from distutils.errors import DistutilsError
import six
+import pytest
from setuptools.command.test import test
-from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
-SETUP_PY = """\
-from setuptools import setup
-
-setup(name='foo',
- packages=['name', 'name.space', 'name.space.tests'],
- namespace_packages=['name'],
- test_suite='name.space.tests.test_suite',
-)
-"""
-
-NS_INIT = """# -*- coding: Latin-1 -*-
-# Söme Arbiträry Ünicode to test Issüé 310
-try:
- __import__('pkg_resources').declare_namespace(__name__)
-except ImportError:
- from pkgutil import extend_path
- __path__ = extend_path(__path__, __name__)
-"""
-# Make sure this is Latin-1 binary, before writing:
-if six.PY2:
- NS_INIT = NS_INIT.decode('UTF-8')
-NS_INIT = NS_INIT.encode('Latin-1')
-
-TEST_PY = """import unittest
-
-class TestTest(unittest.TestCase):
- def test_test(self):
- print "Foo" # Should fail under Python 3 unless 2to3 is used
+from .textwrap import DALS
+from . import contexts
+
+SETUP_PY = DALS("""
+ from setuptools import setup
+
+ setup(name='foo',
+ packages=['name', 'name.space', 'name.space.tests'],
+ namespace_packages=['name'],
+ test_suite='name.space.tests.test_suite',
+ )
+ """)
+
+NS_INIT = DALS("""
+ # -*- coding: Latin-1 -*-
+ # Söme Arbiträry Ünicode to test Distribute Issüé 310
+ try:
+ __import__('pkg_resources').declare_namespace(__name__)
+ except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
+ """)
+
+TEST_PY = DALS("""
+ import unittest
+
+ class TestTest(unittest.TestCase):
+ def test_test(self):
+ print "Foo" # Should fail under Python 3 unless 2to3 is used
-test_suite = unittest.makeSuite(TestTest)
-"""
+ test_suite = unittest.makeSuite(TestTest)
+ """)
-class TestTestTest(unittest.TestCase):
- def setUp(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
- return
+@pytest.fixture
+def sample_test(tmpdir_cwd):
+ os.makedirs('name/space/tests')
- # Directory structure
- self.dir = tempfile.mkdtemp()
- os.mkdir(os.path.join(self.dir, 'name'))
- os.mkdir(os.path.join(self.dir, 'name', 'space'))
- os.mkdir(os.path.join(self.dir, 'name', 'space', 'tests'))
- # setup.py
- setup = os.path.join(self.dir, 'setup.py')
- f = open(setup, 'wt')
+ # setup.py
+ with open('setup.py', 'wt') as f:
f.write(SETUP_PY)
- f.close()
- self.old_cwd = os.getcwd()
- # name/__init__.py
- init = os.path.join(self.dir, 'name', '__init__.py')
- f = open(init, 'wb')
- f.write(NS_INIT)
- f.close()
- # name/space/__init__.py
- init = os.path.join(self.dir, 'name', 'space', '__init__.py')
- f = open(init, 'wt')
+
+ # name/__init__.py
+ with open('name/__init__.py', 'wb') as f:
+ f.write(NS_INIT.encode('Latin-1'))
+
+ # name/space/__init__.py
+ with open('name/space/__init__.py', 'wt') as f:
f.write('#empty\n')
- f.close()
- # name/space/tests/__init__.py
- init = os.path.join(self.dir, 'name', 'space', 'tests', '__init__.py')
- f = open(init, 'wt')
- f.write(TEST_PY)
- f.close()
- os.chdir(self.dir)
- self.old_base = site.USER_BASE
- site.USER_BASE = tempfile.mkdtemp()
- self.old_site = site.USER_SITE
- site.USER_SITE = tempfile.mkdtemp()
+ # name/space/tests/__init__.py
+ with open('name/space/tests/__init__.py', 'wt') as f:
+ f.write(TEST_PY)
- def tearDown(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
- return
- 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
+@pytest.mark.skipif('hasattr(sys, "real_prefix")')
+@pytest.mark.usefixtures('user_override')
+@pytest.mark.usefixtures('sample_test')
+class TestTestTest:
def test_test(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
- return
-
- dist = Distribution(dict(
+ params = dict(
name='foo',
packages=['name', 'name.space', 'name.space.tests'],
namespace_packages=['name'],
test_suite='name.space.tests.test_suite',
use_2to3=True,
- ))
+ )
+ dist = Distribution(params)
dist.script_name = 'setup.py'
cmd = test(dist)
cmd.user = 1
cmd.ensure_finalized()
cmd.install_dir = site.USER_SITE
cmd.user = 1
- old_stdout = sys.stdout
- sys.stdout = six.StringIO()
- try:
- try: # try/except/finally doesn't work in Python 2.4, so we need nested try-statements.
+ with contexts.quiet():
+ # The test runner calls sys.exit
+ with contexts.suppress_exceptions(SystemExit):
cmd.run()
- except SystemExit: # The test runner calls sys.exit, stop that making an error.
- pass
- finally:
- sys.stdout = old_stdout
-
diff --git a/setuptools/tests/test_upload_docs.py b/setuptools/tests/test_upload_docs.py
index 769f16cc..cc71cadb 100644
--- a/setuptools/tests/test_upload_docs.py
+++ b/setuptools/tests/test_upload_docs.py
@@ -1,72 +1,59 @@
-"""build_ext tests
-"""
-import sys, os, shutil, tempfile, unittest, site, zipfile
+import os
+import zipfile
+import contextlib
+
+import pytest
+
from setuptools.command.upload_docs import upload_docs
from setuptools.dist import Distribution
-SETUP_PY = """\
-from setuptools import setup
+from .textwrap import DALS
+from . import contexts
+
-setup(name='foo')
-"""
+SETUP_PY = DALS(
+ """
+ from setuptools import setup
-class TestUploadDocsTest(unittest.TestCase):
- def setUp(self):
- self.dir = tempfile.mkdtemp()
- setup = os.path.join(self.dir, 'setup.py')
- f = open(setup, 'w')
+ setup(name='foo')
+ """)
+
+
+@pytest.fixture
+def sample_project(tmpdir_cwd):
+ # setup.py
+ with open('setup.py', 'wt') as f:
f.write(SETUP_PY)
- f.close()
- self.old_cwd = os.getcwd()
- os.chdir(self.dir)
- self.upload_dir = os.path.join(self.dir, 'build')
- os.mkdir(self.upload_dir)
+ os.mkdir('build')
- # A test document.
- f = open(os.path.join(self.upload_dir, 'index.html'), 'w')
+ # A test document.
+ with open('build/index.html', 'w') as f:
f.write("Hello world.")
- f.close()
-
- # An empty folder.
- os.mkdir(os.path.join(self.upload_dir, 'empty'))
-
- if sys.version >= "2.6":
- self.old_base = site.USER_BASE
- site.USER_BASE = upload_docs.USER_BASE = tempfile.mkdtemp()
- self.old_site = site.USER_SITE
- site.USER_SITE = upload_docs.USER_SITE = tempfile.mkdtemp()
-
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.dir)
- if sys.version >= "2.6":
- shutil.rmtree(site.USER_BASE)
- shutil.rmtree(site.USER_SITE)
- site.USER_BASE = self.old_base
- site.USER_SITE = self.old_site
+
+ # An empty folder.
+ os.mkdir('build/empty')
+
+
+@pytest.mark.usefixtures('sample_project')
+@pytest.mark.usefixtures('user_override')
+class TestUploadDocsTest:
def test_create_zipfile(self):
- # Test to make sure zipfile creation handles common cases.
- # This explicitly includes a folder containing an empty folder.
+ """
+ Ensure zipfile creation handles common cases, including a folder
+ containing an empty folder.
+ """
dist = Distribution()
cmd = upload_docs(dist)
- cmd.upload_dir = self.upload_dir
- cmd.target_dir = self.upload_dir
- tmp_dir = tempfile.mkdtemp()
- tmp_file = os.path.join(tmp_dir, 'foo.zip')
- try:
+ cmd.target_dir = cmd.upload_dir = 'build'
+ with contexts.tempdir() as tmp_dir:
+ tmp_file = os.path.join(tmp_dir, 'foo.zip')
zip_file = cmd.create_zipfile(tmp_file)
assert zipfile.is_zipfile(tmp_file)
- zip_file = zipfile.ZipFile(tmp_file) # woh...
-
- assert zip_file.namelist() == ['index.html']
-
- zip_file.close()
- finally:
- shutil.rmtree(tmp_dir)
-
+ with contextlib.closing(zipfile.ZipFile(tmp_file)) as zip_file:
+ assert zip_file.namelist() == ['index.html']
diff --git a/setuptools/tests/test_windows_wrappers.py b/setuptools/tests/test_windows_wrappers.py
new file mode 100644
index 00000000..5b14d07b
--- /dev/null
+++ b/setuptools/tests/test_windows_wrappers.py
@@ -0,0 +1,183 @@
+"""
+Python Script Wrapper for Windows
+=================================
+
+setuptools includes wrappers for Python scripts that allows them to be
+executed like regular windows programs. There are 2 wrappers, one
+for command-line programs, cli.exe, and one for graphical programs,
+gui.exe. These programs are almost identical, function pretty much
+the same way, and are generated from the same source file. The
+wrapper programs are used by copying them to the directory containing
+the script they are to wrap and with the same name as the script they
+are to wrap.
+"""
+
+from __future__ import absolute_import
+
+import sys
+import textwrap
+import subprocess
+
+import pytest
+
+from setuptools.command.easy_install import nt_quote_arg
+import pkg_resources
+
+
+pytestmark = pytest.mark.skipif(sys.platform != 'win32', reason="Windows only")
+
+
+class WrapperTester:
+
+ @classmethod
+ def prep_script(cls, template):
+ python_exe = nt_quote_arg(sys.executable)
+ return template % locals()
+
+ @classmethod
+ def create_script(cls, tmpdir):
+ """
+ Create a simple script, foo-script.py
+
+ Note that the script starts with a Unix-style '#!' line saying which
+ Python executable to run. The wrapper will use this line to find the
+ correct Python executable.
+ """
+
+ script = cls.prep_script(cls.script_tmpl)
+
+ with (tmpdir / cls.script_name).open('w') as f:
+ f.write(script)
+
+ # also copy cli.exe to the sample directory
+ with (tmpdir / cls.wrapper_name).open('wb') as f:
+ w = pkg_resources.resource_string('setuptools', cls.wrapper_source)
+ f.write(w)
+
+
+class TestCLI(WrapperTester):
+ script_name = 'foo-script.py'
+ wrapper_source = 'cli-32.exe'
+ wrapper_name = 'foo.exe'
+ script_tmpl = textwrap.dedent("""
+ #!%(python_exe)s
+ import sys
+ input = repr(sys.stdin.read())
+ print(sys.argv[0][-14:])
+ print(sys.argv[1:])
+ print(input)
+ if __debug__:
+ print('non-optimized')
+ """).lstrip()
+
+ def test_basic(self, tmpdir):
+ """
+ When the copy of cli.exe, foo.exe in this example, runs, it examines
+ the path name it was run with and computes a Python script path name
+ by removing the '.exe' suffix and adding the '-script.py' suffix. (For
+ GUI programs, the suffix '-script.pyw' is added.) This is why we
+ named out script the way we did. Now we can run out script by running
+ the wrapper:
+
+ This example was a little pathological in that it exercised windows
+ (MS C runtime) quoting rules:
+
+ - Strings containing spaces are surrounded by double quotes.
+
+ - Double quotes in strings need to be escaped by preceding them with
+ back slashes.
+
+ - One or more backslashes preceding double quotes need to be escaped
+ by preceding each of them with back slashes.
+ """
+ self.create_script(tmpdir)
+ cmd = [
+ str(tmpdir / 'foo.exe'),
+ 'arg1',
+ 'arg 2',
+ 'arg "2\\"',
+ 'arg 4\\',
+ 'arg5 a\\\\b',
+ ]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ stdout, stderr = proc.communicate('hello\nworld\n'.encode('ascii'))
+ actual = stdout.decode('ascii').replace('\r\n', '\n')
+ expected = textwrap.dedent(r"""
+ \foo-script.py
+ ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b']
+ 'hello\nworld\n'
+ non-optimized
+ """).lstrip()
+ assert actual == expected
+
+ def test_with_options(self, tmpdir):
+ """
+ Specifying Python Command-line Options
+ --------------------------------------
+
+ You can specify a single argument on the '#!' line. This can be used
+ to specify Python options like -O, to run in optimized mode or -i
+ to start the interactive interpreter. You can combine multiple
+ options as usual. For example, to run in optimized mode and
+ enter the interpreter after running the script, you could use -Oi:
+ """
+ self.create_script(tmpdir)
+ tmpl = textwrap.dedent("""
+ #!%(python_exe)s -Oi
+ import sys
+ input = repr(sys.stdin.read())
+ print(sys.argv[0][-14:])
+ print(sys.argv[1:])
+ print(input)
+ if __debug__:
+ print('non-optimized')
+ sys.ps1 = '---'
+ """).lstrip()
+ with (tmpdir / 'foo-script.py').open('w') as f:
+ f.write(self.prep_script(tmpl))
+ cmd = [str(tmpdir / 'foo.exe')]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdout, stderr = proc.communicate()
+ actual = stdout.decode('ascii').replace('\r\n', '\n')
+ expected = textwrap.dedent(r"""
+ \foo-script.py
+ []
+ ''
+ ---
+ """).lstrip()
+ assert actual == expected
+
+
+class TestGUI(WrapperTester):
+ """
+ Testing the GUI Version
+ -----------------------
+ """
+ script_name = 'bar-script.pyw'
+ wrapper_source = 'gui-32.exe'
+ wrapper_name = 'bar.exe'
+
+ script_tmpl = textwrap.dedent("""
+ #!%(python_exe)s
+ import sys
+ f = open(sys.argv[1], 'wb')
+ bytes_written = f.write(repr(sys.argv[2]).encode('utf-8'))
+ f.close()
+ """).strip()
+
+ def test_basic(self, tmpdir):
+ """Test the GUI version with the simple scipt, bar-script.py"""
+ self.create_script(tmpdir)
+
+ cmd = [
+ str(tmpdir / 'bar.exe'),
+ str(tmpdir / 'test_output.txt'),
+ 'Test Argument',
+ ]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdout, stderr = proc.communicate()
+ assert not stdout
+ assert not stderr
+ with (tmpdir / 'test_output.txt').open('rb') as f_out:
+ actual = f_out.read().decode('ascii')
+ assert actual == repr('Test Argument')
diff --git a/setuptools/tests/textwrap.py b/setuptools/tests/textwrap.py
new file mode 100644
index 00000000..5cd9e5bc
--- /dev/null
+++ b/setuptools/tests/textwrap.py
@@ -0,0 +1,8 @@
+from __future__ import absolute_import
+
+import textwrap
+
+
+def DALS(s):
+ "dedent and left-strip"
+ return textwrap.dedent(s).lstrip()
diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt
deleted file mode 100644
index b3a52e0a..00000000
--- a/setuptools/tests/win_script_wrapper.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Python Script Wrapper for Windows
-=================================
-
-setuptools includes wrappers for Python scripts that allows them to be
-executed like regular windows programs. There are 2 wrappers, once
-for command-line programs, cli.exe, and one for graphical programs,
-gui.exe. These programs are almost identical, function pretty much
-the same way, and are generated from the same source file. The
-wrapper programs are used by copying them to the directory containing
-the script they are to wrap and with the same name as the script they
-are to wrap. In the rest of this document, we'll give an example that
-will illustrate this.
-
-Let's create a simple script, foo-script.py:
-
- >>> import os, sys, tempfile
- >>> from setuptools.command.easy_install import nt_quote_arg
- >>> sample_directory = tempfile.mkdtemp()
- >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w')
- >>> bytes_written = f.write(
- ... """#!%(python_exe)s
- ... import sys
- ... input = repr(sys.stdin.read())
- ... print(sys.argv[0][-14:])
- ... print(sys.argv[1:])
- ... print(input)
- ... if __debug__:
- ... print('non-optimized')
- ... """ % dict(python_exe=nt_quote_arg(sys.executable)))
- >>> f.close()
-
-Note that the script starts with a Unix-style '#!' line saying which
-Python executable to run. The wrapper will use this to find the
-correct Python executable.
-
-We'll also copy cli.exe to the sample-directory with the name foo.exe:
-
- >>> import pkg_resources
- >>> f = open(os.path.join(sample_directory, 'foo.exe'), 'wb')
- >>> bytes_written = f.write(
- ... pkg_resources.resource_string('setuptools', 'cli-32.exe')
- ... )
- >>> f.close()
-
-When the copy of cli.exe, foo.exe in this example, runs, it examines
-the path name it was run with and computes a Python script path name
-by removing the '.exe' suffix and adding the '-script.py' suffix. (For
-GUI programs, the suffix '-script-pyw' is added.) This is why we
-named out script the way we did. Now we can run out script by running
-the wrapper:
-
- >>> import subprocess
- >>> cmd = [os.path.join(sample_directory, 'foo.exe'), 'arg1', 'arg 2',
- ... 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b']
- >>> proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
- >>> stdout, stderr = proc.communicate('hello\nworld\n'.encode('ascii'))
- >>> bytes = sys.stdout.write(stdout.decode('ascii').replace('\r\n', '\n'))
- \foo-script.py
- ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b']
- 'hello\nworld\n'
- non-optimized
-
-This example was a little pathological in that it exercised windows
-(MS C runtime) quoting rules:
-
-- Strings containing spaces are surrounded by double quotes.
-
-- Double quotes in strings need to be escaped by preceding them with
- back slashes.
-
-- One or more backslashes preceding double quotes need to be escaped
- by preceding each of them with back slashes.
-
-
-Specifying Python Command-line Options
---------------------------------------
-
-You can specify a single argument on the '#!' line. This can be used
-to specify Python options like -O, to run in optimized mode or -i
-to start the interactive interpreter. You can combine multiple
-options as usual. For example, to run in optimized mode and
-enter the interpreter after running the script, you could use -Oi:
-
- >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w')
- >>> bytes_written = f.write(
- ... """#!%(python_exe)s -Oi
- ... import sys
- ... input = repr(sys.stdin.read())
- ... print(sys.argv[0][-14:])
- ... print(sys.argv[1:])
- ... print(input)
- ... if __debug__:
- ... print('non-optimized')
- ... sys.ps1 = '---'
- ... """ % dict(python_exe=nt_quote_arg(sys.executable)))
- >>> f.close()
- >>> cmd = [os.path.join(sample_directory, 'foo.exe')]
- >>> proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
- >>> stdout, stderr = proc.communicate()
- >>> bytes = sys.stdout.write(stdout.decode('ascii').replace('\r\n', '\n'))
- \foo-script.py
- []
- ''
- ---
-
-Testing the GUI Version
------------------------
-
-Now let's test the GUI version with the simple scipt, bar-script.py:
-
- >>> import os, sys, tempfile
- >>> from setuptools.command.easy_install import nt_quote_arg
- >>> sample_directory = tempfile.mkdtemp()
- >>> f = open(os.path.join(sample_directory, 'bar-script.pyw'), 'w')
- >>> bytes_written = f.write(
- ... """#!%(python_exe)s
- ... import sys
- ... f = open(sys.argv[1], 'wb')
- ... bytes_written = f.write(repr(sys.argv[2]).encode('utf-8'))
- ... f.close()
- ... """ % dict(python_exe=nt_quote_arg(sys.executable)))
- >>> f.close()
-
-We'll also copy gui.exe to the sample-directory with the name bar.exe:
-
- >>> import pkg_resources
- >>> f = open(os.path.join(sample_directory, 'bar.exe'), 'wb')
- >>> bytes_written = f.write(
- ... pkg_resources.resource_string('setuptools', 'gui-32.exe')
- ... )
- >>> f.close()
-
-Finally, we'll run the script and check the result:
-
- >>> cmd = [
- ... os.path.join(sample_directory, 'bar.exe'),
- ... os.path.join(sample_directory, 'test_output.txt'),
- ... 'Test Argument',
- ... ]
- >>> proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
- >>> stdout, stderr = proc.communicate()
- >>> print(stdout.decode('ascii'))
- <BLANKLINE>
- >>> f_out = open(os.path.join(sample_directory, 'test_output.txt'), 'rb')
- >>> print(f_out.read().decode('ascii'))
- 'Test Argument'
- >>> f_out.close()
-
-
-We're done with the sample_directory:
-
- >>> import shutil
- >>> shutil.rmtree(sample_directory)
-
diff --git a/setuptools/version.py b/setuptools/version.py
index 0ab618ea..addf63a6 100644
--- a/setuptools/version.py
+++ b/setuptools/version.py
@@ -1 +1 @@
-__version__ = '7.1'
+__version__ = '10.2.2'