aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2016-09-17 17:05:07 -0400
committerJason R. Coombs <jaraco@jaraco.com>2016-09-17 17:05:07 -0400
commit5e4eea7d600f44321e76689890f9f885669f34c9 (patch)
tree490fe5028f963f18e884a0a8f6abb323fb2ce1f6
parent22aa7670dd81117df523109b74011b5609acd362 (diff)
downloadexternal_python_setuptools-5e4eea7d600f44321e76689890f9f885669f34c9.tar.gz
external_python_setuptools-5e4eea7d600f44321e76689890f9f885669f34c9.tar.bz2
external_python_setuptools-5e4eea7d600f44321e76689890f9f885669f34c9.zip
In test command, add installed eggs to PYTHONPATH when invoking tests so that subprocesses will also have the dependencies available. Fixes #794.
-rw-r--r--CHANGES.rst7
-rw-r--r--setuptools/command/test.py57
-rw-r--r--setuptools/dist.py1
3 files changed, 56 insertions, 9 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index af25cc4a..54a4d52a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,6 +2,13 @@
CHANGES
=======
+v27.3.0
+-------
+
+* #794: In test command, add installed eggs to PYTHONPATH
+ when invoking tests so that subprocesses will also have the
+ dependencies available.
+
v27.2.0
-------
diff --git a/setuptools/command/test.py b/setuptools/command/test.py
index 2d1adba8..e0650d27 100644
--- a/setuptools/command/test.py
+++ b/setuptools/command/test.py
@@ -1,10 +1,12 @@
+import os
+import operator
import sys
import contextlib
from distutils.errors import DistutilsOptionError
from unittest import TestLoader
from setuptools.extern import six
-from setuptools.extern.six.moves import map
+from setuptools.extern.six.moves import map, filter
from pkg_resources import (resource_listdir, resource_exists, normalize_path,
working_set, _namespace_packages,
@@ -112,7 +114,7 @@ class test(Command):
func()
@contextlib.contextmanager
- def project_on_sys_path(self):
+ def project_on_sys_path(self, include_dists=[]):
with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False)
if with_2to3:
@@ -144,23 +146,57 @@ class test(Command):
old_modules = sys.modules.copy()
try:
- sys.path.insert(0, normalize_path(ei_cmd.egg_base))
+ project_path = normalize_path(ei_cmd.egg_base)
+ sys.path.insert(0, project_path)
working_set.__init__()
add_activation_listener(lambda dist: dist.activate())
require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
- yield
+ with self.paths_on_pythonpath([project_path]):
+ yield
finally:
sys.path[:] = old_path
sys.modules.clear()
sys.modules.update(old_modules)
working_set.__init__()
+ @staticmethod
+ @contextlib.contextmanager
+ def paths_on_pythonpath(paths):
+ """
+ Add the indicated paths to the head of the PYTHONPATH environment
+ variable so that subprocesses will also see the packages at
+ these paths.
+
+ Do this in a context that restores the value on exit.
+ """
+ nothing = object()
+ orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
+ current_pythonpath = os.environ.get('PYTHONPATH', '')
+ try:
+ prefix = os.pathsep.join(paths)
+ to_join = filter(None, [prefix, current_pythonpath])
+ new_path = os.pathsep.join(to_join)
+ if new_path:
+ os.environ['PYTHONPATH'] = new_path
+ yield
+ finally:
+ if orig_pythonpath is nothing:
+ os.environ.pop('PYTHONPATH', None)
+ else:
+ os.environ['PYTHONPATH'] = orig_pythonpath
+
def run(self):
+ installed_dists = []
if self.distribution.install_requires:
- self.distribution.fetch_build_eggs(
- self.distribution.install_requires)
+ installed_dists.extend(
+ self.distribution.fetch_build_eggs(
+ self.distribution.install_requires,
+ ))
if self.distribution.tests_require:
- self.distribution.fetch_build_eggs(self.distribution.tests_require)
+ installed_dists.extend(
+ self.distribution.fetch_build_eggs(
+ self.distribution.tests_require,
+ ))
cmd = ' '.join(self._argv)
if self.dry_run:
@@ -168,8 +204,11 @@ class test(Command):
return
self.announce('running "%s"' % cmd)
- with self.project_on_sys_path():
- self.run_tests()
+
+ paths = map(operator.attrgetter('location'), installed_dists)
+ with self.paths_on_pythonpath(paths):
+ with self.project_on_sys_path():
+ self.run_tests()
def run_tests(self):
# Purge modules under test from sys.modules. The test loader will
diff --git a/setuptools/dist.py b/setuptools/dist.py
index b004f928..364f2b4d 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -362,6 +362,7 @@ class Distribution(_Distribution):
)
for dist in resolved_dists:
pkg_resources.working_set.add(dist, replace=True)
+ return resolved_dists
def finalize_options(self):
_Distribution.finalize_options(self)