diff options
author | Éric Araujo <merwok@netwok.org> | 2011-08-25 23:56:15 (GMT) |
---|---|---|
committer | Éric Araujo <merwok@netwok.org> | 2011-08-25 23:56:15 (GMT) |
commit | 04612d60929d5cda8d4cd215dfa2fc050d20b530 (patch) | |
tree | 808256f32d6ed2c21322ce403d33b20895cb00b6 /Lib | |
parent | 04295009b8d7be75d5e361d8f332b12a6418799a (diff) | |
download | cpython-04612d60929d5cda8d4cd215dfa2fc050d20b530.zip cpython-04612d60929d5cda8d4cd215dfa2fc050d20b530.tar.gz cpython-04612d60929d5cda8d4cd215dfa2fc050d20b530.tar.bz2 |
Refactor helpers for compiling the xx module in distutils tests.
I need to copy the xxmodule.c file in other tests, so I moved the
support code to distutils.tests.support and improved it:
- don’t skip when run from the Lib/distutils/tests directory
- use proper skip machinery instead of custom print/return/test suite
fiddling.
I also took out the fixup_build_ext function, which is needed for tests
to pass on Unix shared builds and Windows debug builds.
Finally, I cleaned up a few things:
- don’t remove directories in tearDown when the parent class’ tearDown
has already registered the directories for removal
- simplify restoration of sys.path
- remove a few unused names found by pyflakes.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/distutils/tests/support.py | 76 | ||||
-rw-r--r-- | Lib/distutils/tests/test_build_ext.py | 68 |
2 files changed, 85 insertions, 59 deletions
diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py index 783318e..788acda 100644 --- a/Lib/distutils/tests/support.py +++ b/Lib/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils import log from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ def capture_warnings(func): return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ class LoggingSilencer(object): def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -105,6 +111,7 @@ class TempdirManager(object): return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +122,7 @@ class DummyCommand: def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +139,71 @@ class EnvironGuard(object): del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): + """Helper for tests that need the xxmodule.c source file. + + Example use: + + def test_compile(self): + copy_xxmodule_c(self.tmpdir) + self.assertIn('xxmodule.c', os.listdir(self.tmpdir)) + + If the source file can be found, it will be copied to *directory*. If not, + the test will be skipped. Errors during copy are not caught. + """ + filename = _get_xxmodule_path() + if filename is None: + raise unittest.SkipTest('cannot find xxmodule.c (test must run in ' + 'the python build dir)') + shutil.copy(filename, directory) + + +def _get_xxmodule_path(): + srcdir = sysconfig.get_config_var('srcdir') + candidates = [ + # use installed copy if available + os.path.join(os.path.dirname(__file__), 'xxmodule.c'), + # otherwise try using copy from build directory + os.path.join(srcdir, 'Modules', 'xxmodule.c'), + # srcdir mysteriously can be $srcdir/Lib/distutils/tests when + # this file is run from its parent directory, so walk up the + # tree to find the real srcdir + os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'), + ] + for path in candidates: + if os.path.exists(path): + return path + + +def fixup_build_ext(cmd): + """Function needed to make build_ext tests pass. + + When Python was build with --enable-shared on Unix, -L. is not good + enough to find the libpython<blah>.so. This is because regrtest runs + it under a tempdir, not in the top level where the .so lives. By the + time we've gotten here, Python's already been chdir'd to the tempdir. + + When Python was built with in debug mode on Windows, build_ext commands + need their debug attribute set, and it is not done automatically for + some reason. + + This function handles both of these things. Example use: + + cmd = build_ext(dist) + support.fixup_build_ext(cmd) + cmd.ensure_finalized() + """ + if os.name == 'nt': + cmd.debug = sys.executable.endswith('_d.exe') + elif sysconfig.get_config_var('Py_ENABLE_SHARED'): + # To further add to the shared builds fun on Unix, we can't just add + # library_dirs to the Extension() instance because that doesn't get + # plumbed through to the final compiler command. + runshared = sysconfig.get_config_var('RUNSHARED') + if runshared is None: + cmd.library_dirs = ['.'] + else: + name, equals, value = runshared.partition('=') + cmd.library_dirs = value.split(os.pathsep) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index ced1329..30de0e2 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -1,7 +1,5 @@ import sys import os -import tempfile -import shutil from StringIO import StringIO import textwrap @@ -19,76 +17,34 @@ from test import test_support # Don't load the xx module more than once. ALREADY_TESTED = False -def _get_source_filename(): - # use installed copy if available - tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c') - if os.path.exists(tests_f): - return tests_f - # otherwise try using copy from build directory - srcdir = sysconfig.get_config_var('srcdir') - if srcdir is None: - return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c') - return os.path.join(srcdir, 'Modules', 'xxmodule.c') - -_XX_MODULE_PATH = _get_source_filename() class BuildExtTestCase(support.TempdirManager, support.LoggingSilencer, unittest.TestCase): def setUp(self): - # Create a simple test environment - # Note that we're making changes to sys.path super(BuildExtTestCase, self).setUp() - self.tmp_dir = tempfile.mkdtemp(prefix="pythontest_") - if os.path.exists(_XX_MODULE_PATH): - self.sys_path = sys.path[:] - sys.path.append(self.tmp_dir) - shutil.copy(_XX_MODULE_PATH, self.tmp_dir) + self.tmp_dir = self.mkdtemp() + self.xx_created = False + sys.path.append(self.tmp_dir) + self.addCleanup(sys.path.remove, self.tmp_dir) def tearDown(self): - # Get everything back to normal - if os.path.exists(_XX_MODULE_PATH): + if self.xx_created: test_support.unload('xx') - sys.path[:] = self.sys_path # XXX on Windows the test leaves a directory # with xx module in TEMP - shutil.rmtree(self.tmp_dir, os.name == 'nt' or - sys.platform == 'cygwin') super(BuildExtTestCase, self).tearDown() - def _fixup_command(self, cmd): - # When Python was build with --enable-shared, -L. is not good enough - # to find the libpython<blah>.so. This is because regrtest runs it - # under a tempdir, not in the top level where the .so lives. By the - # time we've gotten here, Python's already been chdir'd to the - # tempdir. - # - # To further add to the fun, we can't just add library_dirs to the - # Extension() instance because that doesn't get plumbed through to the - # final compiler command. - if (sysconfig.get_config_var('Py_ENABLE_SHARED') and - not sys.platform.startswith('win')): - runshared = sysconfig.get_config_var('RUNSHARED') - if runshared is None: - cmd.library_dirs = ['.'] - else: - name, equals, value = runshared.partition('=') - cmd.library_dirs = value.split(os.pathsep) - - @unittest.skipIf(not os.path.exists(_XX_MODULE_PATH), - 'xxmodule.c not found') def test_build_ext(self): global ALREADY_TESTED + support.copy_xxmodule_c(self.tmp_dir) + self.xx_created = True xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') xx_ext = Extension('xx', [xx_c]) dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) dist.package_dir = self.tmp_dir cmd = build_ext(dist) - self._fixup_command(cmd) - if os.name == "nt": - # On Windows, we must build a debug version iff running - # a debug build of Python - cmd.debug = sys.executable.endswith("_d.exe") + support.fixup_build_ext(cmd) cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir @@ -149,7 +105,6 @@ class BuildExtTestCase(support.TempdirManager, cmd = build_ext(dist) cmd.finalize_options() - from distutils import sysconfig py_include = sysconfig.get_python_inc() self.assertTrue(py_include in cmd.include_dirs) @@ -277,13 +232,10 @@ class BuildExtTestCase(support.TempdirManager, dist = Distribution({'name': 'xx', 'ext_modules': [ext]}) cmd = build_ext(dist) - self._fixup_command(cmd) + support.fixup_build_ext(cmd) cmd.ensure_finalized() self.assertEqual(len(cmd.get_outputs()), 1) - if os.name == "nt": - cmd.debug = sys.executable.endswith("_d.exe") - cmd.build_lib = os.path.join(self.tmp_dir, 'build') cmd.build_temp = os.path.join(self.tmp_dir, 'tempt') @@ -509,10 +461,8 @@ class BuildExtTestCase(support.TempdirManager, cmd.build_temp = self.tmp_dir try: - old_stdout = sys.stdout cmd.ensure_finalized() cmd.run() - except CompileError: self.fail("Wrong deployment target during compilation") |