]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/tests/test_build_ext.py
AppPkg/Applications/Python: Add Python 2.7.2 sources since the release of Python...
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / tests / test_build_ext.py
CommitLineData
4710c53d 1import sys\r
2import os\r
3import tempfile\r
4import shutil\r
5from StringIO import StringIO\r
6import textwrap\r
7\r
8from distutils.core import Extension, Distribution\r
9from distutils.command.build_ext import build_ext\r
10from distutils import sysconfig\r
11from distutils.tests import support\r
12from distutils.errors import DistutilsSetupError, CompileError\r
13\r
14import unittest\r
15from test import test_support\r
16\r
17# http://bugs.python.org/issue4373\r
18# Don't load the xx module more than once.\r
19ALREADY_TESTED = False\r
20\r
21def _get_source_filename():\r
22 srcdir = sysconfig.get_config_var('srcdir')\r
23 if srcdir is None:\r
24 return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c')\r
25 return os.path.join(srcdir, 'Modules', 'xxmodule.c')\r
26\r
27_XX_MODULE_PATH = _get_source_filename()\r
28\r
29class BuildExtTestCase(support.TempdirManager,\r
30 support.LoggingSilencer,\r
31 unittest.TestCase):\r
32 def setUp(self):\r
33 # Create a simple test environment\r
34 # Note that we're making changes to sys.path\r
35 super(BuildExtTestCase, self).setUp()\r
36 self.tmp_dir = tempfile.mkdtemp(prefix="pythontest_")\r
37 if os.path.exists(_XX_MODULE_PATH):\r
38 self.sys_path = sys.path[:]\r
39 sys.path.append(self.tmp_dir)\r
40 shutil.copy(_XX_MODULE_PATH, self.tmp_dir)\r
41\r
42 def tearDown(self):\r
43 # Get everything back to normal\r
44 if os.path.exists(_XX_MODULE_PATH):\r
45 test_support.unload('xx')\r
46 sys.path[:] = self.sys_path\r
47 # XXX on Windows the test leaves a directory\r
48 # with xx module in TEMP\r
49 shutil.rmtree(self.tmp_dir, os.name == 'nt' or\r
50 sys.platform == 'cygwin')\r
51 super(BuildExtTestCase, self).tearDown()\r
52\r
53 def _fixup_command(self, cmd):\r
54 # When Python was build with --enable-shared, -L. is not good enough\r
55 # to find the libpython<blah>.so. This is because regrtest runs it\r
56 # under a tempdir, not in the top level where the .so lives. By the\r
57 # time we've gotten here, Python's already been chdir'd to the\r
58 # tempdir.\r
59 #\r
60 # To further add to the fun, we can't just add library_dirs to the\r
61 # Extension() instance because that doesn't get plumbed through to the\r
62 # final compiler command.\r
63 if (sysconfig.get_config_var('Py_ENABLE_SHARED') and\r
64 not sys.platform.startswith('win')):\r
65 runshared = sysconfig.get_config_var('RUNSHARED')\r
66 if runshared is None:\r
67 cmd.library_dirs = ['.']\r
68 else:\r
69 name, equals, value = runshared.partition('=')\r
70 cmd.library_dirs = value.split(os.pathsep)\r
71\r
72 @unittest.skipIf(not os.path.exists(_XX_MODULE_PATH),\r
73 'xxmodule.c not found')\r
74 def test_build_ext(self):\r
75 global ALREADY_TESTED\r
76 xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')\r
77 xx_ext = Extension('xx', [xx_c])\r
78 dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})\r
79 dist.package_dir = self.tmp_dir\r
80 cmd = build_ext(dist)\r
81 self._fixup_command(cmd)\r
82 if os.name == "nt":\r
83 # On Windows, we must build a debug version iff running\r
84 # a debug build of Python\r
85 cmd.debug = sys.executable.endswith("_d.exe")\r
86 cmd.build_lib = self.tmp_dir\r
87 cmd.build_temp = self.tmp_dir\r
88\r
89 old_stdout = sys.stdout\r
90 if not test_support.verbose:\r
91 # silence compiler output\r
92 sys.stdout = StringIO()\r
93 try:\r
94 cmd.ensure_finalized()\r
95 cmd.run()\r
96 finally:\r
97 sys.stdout = old_stdout\r
98\r
99 if ALREADY_TESTED:\r
100 return\r
101 else:\r
102 ALREADY_TESTED = True\r
103\r
104 import xx\r
105\r
106 for attr in ('error', 'foo', 'new', 'roj'):\r
107 self.assertTrue(hasattr(xx, attr))\r
108\r
109 self.assertEqual(xx.foo(2, 5), 7)\r
110 self.assertEqual(xx.foo(13,15), 28)\r
111 self.assertEqual(xx.new().demo(), None)\r
112 doc = 'This is a template module just for instruction.'\r
113 self.assertEqual(xx.__doc__, doc)\r
114 self.assertTrue(isinstance(xx.Null(), xx.Null))\r
115 self.assertTrue(isinstance(xx.Str(), xx.Str))\r
116\r
117 def test_solaris_enable_shared(self):\r
118 dist = Distribution({'name': 'xx'})\r
119 cmd = build_ext(dist)\r
120 old = sys.platform\r
121\r
122 sys.platform = 'sunos' # fooling finalize_options\r
123 from distutils.sysconfig import _config_vars\r
124 old_var = _config_vars.get('Py_ENABLE_SHARED')\r
125 _config_vars['Py_ENABLE_SHARED'] = 1\r
126 try:\r
127 cmd.ensure_finalized()\r
128 finally:\r
129 sys.platform = old\r
130 if old_var is None:\r
131 del _config_vars['Py_ENABLE_SHARED']\r
132 else:\r
133 _config_vars['Py_ENABLE_SHARED'] = old_var\r
134\r
135 # make sure we get some library dirs under solaris\r
136 self.assertTrue(len(cmd.library_dirs) > 0)\r
137\r
138 def test_finalize_options(self):\r
139 # Make sure Python's include directories (for Python.h, pyconfig.h,\r
140 # etc.) are in the include search path.\r
141 modules = [Extension('foo', ['xxx'])]\r
142 dist = Distribution({'name': 'xx', 'ext_modules': modules})\r
143 cmd = build_ext(dist)\r
144 cmd.finalize_options()\r
145\r
146 from distutils import sysconfig\r
147 py_include = sysconfig.get_python_inc()\r
148 self.assertTrue(py_include in cmd.include_dirs)\r
149\r
150 plat_py_include = sysconfig.get_python_inc(plat_specific=1)\r
151 self.assertTrue(plat_py_include in cmd.include_dirs)\r
152\r
153 # make sure cmd.libraries is turned into a list\r
154 # if it's a string\r
155 cmd = build_ext(dist)\r
156 cmd.libraries = 'my_lib'\r
157 cmd.finalize_options()\r
158 self.assertEqual(cmd.libraries, ['my_lib'])\r
159\r
160 # make sure cmd.library_dirs is turned into a list\r
161 # if it's a string\r
162 cmd = build_ext(dist)\r
163 cmd.library_dirs = 'my_lib_dir'\r
164 cmd.finalize_options()\r
165 self.assertTrue('my_lib_dir' in cmd.library_dirs)\r
166\r
167 # make sure rpath is turned into a list\r
168 # if it's a list of os.pathsep's paths\r
169 cmd = build_ext(dist)\r
170 cmd.rpath = os.pathsep.join(['one', 'two'])\r
171 cmd.finalize_options()\r
172 self.assertEqual(cmd.rpath, ['one', 'two'])\r
173\r
174 # XXX more tests to perform for win32\r
175\r
176 # make sure define is turned into 2-tuples\r
177 # strings if they are ','-separated strings\r
178 cmd = build_ext(dist)\r
179 cmd.define = 'one,two'\r
180 cmd.finalize_options()\r
181 self.assertEqual(cmd.define, [('one', '1'), ('two', '1')])\r
182\r
183 # make sure undef is turned into a list of\r
184 # strings if they are ','-separated strings\r
185 cmd = build_ext(dist)\r
186 cmd.undef = 'one,two'\r
187 cmd.finalize_options()\r
188 self.assertEqual(cmd.undef, ['one', 'two'])\r
189\r
190 # make sure swig_opts is turned into a list\r
191 cmd = build_ext(dist)\r
192 cmd.swig_opts = None\r
193 cmd.finalize_options()\r
194 self.assertEqual(cmd.swig_opts, [])\r
195\r
196 cmd = build_ext(dist)\r
197 cmd.swig_opts = '1 2'\r
198 cmd.finalize_options()\r
199 self.assertEqual(cmd.swig_opts, ['1', '2'])\r
200\r
201 def test_check_extensions_list(self):\r
202 dist = Distribution()\r
203 cmd = build_ext(dist)\r
204 cmd.finalize_options()\r
205\r
206 #'extensions' option must be a list of Extension instances\r
207 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, 'foo')\r
208\r
209 # each element of 'ext_modules' option must be an\r
210 # Extension instance or 2-tuple\r
211 exts = [('bar', 'foo', 'bar'), 'foo']\r
212 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)\r
213\r
214 # first element of each tuple in 'ext_modules'\r
215 # must be the extension name (a string) and match\r
216 # a python dotted-separated name\r
217 exts = [('foo-bar', '')]\r
218 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)\r
219\r
220 # second element of each tuple in 'ext_modules'\r
221 # must be a ary (build info)\r
222 exts = [('foo.bar', '')]\r
223 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)\r
224\r
225 # ok this one should pass\r
226 exts = [('foo.bar', {'sources': [''], 'libraries': 'foo',\r
227 'some': 'bar'})]\r
228 cmd.check_extensions_list(exts)\r
229 ext = exts[0]\r
230 self.assertTrue(isinstance(ext, Extension))\r
231\r
232 # check_extensions_list adds in ext the values passed\r
233 # when they are in ('include_dirs', 'library_dirs', 'libraries'\r
234 # 'extra_objects', 'extra_compile_args', 'extra_link_args')\r
235 self.assertEqual(ext.libraries, 'foo')\r
236 self.assertTrue(not hasattr(ext, 'some'))\r
237\r
238 # 'macros' element of build info dict must be 1- or 2-tuple\r
239 exts = [('foo.bar', {'sources': [''], 'libraries': 'foo',\r
240 'some': 'bar', 'macros': [('1', '2', '3'), 'foo']})]\r
241 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)\r
242\r
243 exts[0][1]['macros'] = [('1', '2'), ('3',)]\r
244 cmd.check_extensions_list(exts)\r
245 self.assertEqual(exts[0].undef_macros, ['3'])\r
246 self.assertEqual(exts[0].define_macros, [('1', '2')])\r
247\r
248 def test_get_source_files(self):\r
249 modules = [Extension('foo', ['xxx'])]\r
250 dist = Distribution({'name': 'xx', 'ext_modules': modules})\r
251 cmd = build_ext(dist)\r
252 cmd.ensure_finalized()\r
253 self.assertEqual(cmd.get_source_files(), ['xxx'])\r
254\r
255 def test_compiler_option(self):\r
256 # cmd.compiler is an option and\r
257 # should not be overriden by a compiler instance\r
258 # when the command is run\r
259 dist = Distribution()\r
260 cmd = build_ext(dist)\r
261 cmd.compiler = 'unix'\r
262 cmd.ensure_finalized()\r
263 cmd.run()\r
264 self.assertEqual(cmd.compiler, 'unix')\r
265\r
266 def test_get_outputs(self):\r
267 tmp_dir = self.mkdtemp()\r
268 c_file = os.path.join(tmp_dir, 'foo.c')\r
269 self.write_file(c_file, 'void initfoo(void) {};\n')\r
270 ext = Extension('foo', [c_file])\r
271 dist = Distribution({'name': 'xx',\r
272 'ext_modules': [ext]})\r
273 cmd = build_ext(dist)\r
274 self._fixup_command(cmd)\r
275 cmd.ensure_finalized()\r
276 self.assertEqual(len(cmd.get_outputs()), 1)\r
277\r
278 if os.name == "nt":\r
279 cmd.debug = sys.executable.endswith("_d.exe")\r
280\r
281 cmd.build_lib = os.path.join(self.tmp_dir, 'build')\r
282 cmd.build_temp = os.path.join(self.tmp_dir, 'tempt')\r
283\r
284 # issue #5977 : distutils build_ext.get_outputs\r
285 # returns wrong result with --inplace\r
286 other_tmp_dir = os.path.realpath(self.mkdtemp())\r
287 old_wd = os.getcwd()\r
288 os.chdir(other_tmp_dir)\r
289 try:\r
290 cmd.inplace = 1\r
291 cmd.run()\r
292 so_file = cmd.get_outputs()[0]\r
293 finally:\r
294 os.chdir(old_wd)\r
295 self.assertTrue(os.path.exists(so_file))\r
296 self.assertEqual(os.path.splitext(so_file)[-1],\r
297 sysconfig.get_config_var('SO'))\r
298 so_dir = os.path.dirname(so_file)\r
299 self.assertEqual(so_dir, other_tmp_dir)\r
300 cmd.compiler = None\r
301 cmd.inplace = 0\r
302 cmd.run()\r
303 so_file = cmd.get_outputs()[0]\r
304 self.assertTrue(os.path.exists(so_file))\r
305 self.assertEqual(os.path.splitext(so_file)[-1],\r
306 sysconfig.get_config_var('SO'))\r
307 so_dir = os.path.dirname(so_file)\r
308 self.assertEqual(so_dir, cmd.build_lib)\r
309\r
310 # inplace = 0, cmd.package = 'bar'\r
311 build_py = cmd.get_finalized_command('build_py')\r
312 build_py.package_dir = {'': 'bar'}\r
313 path = cmd.get_ext_fullpath('foo')\r
314 # checking that the last directory is the build_dir\r
315 path = os.path.split(path)[0]\r
316 self.assertEqual(path, cmd.build_lib)\r
317\r
318 # inplace = 1, cmd.package = 'bar'\r
319 cmd.inplace = 1\r
320 other_tmp_dir = os.path.realpath(self.mkdtemp())\r
321 old_wd = os.getcwd()\r
322 os.chdir(other_tmp_dir)\r
323 try:\r
324 path = cmd.get_ext_fullpath('foo')\r
325 finally:\r
326 os.chdir(old_wd)\r
327 # checking that the last directory is bar\r
328 path = os.path.split(path)[0]\r
329 lastdir = os.path.split(path)[-1]\r
330 self.assertEqual(lastdir, 'bar')\r
331\r
332 def test_ext_fullpath(self):\r
333 ext = sysconfig.get_config_vars()['SO']\r
334 dist = Distribution()\r
335 cmd = build_ext(dist)\r
336 cmd.inplace = 1\r
337 cmd.distribution.package_dir = {'': 'src'}\r
338 cmd.distribution.packages = ['lxml', 'lxml.html']\r
339 curdir = os.getcwd()\r
340 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext)\r
341 path = cmd.get_ext_fullpath('lxml.etree')\r
342 self.assertEqual(wanted, path)\r
343\r
344 # building lxml.etree not inplace\r
345 cmd.inplace = 0\r
346 cmd.build_lib = os.path.join(curdir, 'tmpdir')\r
347 wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext)\r
348 path = cmd.get_ext_fullpath('lxml.etree')\r
349 self.assertEqual(wanted, path)\r
350\r
351 # building twisted.runner.portmap not inplace\r
352 build_py = cmd.get_finalized_command('build_py')\r
353 build_py.package_dir = {}\r
354 cmd.distribution.packages = ['twisted', 'twisted.runner.portmap']\r
355 path = cmd.get_ext_fullpath('twisted.runner.portmap')\r
356 wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner',\r
357 'portmap' + ext)\r
358 self.assertEqual(wanted, path)\r
359\r
360 # building twisted.runner.portmap inplace\r
361 cmd.inplace = 1\r
362 path = cmd.get_ext_fullpath('twisted.runner.portmap')\r
363 wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext)\r
364 self.assertEqual(wanted, path)\r
365\r
366 def test_build_ext_inplace(self):\r
367 etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c')\r
368 etree_ext = Extension('lxml.etree', [etree_c])\r
369 dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]})\r
370 cmd = build_ext(dist)\r
371 cmd.ensure_finalized()\r
372 cmd.inplace = 1\r
373 cmd.distribution.package_dir = {'': 'src'}\r
374 cmd.distribution.packages = ['lxml', 'lxml.html']\r
375 curdir = os.getcwd()\r
376 ext = sysconfig.get_config_var("SO")\r
377 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext)\r
378 path = cmd.get_ext_fullpath('lxml.etree')\r
379 self.assertEqual(wanted, path)\r
380\r
381 def test_setuptools_compat(self):\r
382 import distutils.core, distutils.extension, distutils.command.build_ext\r
383 saved_ext = distutils.extension.Extension\r
384 try:\r
385 # on some platforms, it loads the deprecated "dl" module\r
386 test_support.import_module('setuptools_build_ext', deprecated=True)\r
387\r
388 # theses import patch Distutils' Extension class\r
389 from setuptools_build_ext import build_ext as setuptools_build_ext\r
390 from setuptools_extension import Extension\r
391\r
392 etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c')\r
393 etree_ext = Extension('lxml.etree', [etree_c])\r
394 dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]})\r
395 cmd = setuptools_build_ext(dist)\r
396 cmd.ensure_finalized()\r
397 cmd.inplace = 1\r
398 cmd.distribution.package_dir = {'': 'src'}\r
399 cmd.distribution.packages = ['lxml', 'lxml.html']\r
400 curdir = os.getcwd()\r
401 ext = sysconfig.get_config_var("SO")\r
402 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext)\r
403 path = cmd.get_ext_fullpath('lxml.etree')\r
404 self.assertEqual(wanted, path)\r
405 finally:\r
406 # restoring Distutils' Extension class otherwise its broken\r
407 distutils.extension.Extension = saved_ext\r
408 distutils.core.Extension = saved_ext\r
409 distutils.command.build_ext.Extension = saved_ext\r
410\r
411 def test_build_ext_path_with_os_sep(self):\r
412 dist = Distribution({'name': 'UpdateManager'})\r
413 cmd = build_ext(dist)\r
414 cmd.ensure_finalized()\r
415 ext = sysconfig.get_config_var("SO")\r
416 ext_name = os.path.join('UpdateManager', 'fdsend')\r
417 ext_path = cmd.get_ext_fullpath(ext_name)\r
418 wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext)\r
419 self.assertEqual(ext_path, wanted)\r
420\r
421 def test_build_ext_path_cross_platform(self):\r
422 if sys.platform != 'win32':\r
423 return\r
424 dist = Distribution({'name': 'UpdateManager'})\r
425 cmd = build_ext(dist)\r
426 cmd.ensure_finalized()\r
427 ext = sysconfig.get_config_var("SO")\r
428 # this needs to work even under win32\r
429 ext_name = 'UpdateManager/fdsend'\r
430 ext_path = cmd.get_ext_fullpath(ext_name)\r
431 wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext)\r
432 self.assertEqual(ext_path, wanted)\r
433\r
434 @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX')\r
435 def test_deployment_target(self):\r
436 self._try_compile_deployment_target()\r
437\r
438 orig_environ = os.environ\r
439 os.environ = orig_environ.copy()\r
440 self.addCleanup(setattr, os, 'environ', orig_environ)\r
441\r
442 os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1'\r
443 self._try_compile_deployment_target()\r
444\r
445\r
446 def _try_compile_deployment_target(self):\r
447 deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c')\r
448\r
449 with open(deptarget_c, 'w') as fp:\r
450 fp.write(textwrap.dedent('''\\r
451 #include <AvailabilityMacros.h>\r
452\r
453 int dummy;\r
454\r
455 #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED\r
456 #error "Unexpected target"\r
457 #endif\r
458\r
459 '''))\r
460\r
461 target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')\r
462 target = tuple(map(int, target.split('.')))\r
463 target = '%02d%01d0' % target\r
464\r
465 deptarget_ext = Extension(\r
466 'deptarget',\r
467 [deptarget_c],\r
468 extra_compile_args=['-DTARGET=%s'%(target,)],\r
469 )\r
470 dist = Distribution({\r
471 'name': 'deptarget',\r
472 'ext_modules': [deptarget_ext]\r
473 })\r
474 dist.package_dir = self.tmp_dir\r
475 cmd = build_ext(dist)\r
476 cmd.build_lib = self.tmp_dir\r
477 cmd.build_temp = self.tmp_dir\r
478\r
479 try:\r
480 old_stdout = sys.stdout\r
481 cmd.ensure_finalized()\r
482 cmd.run()\r
483\r
484 except CompileError:\r
485 self.fail("Wrong deployment target during compilation")\r
486\r
487def test_suite():\r
488 return unittest.makeSuite(BuildExtTestCase)\r
489\r
490if __name__ == '__main__':\r
491 test_support.run_unittest(test_suite())\r