summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgtags4
-rw-r--r--.travis.yml7
-rw-r--r--CHANGES.txt28
-rw-r--r--MANIFEST.in7
-rw-r--r--bootstrap.py12
-rw-r--r--conftest.py1
-rw-r--r--ez_setup.py2
-rw-r--r--linkify.py2
-rw-r--r--pkg_resources/__init__.py67
-rw-r--r--pkg_resources/_vendor/packaging/__about__.py2
-rw-r--r--pkg_resources/_vendor/packaging/specifiers.py58
-rw-r--r--pkg_resources/_vendor/packaging/version.py25
-rw-r--r--pkg_resources/_vendor/vendored.txt2
-rw-r--r--pkg_resources/api_tests.txt3
-rw-r--r--pkg_resources/tests/__init__.py0
-rw-r--r--pkg_resources/tests/test_pkg_resources.py (renamed from tests/test_pkg_resources.py)0
-rw-r--r--pkg_resources/tests/test_resources.py (renamed from setuptools/tests/test_resources.py)489
-rwxr-xr-xsetuptools/archive_util.py40
-rwxr-xr-xsetuptools/command/easy_install.py17
-rwxr-xr-xsetuptools/command/sdist.py3
-rw-r--r--setuptools/command/upload_docs.py3
-rw-r--r--setuptools/dist.py3
-rw-r--r--setuptools/msvc9_support.py3
-rwxr-xr-xsetuptools/package_index.py15
-rwxr-xr-xsetuptools/sandbox.py3
-rw-r--r--setuptools/tests/__init__.py283
-rw-r--r--setuptools/tests/contexts.py93
-rw-r--r--setuptools/tests/fixtures.py24
-rw-r--r--setuptools/tests/py26compat.py20
-rw-r--r--setuptools/tests/server.py27
-rw-r--r--setuptools/tests/test_bdist_egg.py57
-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.py231
-rw-r--r--setuptools/tests/test_egg_info.py145
-rw-r--r--setuptools/tests/test_find_packages.py24
-rw-r--r--setuptools/tests/test_integration.py14
-rw-r--r--setuptools/tests/test_markerlib.py79
-rw-r--r--setuptools/tests/test_msvc9compiler.py286
-rw-r--r--setuptools/tests/test_packageindex.py102
-rw-r--r--setuptools/tests/test_sandbox.py81
-rw-r--r--setuptools/tests/test_sdist.py87
-rw-r--r--setuptools/tests/test_test.py155
-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
-rwxr-xr-xtests/shlib_test/hello.c168
-rwxr-xr-xtests/shlib_test/hello.pyx4
-rwxr-xr-xtests/shlib_test/hellolib.c3
-rwxr-xr-xtests/shlib_test/setup.py10
-rwxr-xr-xtests/shlib_test/test_hello.py7
54 files changed, 1593 insertions, 1692 deletions
diff --git a/.hgtags b/.hgtags
index a4071fd7..021c8ff4 100644
--- a/.hgtags
+++ b/.hgtags
@@ -179,3 +179,7 @@ fa069bf2411a150c9379d31a04d1c3836e2d3027 9.0.1
0c4d18a747a6d39bff8e194a58af949a960d674a 10.0
4c41e2cdd70beb0da556d71f46a67734c14f2bc2 10.0.1
26b00011ec65b8f7b4f3d51078ec0a694701a45c 10.1
+651d41db58849d4fc50e466f4dc458d448480c4e 10.2
+1f5de53c079d577ead9d80265c9e006503b16457 10.2.1
+b4b92805bc0e9802da0b597d00df4fa42b30bc40 11.0
+6cd2b18f4be2a9c188fa505b34505b32f4a4554b 11.1
diff --git a/.travis.yml b/.travis.yml
index 5f644e00..0e648b38 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,9 +8,8 @@ python:
- pypy
# command to run tests
script:
- # invoke bootstrap and override egg_info based on setup.py in checkout
+ # update egg_info based on setup.py in checkout
- python bootstrap.py
- - python setup.py egg_info
- - python setup.py ptr
- - python ez_setup.py --version 7.0
+ - python setup.py ptr --addopts='-rs'
+ - python ez_setup.py --version 10.2.1
diff --git a/CHANGES.txt b/CHANGES.txt
index efbb43f8..8fc9e981 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,10 +3,36 @@ CHANGES
=======
----
-next
+11.1
+----
+
+* Issue #281: Since Setuptools 6.1 (Issue #268), a ValueError would be raised
+ in certain cases where VersionConflict was raised with two arguments, which
+ occurred in ``pkg_resources.WorkingSet.find``. This release adds support
+ for indicating the dependent packages while maintaining support for
+ a VersionConflict when no dependent package context is known. New unit tests
+ now capture the expected interface.
+
+----
+11.0
+----
+
+* Interop #3: Upgrade to Packaging 15.0; updates to PEP 440 so that >1.7 does
+ not exclude 1.7.1 but does exclude 1.7.0 and 1.7.0.post1.
+
+------
+10.2.1
+------
+
+* Issue #323: Fix regression in entry point name parsing.
+
+----
+10.2
----
* Deprecated use of EntryPoint.load(require=False).
+* Substantial refactoring of all unit tests. Tests are now much leaner and
+ re-use a lot of fixtures and contexts for better clarity of purpose.
----
10.1
diff --git a/MANIFEST.in b/MANIFEST.in
index f6caf61a..ed60948b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,7 +1,6 @@
-recursive-include setuptools *.py *.txt *.exe *.xml
-recursive-include tests *.py *.c *.pyx *.txt
-recursive-include setuptools/tests *.html entries*
-recursive-include setuptools/tests/svn_data *.zip
+recursive-include setuptools *.py *.exe *.xml
+recursive-include tests *.py *.c *.pyx
+recursive-include setuptools/tests *.html
recursive-include docs *.py *.txt *.conf *.css *.css_t Makefile indexsidebar.html
recursive-include _markerlib *.py
recursive-include pkg_resources *.py *.txt
diff --git a/bootstrap.py b/bootstrap.py
index cbc1ca9d..70f96258 100644
--- a/bootstrap.py
+++ b/bootstrap.py
@@ -28,8 +28,10 @@ minimal_egg_info = textwrap.dedent("""
""")
def ensure_egg_info():
- if not os.path.exists('setuptools.egg-info'):
- build_egg_info()
+ if os.path.exists('setuptools.egg-info'):
+ return
+ print("adding minimal entry_points")
+ build_egg_info()
def build_egg_info():
@@ -43,7 +45,11 @@ def build_egg_info():
def run_egg_info():
- subprocess.check_call([sys.executable, 'setup.py', 'egg_info'])
+ cmd = [sys.executable, 'setup.py', 'egg_info']
+ print("Regenerating egg_info")
+ subprocess.check_call(cmd)
+ print("...and again.")
+ subprocess.check_call(cmd)
if __name__ == '__main__':
diff --git a/conftest.py b/conftest.py
new file mode 100644
index 00000000..a513bb9e
--- /dev/null
+++ b/conftest.py
@@ -0,0 +1 @@
+pytest_plugins = 'setuptools.tests.fixtures'
diff --git a/ez_setup.py b/ez_setup.py
index 62ead23a..388ff490 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -36,7 +36,7 @@ try:
except ImportError:
USER_SITE = None
-DEFAULT_VERSION = "10.2"
+DEFAULT_VERSION = "11.2"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
diff --git a/linkify.py b/linkify.py
index 1d925aba..e7b3ca7b 100644
--- a/linkify.py
+++ b/linkify.py
@@ -14,6 +14,7 @@ link_patterns = [
r"Old Setuptools #(?P<old_setuptools>\d+)",
r"Jython #(?P<jython>\d+)",
r"Python #(?P<python>\d+)",
+ r"Interop #(?P<interop>\d+)",
]
issue_urls = dict(
@@ -25,6 +26,7 @@ issue_urls = dict(
old_setuptools='http://bugs.python.org/setuptools/issue{old_setuptools}',
jython='http://bugs.jython.org/issue{jython}',
python='http://bugs.python.org/issue{python}',
+ interop='https://github.com/pypa/interoperability-peps/issues/{interop}',
)
diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py
index 0e6223de..b31ae532 100644
--- a/pkg_resources/__init__.py
+++ b/pkg_resources/__init__.py
@@ -52,6 +52,8 @@ if PY3:
else:
string_types = str, eval('unicode')
+iteritems = (lambda i: i.items()) if PY3 else lambda i: i.iteritems()
+
# capture these to bypass sandboxing
from os import utime
try:
@@ -315,8 +317,51 @@ class ResolutionError(Exception):
def __repr__(self):
return self.__class__.__name__+repr(self.args)
+
class VersionConflict(ResolutionError):
- """An already-installed version conflicts with the requested version"""
+ """
+ An already-installed version conflicts with the requested version.
+
+ Should be initialized with the installed Distribution and the requested
+ Requirement.
+ """
+
+ _template = "{self.dist} is installed but {self.req} is required"
+
+ @property
+ def dist(self):
+ return self.args[0]
+
+ @property
+ def req(self):
+ return self.args[1]
+
+ def report(self):
+ return self._template.format(**locals())
+
+ def with_context(self, required_by):
+ """
+ If required_by is non-empty, return a version of self that is a
+ ContextualVersionConflict.
+ """
+ if not required_by:
+ return self
+ args = self.args + (required_by,)
+ return ContextualVersionConflict(*args)
+
+
+class ContextualVersionConflict(VersionConflict):
+ """
+ A VersionConflict that accepts a third parameter, the set of the
+ requirements that required the installed Distribution.
+ """
+
+ _template = VersionConflict._template + ' by {self.required_by}'
+
+ @property
+ def required_by(self):
+ return self.args[2]
+
class DistributionNotFound(ResolutionError):
"""A requested distribution was not found"""
@@ -625,8 +670,7 @@ class WorkingSet(object):
if dist is not None and dist not in req:
# XXX add more info
raise VersionConflict(dist, req)
- else:
- return dist
+ return dist
def iter_entry_points(self, group, name=None):
"""Yield entry point objects from `group` matching `name`
@@ -762,9 +806,8 @@ class WorkingSet(object):
to_activate.append(dist)
if dist not in req:
# Oops, the "best" so far conflicts with a dependency
- tmpl = "%s is installed but %s is required by %s"
- args = dist, req, list(required_by.get(req, []))
- raise VersionConflict(tmpl % args)
+ dependent_req = required_by[req]
+ raise VersionConflict(dist, req).with_context(dependent_req)
# push the new requirements onto the stack
new_requirements = dist.requires(req.extras)[::-1]
@@ -841,8 +884,7 @@ class WorkingSet(object):
try:
resolvees = shadow_set.resolve(req, env, installer)
- except ResolutionError:
- v = sys.exc_info()[1]
+ except ResolutionError as v:
# save error info
error_info[dist] = v
if fallback:
@@ -1338,8 +1380,8 @@ class MarkerEvaluation(object):
"""
try:
cls.evaluate_marker(text)
- except SyntaxError:
- return cls.normalize_exception(sys.exc_info()[1])
+ except SyntaxError as e:
+ return cls.normalize_exception(e)
return False
@staticmethod
@@ -1454,8 +1496,7 @@ class MarkerEvaluation(object):
env[new_key] = env.pop(key)
try:
result = _markerlib.interpret(text, env)
- except NameError:
- e = sys.exc_info()[1]
+ except NameError as e:
raise SyntaxError(e.args[0])
return result
@@ -2281,7 +2322,7 @@ class EntryPoint(object):
pattern = re.compile(
r'\s*'
- r'(?P<name>[\w. -]+?)\s*'
+ r'(?P<name>[+\w. -]+?)\s*'
r'=\s*'
r'(?P<module>[\w.]+)\s*'
r'(:\s*(?P<attr>[\w.]+))?\s*'
diff --git a/pkg_resources/_vendor/packaging/__about__.py b/pkg_resources/_vendor/packaging/__about__.py
index d3e50f1e..36f1a35c 100644
--- a/pkg_resources/_vendor/packaging/__about__.py
+++ b/pkg_resources/_vendor/packaging/__about__.py
@@ -22,7 +22,7 @@ __title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
-__version__ = "14.5"
+__version__ = "15.0"
__author__ = "Donald Stufft"
__email__ = "donald@stufft.io"
diff --git a/pkg_resources/_vendor/packaging/specifiers.py b/pkg_resources/_vendor/packaging/specifiers.py
index 80225786..9ad0a635 100644
--- a/pkg_resources/_vendor/packaging/specifiers.py
+++ b/pkg_resources/_vendor/packaging/specifiers.py
@@ -458,21 +458,59 @@ class Specifier(_IndividualSpecifier):
@_require_version_compare
def _compare_less_than(self, prospective, spec):
- # Less than are defined as exclusive operators, this implies that
- # pre-releases do not match for the same series as the spec. This is
- # implemented by making <V imply !=V.*.
+ # Convert our spec to a Version instance, since we'll want to work with
+ # it as a version.
spec = Version(spec)
- return (prospective < spec
- and self._get_operator("!=")(prospective, str(spec) + ".*"))
+
+ # Check to see if the prospective version is less than the spec
+ # version. If it's not we can short circuit and just return False now
+ # instead of doing extra unneeded work.
+ if not prospective < spec:
+ return False
+
+ # This special case is here so that, unless the specifier itself
+ # includes is a pre-release version, that we do not accept pre-release
+ # versions for the version mentioned in the specifier (e.g. <3.1 should
+ # not match 3.1.dev0, but should match 3.0.dev0).
+ if not spec.is_prerelease and prospective.is_prerelease:
+ if Version(prospective.base_version) == Version(spec.base_version):
+ return False
+
+ # If we've gotten to here, it means that prospective version is both
+ # less than the spec version *and* it's not a pre-release of the same
+ # version in the spec.
+ return True
@_require_version_compare
def _compare_greater_than(self, prospective, spec):
- # Greater than are defined as exclusive operators, this implies that
- # pre-releases do not match for the same series as the spec. This is
- # implemented by making >V imply !=V.*.
+ # Convert our spec to a Version instance, since we'll want to work with
+ # it as a version.
spec = Version(spec)
- return (prospective > spec
- and self._get_operator("!=")(prospective, str(spec) + ".*"))
+
+ # Check to see if the prospective version is greater than the spec
+ # version. If it's not we can short circuit and just return False now
+ # instead of doing extra unneeded work.
+ if not prospective > spec:
+ return False
+
+ # This special case is here so that, unless the specifier itself
+ # includes is a post-release version, that we do not accept
+ # post-release versions for the version mentioned in the specifier
+ # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
+ if not spec.is_postrelease and prospective.is_postrelease:
+ if Version(prospective.base_version) == Version(spec.base_version):
+ return False
+
+ # Ensure that we do not allow a local version of the version mentioned
+ # in the specifier, which is techincally greater than, to match.
+ if prospective.local is not None:
+ if Version(prospective.base_version) == Version(spec.base_version):
+ return False
+
+ # If we've gotten to here, it means that prospective version is both
+ # greater than the spec version *and* it's not a pre-release of the
+ # same version in the spec.
+ return True
def _compare_arbitrary(self, prospective, spec):
return str(prospective).lower() == str(spec).lower()
diff --git a/pkg_resources/_vendor/packaging/version.py b/pkg_resources/_vendor/packaging/version.py
index 8d779a48..cf8afb16 100644
--- a/pkg_resources/_vendor/packaging/version.py
+++ b/pkg_resources/_vendor/packaging/version.py
@@ -96,6 +96,10 @@ class LegacyVersion(_BaseVersion):
return self._version
@property
+ def base_version(self):
+ return self._version
+
+ @property
def local(self):
return None
@@ -103,6 +107,10 @@ class LegacyVersion(_BaseVersion):
def is_prerelease(self):
return False
+ @property
+ def is_postrelease(self):
+ return False
+
_legacy_version_component_re = re.compile(
r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
@@ -270,6 +278,19 @@ class Version(_BaseVersion):
return str(self).split("+", 1)[0]
@property
+ def base_version(self):
+ parts = []
+
+ # Epoch
+ if self._version.epoch != 0:
+ parts.append("{0}!".format(self._version.epoch))
+
+ # Release segment
+ parts.append(".".join(str(x) for x in self._version.release))
+
+ return "".join(parts)
+
+ @property
def local(self):
version_string = str(self)
if "+" in version_string:
@@ -279,6 +300,10 @@ class Version(_BaseVersion):
def is_prerelease(self):
return bool(self._version.dev or self._version.pre)
+ @property
+ def is_postrelease(self):
+ return bool(self._version.post)
+
def _parse_letter_version(letter, number):
if letter:
diff --git a/pkg_resources/_vendor/vendored.txt b/pkg_resources/_vendor/vendored.txt
index 723e026b..75a31670 100644
--- a/pkg_resources/_vendor/vendored.txt
+++ b/pkg_resources/_vendor/vendored.txt
@@ -1 +1 @@
-packaging==14.5
+packaging==15.0
diff --git a/pkg_resources/api_tests.txt b/pkg_resources/api_tests.txt
index 50e04b87..a6c25a37 100644
--- a/pkg_resources/api_tests.txt
+++ b/pkg_resources/api_tests.txt
@@ -210,8 +210,7 @@ working set triggers a ``pkg_resources.VersionConflict`` error:
>>> try:
... ws.find(Requirement.parse("Bar==1.0"))
- ... except pkg_resources.VersionConflict:
- ... exc = sys.exc_info()[1]
+ ... except pkg_resources.VersionConflict as exc:
... print(str(exc))
... else:
... raise AssertionError("VersionConflict was not raised")
diff --git a/pkg_resources/tests/__init__.py b/pkg_resources/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/pkg_resources/tests/__init__.py
diff --git a/tests/test_pkg_resources.py b/pkg_resources/tests/test_pkg_resources.py
index 564d7cec..564d7cec 100644
--- a/tests/test_pkg_resources.py
+++ b/pkg_resources/tests/test_pkg_resources.py
diff --git a/setuptools/tests/test_resources.py b/pkg_resources/tests/test_resources.py
index f9f2e459..f252ddff 100644
--- a/setuptools/tests/test_resources.py
+++ b/pkg_resources/tests/test_resources.py
@@ -1,12 +1,9 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# NOTE: the shebang and encoding lines are for ScriptHeaderTests 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,
@@ -15,10 +12,6 @@ from pkg_resources import (parse_requirements, VersionConflict, parse_version,
packaging = pkg_resources.packaging
-from setuptools.command.easy_install import (get_script_header, is_sh,
- nt_quote_arg)
-from setuptools.compat import StringIO, iteritems, PY3
-from .py26compat import skipIf
def safe_repr(obj, short=False):
""" copied from Python2.7"""
@@ -30,53 +23,51 @@ def safe_repr(obj, short=False):
return result
return result[:pkg_resources._MAX_LENGTH] + ' [truncated]...'
+
class Metadata(pkg_resources.EmptyProvider):
"""Mock object to return metadata as if from an on-disk distribution"""
- def __init__(self,*pairs):
+ def __init__(self, *pairs):
self.metadata = dict(pairs)
- def has_metadata(self,name):
+ def has_metadata(self, name):
return name in self.metadata
- def get_metadata(self,name):
+ def get_metadata(self, name):
return self.metadata[name]
- def get_metadata_lines(self,name):
+ def get_metadata_lines(self, name):
return pkg_resources.yield_lines(self.get_metadata(name))
+
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")
@@ -84,31 +75,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.post1")
- 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(
@@ -118,8 +110,8 @@ 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.post1-py2.4-win32.egg")
@@ -140,10 +132,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":
@@ -153,11 +142,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"))
@@ -168,28 +157,28 @@ 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) as vc:
+ ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
+
+ msg = 'Foo 0.9 is installed but Foo==1.2 is required'
+ assert vc.value.report() == msg
def testDistroDependsOptions(self):
d = self.distRequires("""
@@ -214,49 +203,96 @@ 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 TestWorkingSet:
+ def test_find_conflicting(self):
+ ws = WorkingSet([])
+ Foo = Distribution.from_filename("/foo_dir/Foo-1.2.egg")
+ ws.add(Foo)
- 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]"
- )
+ # create a requirement that conflicts with Foo 1.2
+ req = next(parse_requirements("Foo<1.2"))
+
+ with pytest.raises(VersionConflict) as vc:
+ ws.find(req)
+
+ msg = 'Foo 1.2 is installed but Foo<1.2 is required'
+ assert vc.value.report() == msg
+
+ def test_resolve_conflicts_with_prior(self):
+ """
+ A ContextualVersionConflict should be raised when a requirement
+ conflicts with a prior requirement for a different package.
+ """
+ # Create installation where Foo depends on Baz 1.0 and Bar depends on
+ # Baz 2.0.
+ ws = WorkingSet([])
+ md = Metadata(('depends.txt', "Baz==1.0"))
+ Foo = Distribution.from_filename("/foo_dir/Foo-1.0.egg", metadata=md)
+ ws.add(Foo)
+ md = Metadata(('depends.txt', "Baz==2.0"))
+ Bar = Distribution.from_filename("/foo_dir/Bar-1.0.egg", metadata=md)
+ ws.add(Bar)
+ Baz = Distribution.from_filename("/foo_dir/Baz-1.0.egg")
+ ws.add(Baz)
+ Baz = Distribution.from_filename("/foo_dir/Baz-2.0.egg")
+ ws.add(Baz)
- def setUp(self):
+ with pytest.raises(VersionConflict) as vc:
+ ws.resolve(parse_requirements("Foo\nBar\n"))
+
+ msg = "Baz 1.0 is installed but Baz==2.0 is required by {'Bar'}"
+ if pkg_resources.PY2:
+ msg = msg.replace("{'Bar'}", "set(['Bar'])")
+ assert vc.value.report() == msg
+
+
+class TestEntryPoints:
+
+ def assertfields(self, ep):
+ assert ep.name == "foo"
+ assert ep.module_name == "pkg_resources.tests.test_resources"
+ assert ep.attrs == ("TestEntryPoints",)
+ assert ep.extras == ("x",)
+ assert ep.load() is TestEntryPoints
+ expect = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]"
+ assert str(ep) == expect
+
+ 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", "pkg_resources.tests.test_resources", ["TestEntryPoints"],
["x"], self.dist
)
self.assertfields(ep)
def testParse(self):
- s = "foo = setuptools.tests.test_resources:EntryPointTests [x]"
+ s = "foo = pkg_resources.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 [
@@ -267,9 +303,9 @@ class EntryPointTests(TestCase):
else: raise AssertionError("Should've been bad", ep)
def checkSubMap(self, m):
- self.assertEqual(len(m), len(self.submap_expect))
- for key, ep in iteritems(self.submap_expect):
- self.assertEqual(repr(m.get(key)), repr(ep))
+ assert len(m) == len(self.submap_expect)
+ for key, ep in pkg_resources.iteritems(self.submap_expect):
+ assert repr(m.get(key)) == repr(ep)
submap_expect = dict(
feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
@@ -285,63 +321,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)
+ 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")
- self.assertEqual(r1,r2)
- 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", packaging.specifiers.SpecifierSet(">=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):
@@ -349,42 +393,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 = """
@@ -400,48 +444,65 @@ 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.post1")
- 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')
@@ -457,7 +518,7 @@ class ParseTests(TestCase):
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')
@@ -502,15 +563,15 @@ class ParseTests(TestCase):
return True
return _final_version(parsed_version)
- self.assertTrue(buildout(parse_version("1.0")))
- self.assertFalse(buildout(parse_version("1.0a1")))
+ 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.
"""
- self.assertEqual(parse_version("1.0")[0], "00000001")
+ assert parse_version("1.0")[0] == "00000001"
def testVersionTupleSort(self):
"""
@@ -518,102 +579,42 @@ class ParseTests(TestCase):
value of parse_version. So again we'll add a warning enabled shim to
make this possible.
"""
- self.assertTrue(parse_version("1.0") < tuple(parse_version("2.0")))
- self.assertTrue(parse_version("1.0") <= tuple(parse_version("2.0")))
- self.assertTrue(parse_version("1.0") == tuple(parse_version("1.0")))
- self.assertTrue(parse_version("3.0") > tuple(parse_version("2.0")))
- self.assertTrue(parse_version("3.0") >= tuple(parse_version("2.0")))
- self.assertTrue(parse_version("3.0") != tuple(parse_version("2.0")))
- self.assertFalse(parse_version("3.0") != tuple(parse_version("3.0")))
+ 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.
"""
- self.assertEqual(
- hash(parse_version("1.0")),
- hash(parse_version("1.0")),
+ assert (
+ hash(parse_version("1.0"))
+ ==
+ hash(parse_version("1.0"))
)
-class ScriptHeaderTests(TestCase):
- non_ascii_exe = '/Users/José/bin/python'
- exe_with_spaces = r'C:\Program Files\Python33\python.exe'
-
- def test_get_script_header(self):
- 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)
- 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)
- candidate = get_script_header('#!/usr/bin/python',
- executable=self.exe_with_spaces)
- self.assertEqual(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
- if PY3 and os.environ.get("LC_CTYPE") in (None, "C", "POSIX"):
- return
-
- class java:
- class lang:
- class System:
- @staticmethod
- def getProperty(property):
- return ""
- sys.modules["java"] = java
-
- platform = sys.platform
- sys.platform = 'java1.5.0_13'
- stdout, stderr = sys.stdout, sys.stderr
- 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)
-
- # Ensure we generate what is basically a broken shebang line
- # when there's options, with a warning emitted
- sys.stdout = sys.stderr = 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())
- sys.stdout = sys.stderr = 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())
- finally:
- del sys.modules["java"]
- sys.platform = platform
- sys.stdout, sys.stderr = stdout, stderr
-
-
-class NamespaceTests(TestCase):
-
- def setUp(self):
+class TestNamespaces:
+
+ 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
@@ -638,10 +639,8 @@ class NamespaceTests(TestCase):
pkg2_init.close()
import pkg1
assert "pkg1" in pkg_resources._namespace_packages
- try:
- import pkg1.pkg2
- except ImportError:
- self.fail("Setuptools tried to import the parent namespace package")
+ # attempt to import pkg2 from site-pkgs2
+ import pkg1.pkg2
# check the _namespace_packages dict
assert "pkg1.pkg2" in pkg_resources._namespace_packages
assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"]
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/easy_install.py b/setuptools/command/easy_install.py
index 1a2f56ae..d05f4c65 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -698,17 +698,12 @@ Please make the appropriate changes for your system and try again.
distros = WorkingSet([]).resolve(
[requirement], self.local_index, self.easy_install
)
- except DistributionNotFound:
- e = sys.exc_info()[1]
+ except DistributionNotFound as e:
raise DistutilsError(
"Could not find required distribution %s" % e.args
)
- except VersionConflict:
- e = sys.exc_info()[1]
- raise DistutilsError(
- "Installed distribution %s conflicts with requirement %s"
- % e.args
- )
+ except VersionConflict as e:
+ raise DistutilsError(e.report())
if self.always_copy or self.always_copy_from:
# Force all the relevant distros to be copied or activated
for dist in distros:
@@ -1044,8 +1039,7 @@ See the setuptools documentation for the "develop" command for more info.
)
try:
run_setup(setup_script, args)
- except SystemExit:
- v = sys.exc_info()[1]
+ except SystemExit as v:
raise DistutilsError("Setup script exited with %s" % (v.args[0],))
def build_and_install(self, setup_script, setup_base):
@@ -1889,8 +1883,7 @@ def chmod(path, mode):
log.debug("changing mode of %s to %o", path, mode)
try:
_chmod(path, mode)
- except os.error:
- e = sys.exc_info()[1]
+ except os.error as e:
log.debug("chmod failed: %s", e)
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index 3d33df80..851a1775 100755
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -70,7 +70,8 @@ class sdist(orig.sdist):
try:
orig.sdist.read_template(self)
except:
- sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close()
+ _, _, tb = sys.exc_info()
+ tb.tb_next.tb_frame.f_locals['template'].close()
raise
# Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py
index cd6c300c..001ee936 100644
--- a/setuptools/command/upload_docs.py
+++ b/setuptools/command/upload_docs.py
@@ -169,8 +169,7 @@ class upload_docs(upload):
conn.putheader('Authorization', auth)
conn.endheaders()
conn.send(body)
- except socket.error:
- e = sys.exc_info()[1]
+ except socket.error as e:
self.announce(str(e), log.ERROR)
return
diff --git a/setuptools/dist.py b/setuptools/dist.py
index eb146444..1917a610 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -131,8 +131,7 @@ def check_entry_points(dist, attr, value):
"""Verify that entry_points map is parseable"""
try:
pkg_resources.EntryPoint.parse_map(value)
- except ValueError:
- e = sys.exc_info()[1]
+ except ValueError as e:
raise DistutilsSetupError(e)
def check_test_suite(dist, attr, value):
diff --git a/setuptools/msvc9_support.py b/setuptools/msvc9_support.py
index d0be70e2..e76d70f0 100644
--- a/setuptools/msvc9_support.py
+++ b/setuptools/msvc9_support.py
@@ -50,8 +50,7 @@ def find_vcvarsall(version):
def query_vcvarsall(version, *args, **kwargs):
try:
return unpatched['query_vcvarsall'](version, *args, **kwargs)
- except distutils.errors.DistutilsPlatformError:
- exc = sys.exc_info()[1]
+ except distutils.errors.DistutilsPlatformError as exc:
if exc and "vcvarsall.bat" in exc.args[0]:
message = 'Microsoft Visual C++ %0.1f is required (%s).' % (version, exc.args[0])
if int(version) == 9:
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index 58572ce6..5ed19130 100755
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -699,25 +699,21 @@ class PackageIndex(Environment):
return local_open(url)
try:
return open_with_auth(url, self.opener)
- except (ValueError, httplib.InvalidURL):
- v = sys.exc_info()[1]
+ except (ValueError, httplib.InvalidURL) as v:
msg = ' '.join([str(arg) for arg in v.args])
if warning:
self.warn(warning, msg)
else:
raise DistutilsError('%s %s' % (url, msg))
- except urllib2.HTTPError:
- v = sys.exc_info()[1]
+ except urllib2.HTTPError as v:
return v
- except urllib2.URLError:
- v = sys.exc_info()[1]
+ except urllib2.URLError as v:
if warning:
self.warn(warning, v.reason)
else:
raise DistutilsError("Download error for %s: %s"
% (url, v.reason))
- except httplib.BadStatusLine:
- v = sys.exc_info()[1]
+ except httplib.BadStatusLine as v:
if warning:
self.warn(warning, v.line)
else:
@@ -726,8 +722,7 @@ class PackageIndex(Environment):
'down, %s' %
(url, v.line)
)
- except httplib.HTTPException:
- v = sys.exc_info()[1]
+ except httplib.HTTPException as v:
if warning:
self.warn(warning, v)
else:
diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py
index b90d1e1b..7971f42c 100755
--- a/setuptools/sandbox.py
+++ b/setuptools/sandbox.py
@@ -199,8 +199,7 @@ def run_setup(setup_script, args):
ns = dict(__file__=setup_script, __name__='__main__')
_execfile(setup_script, ns)
DirectorySandbox(setup_dir).run(runner)
- except SystemExit:
- v = sys.exc_info()[1]
+ except SystemExit as v:
if v.args and v.args[0]:
raise
# Normal exit, just return
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py
index e5d6545a..b8a29cba 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,22 +9,13 @@ from distutils.core import Extension
from distutils.version import LooseVersion
from setuptools.compat import func_code
+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(
- '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"""
@@ -41,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'):
@@ -54,86 +48,77 @@ class DependsTests(unittest.TestCase):
y = z
fc = func_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'])
@@ -145,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')
@@ -167,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()
@@ -190,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={
@@ -254,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(
@@ -335,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..d06a333f
--- /dev/null
+++ b/setuptools/tests/contexts.py
@@ -0,0 +1,93 @@
+import tempfile
+import os
+import shutil
+import sys
+import contextlib
+import site
+
+from ..compat import StringIO
+
+
+@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 = StringIO()
+ new_stderr = sys.stderr = 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/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 e120e744..c53b4809 100644
--- a/setuptools/tests/py26compat.py
+++ b/setuptools/tests/py26compat.py
@@ -1,27 +1,11 @@
import sys
-import unittest
import tarfile
-
-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
+import contextlib
def _tarfile_open_ex(*args, **kwargs):
"""
Extend result as a context manager.
"""
- res = tarfile.open(*args, **kwargs)
- res.__exit__ = lambda exc_type, exc_value, traceback: res.close()
- res.__enter__ = lambda: res
- return res
+ 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 ae2381e3..6b214279 100644
--- a/setuptools/tests/server.py
+++ b/setuptools/tests/server.py
@@ -1,11 +1,10 @@
"""Basic http server for tests to simulate PyPI or custom indexes
"""
-import sys
+
import time
import threading
from setuptools.compat import BaseHTTPRequestHandler
-from setuptools.compat import (urllib2, URLError, HTTPServer,
- SimpleHTTPRequestHandler)
+from setuptools.compat import HTTPServer, SimpleHTTPRequestHandler
class IndexServer(HTTPServer):
"""Basic single-threaded http server simulating a package index
@@ -23,12 +22,8 @@ class IndexServer(HTTPServer):
HTTPServer.__init__(self, server_address, 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 +32,7 @@ class IndexServer(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):
- urllib2.urlopen(url, timeout=5)
- else:
- urllib2.urlopen(url)
- except URLError:
- # ignore any errors; all that's important is the request
- pass
+ self.shutdown()
self.thread.join()
self.socket.close()
@@ -77,6 +60,6 @@ class MockServer(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/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py
index cf4bcd11..ccfb2ea7 100644
--- a/setuptools/tests/test_bdist_egg.py
+++ b/setuptools/tests/test_bdist_egg.py
@@ -2,52 +2,31 @@
"""
import os
import re
-import shutil
-import site
-import sys
-import tempfile
-import unittest
-from distutils.errors import DistutilsError
-from setuptools.compat import StringIO
-from setuptools.command.bdist_egg import bdist_egg
-from setuptools.command import easy_install as easy_install_pkg
+import pytest
+
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'],
@@ -55,18 +34,10 @@ class TestDevelopTest(unittest.TestCase):
py_modules=['hi']
))
os.makedirs(os.path.join('build', 'src'))
- old_stdout = sys.stdout
- sys.stdout = o = 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 46c2df2c..7baa989a 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -1,13 +1,15 @@
+#! -*- coding: utf-8 -*-
+
"""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 itertools
@@ -16,10 +18,13 @@ import pytest
import mock
from setuptools import sandbox
+from setuptools import compat
from setuptools.compat import StringIO, BytesIO, urlparse
from setuptools.sandbox import run_setup, SandboxViolation
from setuptools.command.easy_install import (
- easy_install, fix_jython_executable, get_script_args, nt_quote_arg)
+ easy_install, fix_jython_executable, get_script_args, nt_quote_arg,
+ get_script_header, is_sh,
+)
from setuptools.command.easy_install import PthDistributions
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
@@ -29,13 +34,8 @@ import setuptools.tests.server
import pkg_resources
from .py26compat import tarfile_open
-
-
-def DALS(input):
- """
- Dedent and left-strip
- """
- return textwrap.dedent(input).lstrip()
+from . import contexts
+from .textwrap import DALS
class FakeDist(object):
@@ -66,7 +66,7 @@ SETUP_PY = DALS("""
setup(name='foo')
""")
-class TestEasyInstallTest(unittest.TestCase):
+class TestEasyInstallTest:
def test_install_site_py(self):
dist = Distribution()
@@ -76,7 +76,7 @@ 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)
@@ -86,7 +86,7 @@ class TestEasyInstallTest(unittest.TestCase):
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
@@ -99,7 +99,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)
@@ -109,59 +109,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):
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')
- with open(setup, 'w') as f:
- f.write(SETUP_PY)
- 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
+@pytest.yield_fixture
+def setup_context(tmpdir):
+ with (tmpdir/'setup.py').open('w') as f:
+ f.write(SETUP_PY)
+ 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()
@@ -169,7 +154,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:
@@ -190,7 +175,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
@@ -216,7 +201,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, ]:
@@ -242,7 +227,6 @@ class TestUserInstallTest(unittest.TestCase):
ei.__file__ = site.USER_SITE
yield
-
def patched_setup_context(self):
self.orig_context = sandbox.setup_context
@@ -251,7 +235,6 @@ class TestUserInstallTest(unittest.TestCase):
self.user_install_setup_context,
)
-
def test_setup_requires(self):
"""Regression test for Distribute issue #318
@@ -260,15 +243,13 @@ 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 contexts.quiet():
with self.patched_setup_context():
run_setup(test_setup_py, ['install'])
- except SandboxViolation:
- self.fail('Installation caused SandboxViolation')
except IndexError:
# Test fails in some cases due to bugs in Python
# See https://bitbucket.org/pypa/setuptools/issue/201
@@ -281,7 +262,7 @@ def distutils_package():
'from setuptools import setup',
'from distutils.core import setup',
)
- with tempdir_context(cd=os.chdir):
+ with contexts.tempdir(cd=os.chdir):
with open('setup.py', 'w') as f:
f.write(distutils_setup_py)
yield
@@ -292,7 +273,7 @@ class TestDistutilsPackage:
run_setup('setup.py', ['bdist_egg'])
-class TestSetupRequires(unittest.TestCase):
+class TestSetupRequires:
def test_setup_requires_honors_fetch_params(self):
"""
@@ -309,11 +290,11 @@ 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):
+ 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,
@@ -321,15 +302,15 @@ class TestSetupRequires(unittest.TestCase):
'--install-dir', temp_install_dir,
dist_file,
]
- with argv_context(['easy_install']):
+ 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
@@ -338,7 +319,7 @@ 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')
script = DALS("""
import setuptools
@@ -366,21 +347,17 @@ 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):
- 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):
+ # Don't even need to install the package, just
+ # running the setup.py at all is sufficient
+ run_setup(test_setup_py, ['--name'])
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)
@@ -438,51 +415,61 @@ def make_trivial_sdist(dist_path, setup_py):
dist.addfile(setup_py_file, fileobj=setup_py_bytes)
-@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
-
+class TestScriptHeader:
+ non_ascii_exe = '/Users/José/bin/python'
+ exe_with_spaces = r'C:\Program Files\Python33\python.exe'
-@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 = StringIO()
- new_stderr = sys.stderr = StringIO()
- try:
- yield new_stdout, new_stderr
- finally:
- new_stdout.seek(0)
- new_stderr.seek(0)
- sys.stdout = old_stdout
- sys.stderr = old_stderr
+ @pytest.mark.skipif(
+ sys.platform.startswith('java') and is_sh(sys.executable),
+ reason="Test cannot run under java when executable is sh"
+ )
+ def test_get_script_header(self):
+ expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable))
+ assert get_script_header('#!/usr/local/bin/python') == expected
+ expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable))
+ 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)
+ assert candidate == '#!"%s"\n' % self.exe_with_spaces
+
+ @pytest.mark.xfail(
+ compat.PY3 and os.environ.get("LC_CTYPE") in ("C", "POSIX"),
+ reason="Test fails in this locale on Python 3"
+ )
+ @mock.patch.dict(sys.modules, java=mock.Mock(lang=mock.Mock(System=
+ mock.Mock(getProperty=mock.Mock(return_value="")))))
+ @mock.patch('sys.platform', 'java1.5.0_13')
+ def test_get_script_header_jython_workaround(self, tmpdir):
+ # Create a mock sys.executable that uses a shebang line
+ header = DALS("""
+ #!/usr/bin/python
+ # -*- coding: utf-8 -*-
+ """)
+ exe = tmpdir / 'exe.py'
+ with exe.open('w') as f:
+ f.write(header)
+ exe = str(exe)
+
+ header = get_script_header('#!/usr/local/bin/python', executable=exe)
+ assert header == '#!/usr/bin/env %s\n' % exe
+
+ expect_out = 'stdout' if sys.version_info < (2,7) else 'stderr'
+
+ with contexts.quiet() as (stdout, stderr):
+ # When options are included, generate a broken shebang line
+ # with a warning emitted
+ candidate = get_script_header('#!/usr/bin/python -x',
+ executable=exe)
+ assert candidate == '#!%s -x\n' % exe
+ output = locals()[expect_out]
+ assert 'Unable to adapt shebang line' in output.getvalue()
+
+ with contexts.quiet() as (stdout, stderr):
+ candidate = get_script_header('#!/usr/bin/python',
+ executable=self.non_ascii_exe)
+ assert candidate == '#!%s -x\n' % self.non_ascii_exe
+ output = locals()[expect_out]
+ assert 'Unable to adapt shebang line' in output.getvalue()
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index 6b4d917f..a1caf9fd 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -1,79 +1,98 @@
import os
-import tempfile
-import shutil
import stat
-import unittest
-from . import environment
+import pytest
+from . import environment
+from .textwrap import DALS
+from . import contexts
-class TestEggInfo(unittest.TestCase):
- def setUp(self):
- self.test_dir = tempfile.mkdtemp()
+class TestEggInfo:
- self.old_cwd = os.getcwd()
- os.chdir(self.test_dir)
+ setup_script = DALS("""
+ from setuptools import setup
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.test_dir)
+ 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('from setuptools import setup\n')
- f.write('\n')
- f.write('setup(\n')
- f.write(" name='foo',\n")
- f.write(" py_modules=['hello'],\n")
- f.write(" entry_points={'console_scripts': ['hi = hello.run']},\n")
- f.write(' zip_safe=False,\n')
- f.write(' )\n')
+ f.write(self.setup_script)
+
with open('hello.py', 'w') as f:
- f.write('def run():\n')
- f.write(" print('hello')\n")
+ f.write(DALS("""
+ def run():
+ print('hello')
+ """))
- def test_egg_base_installed_egg_info(self):
- self._create_project()
- temp_dir = tempfile.mkdtemp(prefix='setuptools-test.')
- os.chmod(temp_dir, stat.S_IRWXU)
- try:
- paths = {}
- for dirname in ['home', 'lib', 'scripts', 'data', 'egg-base']:
- paths[dirname] = os.path.join(temp_dir, dirname)
- os.mkdir(paths[dirname])
- config = os.path.join(paths['home'], '.pydistutils.cfg')
+ @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('[egg_info]\n')
- f.write('egg-base = %s\n' % paths['egg-base'])
- environ = os.environ.copy()
- environ['HOME'] = paths['home']
- code, data = environment.run_setup_py(
- cmd=[
- 'install', '--home', paths['home'],
- '--install-lib', paths['lib'],
- '--install-scripts', paths['scripts'],
- '--install-data', paths['data']],
- pypath=os.pathsep.join([paths['lib'], self.old_cwd]),
- data_stream=1,
- env=environ)
- if code:
- raise AssertionError(data)
- egg_info = None
- for dirpath, dirnames, filenames in os.walk(paths['lib']):
- if os.path.basename(dirpath) == 'EGG-INFO':
- egg_info = sorted(filenames)
- self.assertEqual(
- egg_info,
- ['PKG-INFO',
- 'SOURCES.txt',
- 'dependency_links.txt',
- 'entry_points.txt',
- 'not-zip-safe',
- 'top_level.txt'])
- finally:
- shutil.rmtree(temp_dir)
+ 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)
+
+ 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 test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
+ 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..92a27080 100644
--- a/setuptools/tests/test_integration.py
+++ b/setuptools/tests/test_integration.py
@@ -14,6 +14,17 @@ from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
+def setup_module(module):
+ packages = 'stevedore', 'virtualenvwrapper', 'pbr', 'novaclient'
+ for pkg in packages:
+ try:
+ __import__(pkg)
+ tmpl = "Integration tests cannot run when {pkg} is installed"
+ pytest.skip(tmpl.format(**locals()))
+ except ImportError:
+ pass
+
+
@pytest.fixture
def install_context(request, tmpdir, monkeypatch):
"""Fixture to set up temporary installation directory.
@@ -27,7 +38,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 +82,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 664566a3..dcd90d6f 100644
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -1,26 +1,24 @@
-"""Package Index Tests
-"""
import sys
-import os
-import unittest
-import pkg_resources
-from setuptools.compat import urllib2, httplib, HTTPError, unicode, pathname2url
import distutils.errors
+
+from setuptools.compat import httplib, HTTPError, unicode, pathname2url
+
+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()
url = 'http://127.0.0.1:0/nonesuch/test_package_index'
try:
v = index.open_url(url)
- except Exception:
- v = sys.exc_info()[1]
- self.assertTrue(url in str(v))
+ except Exception as v:
+ assert url in str(v)
else:
- self.assertTrue(isinstance(v, HTTPError))
+ assert isinstance(v, HTTPError)
def test_bad_url_typo(self):
# issue 16
@@ -33,11 +31,10 @@ class TestPackageIndex(unittest.TestCase):
url = 'url:%20https://svn.plone.org/svn/collective/inquant.contentmirror.plone/trunk'
try:
v = index.open_url(url)
- except Exception:
- v = sys.exc_info()[1]
- self.assertTrue(url in str(v))
+ except Exception as v:
+ assert url in str(v)
else:
- self.assertTrue(isinstance(v, HTTPError))
+ assert isinstance(v, HTTPError)
def test_bad_url_bad_status_line(self):
index = setuptools.package_index.PackageIndex(
@@ -51,9 +48,8 @@ class TestPackageIndex(unittest.TestCase):
url = 'http://example.com'
try:
v = index.open_url(url)
- except Exception:
- v = sys.exc_info()[1]
- self.assertTrue('line' in str(v))
+ except Exception as v:
+ assert 'line' in str(v)
else:
raise AssertionError('Should have raise here!')
@@ -69,8 +65,7 @@ class TestPackageIndex(unittest.TestCase):
url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
try:
index.open_url(url)
- except distutils.errors.DistutilsError:
- error = sys.exc_info()[1]
+ except distutils.errors.DistutilsError as error:
msg = unicode(error)
assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg
return
@@ -94,7 +89,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):
"""
@@ -127,21 +122,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):
"""
@@ -149,55 +153,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:' + 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:' + 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_sandbox.py b/setuptools/tests/test_sandbox.py
index 6a890ebc..cadc4812 100644
--- a/setuptools/tests/test_sandbox.py
+++ b/setuptools/tests/test_sandbox.py
@@ -1,67 +1,43 @@
"""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)
- 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)
+ 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:
+ # attempt to create gen_py file
+ sandbox.run(self._file_writer(target))
+ finally:
+ if os.path.exists(target):
+ os.remove(target)
def test_setup_py_with_BOM(self):
"""
@@ -73,11 +49,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 123e3ea9..d3494d7a 100644
--- a/setuptools/tests/test_sdist.py
+++ b/setuptools/tests/test_sdist.py
@@ -6,10 +6,10 @@ import os
import shutil
import sys
import tempfile
-import unittest
import unicodedata
import contextlib
-from setuptools.tests.py26compat import skipIf
+
+import pytest
import pkg_resources
from setuptools.compat import StringIO, unicode, PY3, PY2
@@ -77,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)
@@ -97,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)
@@ -116,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):
@@ -143,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.
@@ -172,18 +172,14 @@ class TestSdistTest(unittest.TestCase):
manifest.close()
# The manifest should be UTF-8 encoded
- try:
- u_contents = contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
+ u_contents = contents.decode('UTF-8')
# The manifest should contain the UTF-8 filename
if PY2:
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 PY3:
@@ -215,17 +211,13 @@ class TestSdistTest(unittest.TestCase):
manifest.close()
# The manifest should be UTF-8 encoded
- try:
- contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
+ contents.decode('UTF-8')
# 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):
"""
@@ -256,17 +248,13 @@ class TestSdistTest(unittest.TestCase):
manifest.close()
# The manifest should be UTF-8 encoded
- try:
- contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
+ contents.decode('UTF-8')
# 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.
@@ -297,7 +285,7 @@ class TestSdistTest(unittest.TestCase):
# The filelist should contain the UTF-8 filename
if PY3:
filename = filename.decode('utf-8')
- self.assertTrue(filename in cmd.filelist.files)
+ assert filename in cmd.filelist.files
# Python 3 only
if PY3:
@@ -326,18 +314,15 @@ class TestSdistTest(unittest.TestCase):
# Re-read manifest
cmd.filelist.files = []
with quiet():
- try:
- cmd.read_manifest()
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
+ cmd.read_manifest()
# 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(PY3 and locale.getpreferredencoding() != 'UTF-8',
- 'Unittest fails if locale is not utf-8 but the manifests is recorded correctly')
+ @pytest.mark.skipif(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)
@@ -362,15 +347,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.
@@ -382,7 +367,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()
@@ -398,11 +383,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
@@ -412,9 +397,9 @@ 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)
+ filename not in cmd.filelist.files
def test_default_revctrl():
@@ -432,7 +417,3 @@ def test_default_revctrl():
ep = pkg_resources.EntryPoint.parse(ep_def)
res = ep._load()
assert hasattr(res, '__iter__')
-
-
-def test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py
index df92085e..a66294c9 100644
--- a/setuptools/tests/test_test.py
+++ b/setuptools/tests/test_test.py
@@ -1,126 +1,91 @@
# -*- 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
-from setuptools.compat import StringIO, PY2
+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 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
-test_suite = unittest.makeSuite(TestTest)
-"""
+ class TestTest(unittest.TestCase):
+ def test_test(self):
+ print "Foo" # Should fail under Python 3 unless 2to3 is used
-class TestTestTest(unittest.TestCase):
+ test_suite = unittest.makeSuite(TestTest)
+ """)
- def setUp(self):
- if sys.version < "2.6" or hasattr(sys, 'real_prefix'):
- return
- # 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')
+@pytest.fixture
+def sample_test(tmpdir_cwd):
+ os.makedirs('name/space/tests')
+
+ # 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 = 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 6b917706..a6fd3e36 100644
--- a/setuptools/version.py
+++ b/setuptools/version.py
@@ -1 +1 @@
-__version__ = '10.2'
+__version__ = '11.2'
diff --git a/tests/shlib_test/hello.c b/tests/shlib_test/hello.c
deleted file mode 100755
index 9998372c..00000000
--- a/tests/shlib_test/hello.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* Generated by Pyrex 0.9.3 on Thu Jan 05 17:47:12 2006 */
-
-#include "Python.h"
-#include "structmember.h"
-#ifndef PY_LONG_LONG
- #define PY_LONG_LONG LONG_LONG
-#endif
-
-
-typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
-typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
-static PyObject *__Pyx_UnpackItem(PyObject *, int); /*proto*/
-static int __Pyx_EndUnpack(PyObject *, int); /*proto*/
-static int __Pyx_PrintItem(PyObject *); /*proto*/
-static int __Pyx_PrintNewline(void); /*proto*/
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static void __Pyx_ReRaise(void); /*proto*/
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
-static PyObject *__Pyx_GetExcValue(void); /*proto*/
-static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
-static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
-static void __Pyx_WriteUnraisable(char *name); /*proto*/
-static void __Pyx_AddTraceback(char *funcname); /*proto*/
-static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
-static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
-static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
-static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-
-static PyObject *__pyx_m;
-static PyObject *__pyx_b;
-static int __pyx_lineno;
-static char *__pyx_filename;
-staticforward char **__pyx_f;
-
-/* Declarations from hello */
-
-char (*(get_hello_msg(void))); /*proto*/
-
-/* Implementation of hello */
-
-static PyObject *__pyx_n_hello;
-
-static PyObject *__pyx_f_5hello_hello(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_f_5hello_hello(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
- PyObject *__pyx_r;
- PyObject *__pyx_1 = 0;
- static char *__pyx_argnames[] = {0};
- if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0;
-
- /* "C:\cygwin\home\pje\setuptools\tests\shlib_test\hello.pyx":4 */
- __pyx_1 = PyString_FromString(get_hello_msg()); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; goto __pyx_L1;}
- __pyx_r = __pyx_1;
- __pyx_1 = 0;
- goto __pyx_L0;
-
- __pyx_r = Py_None; Py_INCREF(__pyx_r);
- goto __pyx_L0;
- __pyx_L1:;
- Py_XDECREF(__pyx_1);
- __Pyx_AddTraceback("hello.hello");
- __pyx_r = 0;
- __pyx_L0:;
- return __pyx_r;
-}
-
-static __Pyx_InternTabEntry __pyx_intern_tab[] = {
- {&__pyx_n_hello, "hello"},
- {0, 0}
-};
-
-static struct PyMethodDef __pyx_methods[] = {
- {"hello", (PyCFunction)__pyx_f_5hello_hello, METH_VARARGS|METH_KEYWORDS, 0},
- {0, 0, 0, 0}
-};
-
-DL_EXPORT(void) inithello(void); /*proto*/
-DL_EXPORT(void) inithello(void) {
- __pyx_m = Py_InitModule4("hello", __pyx_methods, 0, 0, PYTHON_API_VERSION);
- if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;};
- __pyx_b = PyImport_AddModule("__builtin__");
- if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;};
- if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;};
- if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;};
-
- /* "C:\cygwin\home\pje\setuptools\tests\shlib_test\hello.pyx":3 */
- return;
- __pyx_L1:;
- __Pyx_AddTraceback("hello");
-}
-
-static char *__pyx_filenames[] = {
- "hello.pyx",
-};
-statichere char **__pyx_f = __pyx_filenames;
-
-/* Runtime support code */
-
-static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
- while (t->p) {
- *t->p = PyString_InternFromString(t->s);
- if (!*t->p)
- return -1;
- ++t;
- }
- return 0;
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-
-static void __Pyx_AddTraceback(char *funcname) {
- PyObject *py_srcfile = 0;
- PyObject *py_funcname = 0;
- PyObject *py_globals = 0;
- PyObject *empty_tuple = 0;
- PyObject *empty_string = 0;
- PyCodeObject *py_code = 0;
- PyFrameObject *py_frame = 0;
-
- py_srcfile = PyString_FromString(__pyx_filename);
- if (!py_srcfile) goto bad;
- py_funcname = PyString_FromString(funcname);
- if (!py_funcname) goto bad;
- py_globals = PyModule_GetDict(__pyx_m);
- if (!py_globals) goto bad;
- empty_tuple = PyTuple_New(0);
- if (!empty_tuple) goto bad;
- empty_string = PyString_FromString("");
- if (!empty_string) goto bad;
- py_code = PyCode_New(
- 0, /*int argcount,*/
- 0, /*int nlocals,*/
- 0, /*int stacksize,*/
- 0, /*int flags,*/
- empty_string, /*PyObject *code,*/
- empty_tuple, /*PyObject *consts,*/
- empty_tuple, /*PyObject *names,*/
- empty_tuple, /*PyObject *varnames,*/
- empty_tuple, /*PyObject *freevars,*/
- empty_tuple, /*PyObject *cellvars,*/
- py_srcfile, /*PyObject *filename,*/
- py_funcname, /*PyObject *name,*/
- __pyx_lineno, /*int firstlineno,*/
- empty_string /*PyObject *lnotab*/
- );
- if (!py_code) goto bad;
- py_frame = PyFrame_New(
- PyThreadState_Get(), /*PyThreadState *tstate,*/
- py_code, /*PyCodeObject *code,*/
- py_globals, /*PyObject *globals,*/
- 0 /*PyObject *locals*/
- );
- if (!py_frame) goto bad;
- py_frame->f_lineno = __pyx_lineno;
- PyTraceBack_Here(py_frame);
-bad:
- Py_XDECREF(py_srcfile);
- Py_XDECREF(py_funcname);
- Py_XDECREF(empty_tuple);
- Py_XDECREF(empty_string);
- Py_XDECREF(py_code);
- Py_XDECREF(py_frame);
-}
diff --git a/tests/shlib_test/hello.pyx b/tests/shlib_test/hello.pyx
deleted file mode 100755
index 58ce6919..00000000
--- a/tests/shlib_test/hello.pyx
+++ /dev/null
@@ -1,4 +0,0 @@
-cdef extern char *get_hello_msg()
-
-def hello():
- return get_hello_msg()
diff --git a/tests/shlib_test/hellolib.c b/tests/shlib_test/hellolib.c
deleted file mode 100755
index 88d65cee..00000000
--- a/tests/shlib_test/hellolib.c
+++ /dev/null
@@ -1,3 +0,0 @@
-extern char* get_hello_msg() {
- return "Hello, world!";
-}
diff --git a/tests/shlib_test/setup.py b/tests/shlib_test/setup.py
deleted file mode 100755
index b0c93996..00000000
--- a/tests/shlib_test/setup.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from setuptools import setup, Extension, Library
-
-setup(
- name="shlib_test",
- ext_modules = [
- Library("hellolib", ["hellolib.c"]),
- Extension("hello", ["hello.pyx"], libraries=["hellolib"])
- ],
- test_suite="test_hello.HelloWorldTest",
-)
diff --git a/tests/shlib_test/test_hello.py b/tests/shlib_test/test_hello.py
deleted file mode 100755
index 6da02e31..00000000
--- a/tests/shlib_test/test_hello.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from unittest import TestCase
-
-class HelloWorldTest(TestCase):
- def testHelloMsg(self):
- from hello import hello
- self.assertEqual(hello(), "Hello, world!")
-