diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2016-09-17 17:05:07 -0400 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2016-09-17 17:05:07 -0400 |
commit | 5e4eea7d600f44321e76689890f9f885669f34c9 (patch) | |
tree | 490fe5028f963f18e884a0a8f6abb323fb2ce1f6 | |
parent | 22aa7670dd81117df523109b74011b5609acd362 (diff) | |
download | external_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.rst | 7 | ||||
-rw-r--r-- | setuptools/command/test.py | 57 | ||||
-rw-r--r-- | setuptools/dist.py | 1 |
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) |