import sys import os import tempfile import shutil from io import StringIO from distutils.core import Extension, Distribution from distutils.command.build_ext import build_ext from distutils import sysconfig from distutils.tests.support import TempdirManager from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import UnknownFileError import unittest from test import support # http://bugs.python.org/issue4373 # Don't load the xx module more than once. ALREADY_TESTED = False def _get_source_filename(): srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') class BuildExtTestCase(TempdirManager, 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 = self.mkdtemp() self.sys_path = sys.path[:] sys.path.append(self.tmp_dir) shutil.copy(_get_source_filename(), self.tmp_dir) if sys.version > "2.6": import site self.old_user_base = site.USER_BASE site.USER_BASE = self.mkdtemp() from distutils.command import build_ext build_ext.USER_BASE = site.USER_BASE def test_build_ext(self): global ALREADY_TESTED 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) 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") cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir old_stdout = sys.stdout if not support.verbose: # silence compiler output sys.stdout = StringIO() try: cmd.ensure_finalized() cmd.run() finally: sys.stdout = old_stdout if ALREADY_TESTED: return else: ALREADY_TESTED = True import xx for attr in ('error', 'foo', 'new', 'roj'): self.assert_(hasattr(xx, attr)) self.assertEquals(xx.foo(2, 5), 7) self.assertEquals(xx.foo(13,15), 28) self.assertEquals(xx.new().demo(), None) doc = 'This is a template module just for instruction.' self.assertEquals(xx.__doc__, doc) self.assert_(isinstance(xx.Null(), xx.Null)) self.assert_(isinstance(xx.Str(), xx.Str)) def tearDown(self): # Get everything back to normal support.unload('xx') sys.path = self.sys_path if sys.version > "2.6": import site site.USER_BASE = self.old_user_base from distutils.command import build_ext build_ext.USER_BASE = self.old_user_base super(BuildExtTestCase, self).tearDown() def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) cmd = build_ext(dist) old = sys.platform sys.platform = 'sunos' # fooling finalize_options from distutils.sysconfig import _config_vars old_var = _config_vars.get('Py_ENABLE_SHARED') _config_vars['Py_ENABLE_SHARED'] = 1 try: cmd.ensure_finalized() finally: sys.platform = old if old_var is None: del _config_vars['Py_ENABLE_SHARED'] else: _config_vars['Py_ENABLE_SHARED'] = old_var # make sur we get some lobrary dirs under solaris self.assert_(len(cmd.library_dirs) > 0) def test_user_site(self): # site.USER_SITE was introduced in 2.6 if sys.version < '2.6': return import site dist = Distribution({'name': 'xx'}) cmd = build_ext(dist) # making sure the suer option is there options = [name for name, short, lable in cmd.user_options] self.assert_('user' in options) # setting a value cmd.user = 1 # setting user based lib and include lib = os.path.join(site.USER_BASE, 'lib') incl = os.path.join(site.USER_BASE, 'include') os.mkdir(lib) os.mkdir(incl) # let's run finalize cmd.ensure_finalized() # see if include_dirs and library_dirs # were set self.assert_(lib in cmd.library_dirs) self.assert_(incl in cmd.include_dirs) def test_optional_extension(self): # this extension will fail, but let's ignore this failure # with the optional argument. modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = build_ext(dist) cmd.ensure_finalized() self.assertRaises(UnknownFileError, cmd.run) # should raise an error modules = [Extension('foo', ['xxx'], optional=True)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = build_ext(dist) cmd.ensure_finalized() cmd.run() # should pass def test_suite(): src = _get_source_filename() if not os.path.exists(src): if support.verbose: print('test_build_ext: Cannot find source code (test' ' must run in python build dir)') return unittest.TestSuite() else: return unittest.makeSuite(BuildExtTestCase) if __name__ == '__main__': support.run_unittest(test_suite())