test_build_ext.py (13549B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\tests\test_build_ext.py 2 import sys 3 import os 4 import tempfile 5 import shutil 6 from StringIO import StringIO 7 from distutils.core import Extension, Distribution 8 from distutils.command.build_ext import build_ext 9 from distutils import sysconfig 10 from distutils.tests import support 11 from distutils.errors import DistutilsSetupError 12 import unittest 13 from test import test_support 14 ALREADY_TESTED = False 15 16 def _get_source_filename(): 17 srcdir = sysconfig.get_config_var('srcdir') 18 if srcdir is None: 19 return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c') 20 return os.path.join(srcdir, 'Modules', 'xxmodule.c') 21 22 23 _XX_MODULE_PATH = _get_source_filename() 24 25 class BuildExtTestCase(support.TempdirManager, support.LoggingSilencer, unittest.TestCase): 26 27 def setUp(self): 28 super(BuildExtTestCase, self).setUp() 29 self.tmp_dir = tempfile.mkdtemp(prefix='pythontest_') 30 if os.path.exists(_XX_MODULE_PATH): 31 self.sys_path = sys.path[:] 32 sys.path.append(self.tmp_dir) 33 shutil.copy(_XX_MODULE_PATH, self.tmp_dir) 34 35 def tearDown(self): 36 if os.path.exists(_XX_MODULE_PATH): 37 test_support.unload('xx') 38 sys.path[:] = self.sys_path 39 shutil.rmtree(self.tmp_dir, os.name == 'nt' or sys.platform == 'cygwin') 40 super(BuildExtTestCase, self).tearDown() 41 42 def _fixup_command(self, cmd): 43 if sysconfig.get_config_var('Py_ENABLE_SHARED') and not sys.platform.startswith('win'): 44 runshared = sysconfig.get_config_var('RUNSHARED') 45 if runshared is None: 46 cmd.library_dirs = ['.'] 47 else: 48 name, equals, value = runshared.partition('=') 49 cmd.library_dirs = value.split(os.pathsep) 50 51 @unittest.skipIf(not os.path.exists(_XX_MODULE_PATH), 'xxmodule.c not found') 52 def test_build_ext(self): 53 global ALREADY_TESTED 54 xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') 55 xx_ext = Extension('xx', [xx_c]) 56 dist = Distribution({'name': 'xx', 57 'ext_modules': [xx_ext]}) 58 dist.package_dir = self.tmp_dir 59 cmd = build_ext(dist) 60 self._fixup_command(cmd) 61 if os.name == 'nt': 62 cmd.debug = sys.executable.endswith('_d.exe') 63 cmd.build_lib = self.tmp_dir 64 cmd.build_temp = self.tmp_dir 65 old_stdout = sys.stdout 66 if not test_support.verbose: 67 sys.stdout = StringIO() 68 try: 69 cmd.ensure_finalized() 70 cmd.run() 71 finally: 72 sys.stdout = old_stdout 73 74 if ALREADY_TESTED: 75 return 76 ALREADY_TESTED = True 77 import xx 78 for attr in ('error', 'foo', 'new', 'roj'): 79 self.assertTrue(hasattr(xx, attr)) 80 81 self.assertEqual(xx.foo(2, 5), 7) 82 self.assertEqual(xx.foo(13, 15), 28) 83 self.assertEqual(xx.new().demo(), None) 84 doc = 'This is a template module just for instruction.' 85 self.assertEqual(xx.__doc__, doc) 86 self.assertTrue(isinstance(xx.Null(), xx.Null)) 87 self.assertTrue(isinstance(xx.Str(), xx.Str)) 88 89 def test_solaris_enable_shared(self): 90 dist = Distribution({'name': 'xx'}) 91 cmd = build_ext(dist) 92 old = sys.platform 93 sys.platform = 'sunos' 94 from distutils.sysconfig import _config_vars 95 old_var = _config_vars.get('Py_ENABLE_SHARED') 96 _config_vars['Py_ENABLE_SHARED'] = 1 97 try: 98 cmd.ensure_finalized() 99 finally: 100 sys.platform = old 101 if old_var is None: 102 del _config_vars['Py_ENABLE_SHARED'] 103 else: 104 _config_vars['Py_ENABLE_SHARED'] = old_var 105 106 self.assertTrue(len(cmd.library_dirs) > 0) 107 108 def test_finalize_options(self): 109 modules = [Extension('foo', ['xxx'])] 110 dist = Distribution({'name': 'xx', 111 'ext_modules': modules}) 112 cmd = build_ext(dist) 113 cmd.finalize_options() 114 from distutils import sysconfig 115 py_include = sysconfig.get_python_inc() 116 self.assertTrue(py_include in cmd.include_dirs) 117 plat_py_include = sysconfig.get_python_inc(plat_specific=1) 118 self.assertTrue(plat_py_include in cmd.include_dirs) 119 cmd = build_ext(dist) 120 cmd.libraries = 'my_lib' 121 cmd.finalize_options() 122 self.assertEqual(cmd.libraries, ['my_lib']) 123 cmd = build_ext(dist) 124 cmd.library_dirs = 'my_lib_dir' 125 cmd.finalize_options() 126 self.assertTrue('my_lib_dir' in cmd.library_dirs) 127 cmd = build_ext(dist) 128 cmd.rpath = os.pathsep.join(['one', 'two']) 129 cmd.finalize_options() 130 self.assertEqual(cmd.rpath, ['one', 'two']) 131 cmd = build_ext(dist) 132 cmd.define = 'one,two' 133 cmd.finalize_options() 134 self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) 135 cmd = build_ext(dist) 136 cmd.undef = 'one,two' 137 cmd.finalize_options() 138 self.assertEqual(cmd.undef, ['one', 'two']) 139 cmd = build_ext(dist) 140 cmd.swig_opts = None 141 cmd.finalize_options() 142 self.assertEqual(cmd.swig_opts, []) 143 cmd = build_ext(dist) 144 cmd.swig_opts = '1 2' 145 cmd.finalize_options() 146 self.assertEqual(cmd.swig_opts, ['1', '2']) 147 148 def test_check_extensions_list(self): 149 dist = Distribution() 150 cmd = build_ext(dist) 151 cmd.finalize_options() 152 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, 'foo') 153 exts = [('bar', 'foo', 'bar'), 'foo'] 154 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 155 exts = [('foo-bar', '')] 156 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 157 exts = [('foo.bar', '')] 158 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 159 exts = [('foo.bar', {'sources': [''], 160 'libraries': 'foo', 161 'some': 'bar'})] 162 cmd.check_extensions_list(exts) 163 ext = exts[0] 164 self.assertTrue(isinstance(ext, Extension)) 165 self.assertEqual(ext.libraries, 'foo') 166 self.assertTrue(not hasattr(ext, 'some')) 167 exts = [('foo.bar', {'sources': [''], 168 'libraries': 'foo', 169 'some': 'bar', 170 'macros': [('1', '2', '3'), 'foo']})] 171 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 172 exts[0][1]['macros'] = [('1', '2'), ('3',)] 173 cmd.check_extensions_list(exts) 174 self.assertEqual(exts[0].undef_macros, ['3']) 175 self.assertEqual(exts[0].define_macros, [('1', '2')]) 176 177 def test_get_source_files(self): 178 modules = [Extension('foo', ['xxx'])] 179 dist = Distribution({'name': 'xx', 180 'ext_modules': modules}) 181 cmd = build_ext(dist) 182 cmd.ensure_finalized() 183 self.assertEqual(cmd.get_source_files(), ['xxx']) 184 185 def test_compiler_option(self): 186 dist = Distribution() 187 cmd = build_ext(dist) 188 cmd.compiler = 'unix' 189 cmd.ensure_finalized() 190 cmd.run() 191 self.assertEqual(cmd.compiler, 'unix') 192 193 def test_get_outputs(self): 194 tmp_dir = self.mkdtemp() 195 c_file = os.path.join(tmp_dir, 'foo.c') 196 self.write_file(c_file, 'void initfoo(void) {};\n') 197 ext = Extension('foo', [c_file]) 198 dist = Distribution({'name': 'xx', 199 'ext_modules': [ext]}) 200 cmd = build_ext(dist) 201 self._fixup_command(cmd) 202 cmd.ensure_finalized() 203 self.assertEqual(len(cmd.get_outputs()), 1) 204 if os.name == 'nt': 205 cmd.debug = sys.executable.endswith('_d.exe') 206 cmd.build_lib = os.path.join(self.tmp_dir, 'build') 207 cmd.build_temp = os.path.join(self.tmp_dir, 'tempt') 208 other_tmp_dir = os.path.realpath(self.mkdtemp()) 209 old_wd = os.getcwd() 210 os.chdir(other_tmp_dir) 211 try: 212 cmd.inplace = 1 213 cmd.run() 214 so_file = cmd.get_outputs()[0] 215 finally: 216 os.chdir(old_wd) 217 218 self.assertTrue(os.path.exists(so_file)) 219 self.assertEqual(os.path.splitext(so_file)[-1], sysconfig.get_config_var('SO')) 220 so_dir = os.path.dirname(so_file) 221 self.assertEqual(so_dir, other_tmp_dir) 222 cmd.compiler = None 223 cmd.inplace = 0 224 cmd.run() 225 so_file = cmd.get_outputs()[0] 226 self.assertTrue(os.path.exists(so_file)) 227 self.assertEqual(os.path.splitext(so_file)[-1], sysconfig.get_config_var('SO')) 228 so_dir = os.path.dirname(so_file) 229 self.assertEqual(so_dir, cmd.build_lib) 230 build_py = cmd.get_finalized_command('build_py') 231 build_py.package_dir = {'': 'bar'} 232 path = cmd.get_ext_fullpath('foo') 233 path = os.path.split(path)[0] 234 self.assertEqual(path, cmd.build_lib) 235 cmd.inplace = 1 236 other_tmp_dir = os.path.realpath(self.mkdtemp()) 237 old_wd = os.getcwd() 238 os.chdir(other_tmp_dir) 239 try: 240 path = cmd.get_ext_fullpath('foo') 241 finally: 242 os.chdir(old_wd) 243 244 path = os.path.split(path)[0] 245 lastdir = os.path.split(path)[-1] 246 self.assertEqual(lastdir, 'bar') 247 248 def test_ext_fullpath(self): 249 ext = sysconfig.get_config_vars()['SO'] 250 dist = Distribution() 251 cmd = build_ext(dist) 252 cmd.inplace = 1 253 cmd.distribution.package_dir = {'': 'src'} 254 cmd.distribution.packages = ['lxml', 'lxml.html'] 255 curdir = os.getcwd() 256 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 257 path = cmd.get_ext_fullpath('lxml.etree') 258 self.assertEqual(wanted, path) 259 cmd.inplace = 0 260 cmd.build_lib = os.path.join(curdir, 'tmpdir') 261 wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) 262 path = cmd.get_ext_fullpath('lxml.etree') 263 self.assertEqual(wanted, path) 264 build_py = cmd.get_finalized_command('build_py') 265 build_py.package_dir = {} 266 cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] 267 path = cmd.get_ext_fullpath('twisted.runner.portmap') 268 wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', 'portmap' + ext) 269 self.assertEqual(wanted, path) 270 cmd.inplace = 1 271 path = cmd.get_ext_fullpath('twisted.runner.portmap') 272 wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) 273 self.assertEqual(wanted, path) 274 275 def test_build_ext_inplace(self): 276 etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') 277 etree_ext = Extension('lxml.etree', [etree_c]) 278 dist = Distribution({'name': 'lxml', 279 'ext_modules': [etree_ext]}) 280 cmd = build_ext(dist) 281 cmd.ensure_finalized() 282 cmd.inplace = 1 283 cmd.distribution.package_dir = {'': 'src'} 284 cmd.distribution.packages = ['lxml', 'lxml.html'] 285 curdir = os.getcwd() 286 ext = sysconfig.get_config_var('SO') 287 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 288 path = cmd.get_ext_fullpath('lxml.etree') 289 self.assertEqual(wanted, path) 290 291 def test_setuptools_compat(self): 292 import distutils.core, distutils.extension, distutils.command.build_ext 293 saved_ext = distutils.extension.Extension 294 try: 295 test_support.import_module('setuptools_build_ext', deprecated=True) 296 from setuptools_build_ext import build_ext as setuptools_build_ext 297 from setuptools_extension import Extension 298 etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') 299 etree_ext = Extension('lxml.etree', [etree_c]) 300 dist = Distribution({'name': 'lxml', 301 'ext_modules': [etree_ext]}) 302 cmd = setuptools_build_ext(dist) 303 cmd.ensure_finalized() 304 cmd.inplace = 1 305 cmd.distribution.package_dir = {'': 'src'} 306 cmd.distribution.packages = ['lxml', 'lxml.html'] 307 curdir = os.getcwd() 308 ext = sysconfig.get_config_var('SO') 309 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 310 path = cmd.get_ext_fullpath('lxml.etree') 311 self.assertEqual(wanted, path) 312 finally: 313 distutils.extension.Extension = saved_ext 314 distutils.core.Extension = saved_ext 315 distutils.command.build_ext.Extension = saved_ext 316 317 def test_build_ext_path_with_os_sep(self): 318 dist = Distribution({'name': 'UpdateManager'}) 319 cmd = build_ext(dist) 320 cmd.ensure_finalized() 321 ext = sysconfig.get_config_var('SO') 322 ext_name = os.path.join('UpdateManager', 'fdsend') 323 ext_path = cmd.get_ext_fullpath(ext_name) 324 wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) 325 self.assertEqual(ext_path, wanted) 326 327 def test_build_ext_path_cross_platform(self): 328 if sys.platform != 'win32': 329 return 330 dist = Distribution({'name': 'UpdateManager'}) 331 cmd = build_ext(dist) 332 cmd.ensure_finalized() 333 ext = sysconfig.get_config_var('SO') 334 ext_name = 'UpdateManager/fdsend' 335 ext_path = cmd.get_ext_fullpath(ext_name) 336 wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) 337 self.assertEqual(ext_path, wanted) 338 339 340 def test_suite(): 341 return unittest.makeSuite(BuildExtTestCase) 342 343 344 if __name__ == '__main__': 345 test_support.run_unittest(test_suite())