diff --git a/MANIFEST.in b/MANIFEST.in index 13740ce5..532e6148 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -15,7 +15,6 @@ include doc/make.bat include greenlet.c include greenlet.h include make-win-release -include my_build_ext.py include platform/switch_aarch64_gcc.h include platform/switch_amd64_unix.h include platform/switch_arm32_gcc.h diff --git a/conftest.py b/conftest.py index aed8e5d9..e3d92a12 100644 --- a/conftest.py +++ b/conftest.py @@ -6,7 +6,7 @@ def pytest_configure(config): os.chdir(os.path.dirname(__file__)) - cmd = [sys.executable, "setup.py", "-q", "build_ext", "-q"] + cmd = [sys.executable, "setup.py", "-q", "build_ext", "-q", "-i"] spawn(cmd, search_path=0) from tests import build_test_extensions diff --git a/my_build_ext.py b/my_build_ext.py deleted file mode 100644 index 049f0e73..00000000 --- a/my_build_ext.py +++ /dev/null @@ -1,40 +0,0 @@ -# this code has been taken from gevent's setup.py file. it provides a -# build_ext command that puts .so/.pyd files in-place (like "setup.py -# build_ext -i"). it uses symlinks if possible and will rebuild when -# changing the python version (unlike "setup.py build_ext -i") - -import sys, os, shutil - -from distutils.command.build_ext import build_ext as _build_ext - - -def symlink_or_copy(src, dst): - if hasattr(os, 'symlink'): - try: - os.symlink(src, dst) - return - except OSError: # symbolic link privilege not held?? - pass - except NotImplementedError: # running on XP/'CreateSymbolicLinkW not found' - pass - - shutil.copyfile(src, dst) - - -class build_ext(_build_ext): - def build_extension(self, ext): - self.inplace = 0 - _build_ext.build_extension(self, ext) - filename = self.get_ext_filename(ext.name) - build_path = os.path.abspath(os.path.join(self.build_lib, filename)) - src_path = os.path.abspath(filename) - if build_path != src_path: - try: - os.unlink(src_path) - except OSError: - pass - - if self.verbose: - sys.stderr.write('Linking %s to %s\n' % (build_path, src_path)) - - symlink_or_copy(build_path, src_path) diff --git a/run-tests.py b/run-tests.py index 26e6959b..fdca1713 100755 --- a/run-tests.py +++ b/run-tests.py @@ -5,6 +5,7 @@ build = True verbosity = 2 +build_base = None here = os.path.dirname(os.path.abspath(__file__)) os.chdir(here) @@ -16,7 +17,7 @@ def bits(): # -- parse options try: - opts, args = getopt.getopt(sys.argv[1:], "nq") + opts, args = getopt.getopt(sys.argv[1:], "nqb:") if args: raise getopt.GetoptError("too many arguments") except getopt.GetoptError: @@ -27,13 +28,15 @@ def bits(): verbosity = 0 elif o == "-n": build = False + elif o == "-b": + build_base = a # -- build greenlet if build: if verbosity == 0: - cmd = [sys.executable, "setup.py", "-q", "build_ext", "-q"] + cmd = [sys.executable, "setup.py", "-q", "build_ext", "-q", "-i"] else: - cmd = [sys.executable, "setup.py", "build_ext"] + cmd = [sys.executable, "setup.py", "build_ext", "-i"] spawn(cmd, search_path=0) @@ -55,5 +58,5 @@ def bits(): # -- run tests from tests import test_collector -if unittest.TextTestRunner(verbosity=verbosity).run(test_collector()).failures: +if unittest.TextTestRunner(verbosity=verbosity).run(test_collector(build_base)).failures: sys.exit(1) diff --git a/tests/__init__.py b/tests/__init__.py index eb1c2e5c..52cdd039 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,7 +1,9 @@ import os +import sys import glob import unittest from distutils.core import setup, Extension +from distutils.command.build_ext import build_ext TEST_EXTENSIONS = [ Extension('_test_extension', @@ -20,11 +22,11 @@ TEST_EXTENSIONS_CPP = [] -def test_collector(): +def test_collector(build_base=None): """Collect all tests under the tests directory and return a unittest.TestSuite """ - build_test_extensions() + build_test_extensions(build_base) tests_dir = os.path.realpath(os.path.dirname(__file__)) test_module_list = [ 'tests.%s' % os.path.splitext(os.path.basename(t))[0] @@ -34,21 +36,37 @@ def test_collector(): return unittest.TestLoader().loadTestsFromNames(test_module_list) -def build_test_extensions(): +class build_test_ext(build_ext): + """Command for building test extensions + + Forces a non-inplace build and prepends library directory to sys.path. + """ + def build_extension(self, ext): + self.inplace = 0 + build_ext.build_extension(self, ext) + build_lib = os.path.abspath(self.build_lib) + if build_lib not in sys.path: + if self.verbose: + sys.stderr.write('Adding %s to sys.path\n' % (build_lib,)) + sys.path.insert(0, build_lib) + + +def build_test_extensions(build_base=None): """Because distutils sucks, it just copies the entire contents of the build results dir (e.g. build/lib.linux-i686-2.6) during installation. That means that we can't put any files there that we don't want to distribute. - To deal with it, this code will compile test extensions inplace, but - will use a separate directory for build files. This way testing with + To deal with it, this code will compile test extensions in a separate + directory, prepending it to sys.path afterwards. This way testing with multiple Python release and pydebug versions works and test extensions are not distributed. """ - from my_build_ext import build_ext + if build_base is None: + build_base = os.path.join('build', 'tests') setup( options={ - 'build': {'build_base': os.path.join('build', 'tests')}, + 'build': {'build_base': build_base}, }, - cmdclass=dict(build_ext=build_ext), + cmdclass=dict(build_ext=build_test_ext), script_args=['-q', 'build_ext', '-q'], ext_modules=TEST_EXTENSIONS + TEST_EXTENSIONS_CPP)