Spaces:
Runtime error
Runtime error
| """Tests for distutils.sysconfig.""" | |
| import contextlib | |
| import os | |
| import shutil | |
| import subprocess | |
| import sys | |
| import textwrap | |
| import unittest | |
| from distutils import sysconfig | |
| from distutils.ccompiler import get_default_compiler | |
| from distutils.tests import support | |
| from test.support import run_unittest, swap_item, requires_subprocess, is_wasi | |
| from test.support.os_helper import TESTFN | |
| from test.support.warnings_helper import check_warnings | |
| class SysconfigTestCase(support.EnvironGuard, unittest.TestCase): | |
| def setUp(self): | |
| super(SysconfigTestCase, self).setUp() | |
| self.makefile = None | |
| def tearDown(self): | |
| if self.makefile is not None: | |
| os.unlink(self.makefile) | |
| self.cleanup_testfn() | |
| super(SysconfigTestCase, self).tearDown() | |
| def cleanup_testfn(self): | |
| if os.path.isfile(TESTFN): | |
| os.remove(TESTFN) | |
| elif os.path.isdir(TESTFN): | |
| shutil.rmtree(TESTFN) | |
| def test_get_config_h_filename(self): | |
| config_h = sysconfig.get_config_h_filename() | |
| self.assertTrue(os.path.isfile(config_h), config_h) | |
| def test_get_python_lib(self): | |
| # XXX doesn't work on Linux when Python was never installed before | |
| #self.assertTrue(os.path.isdir(lib_dir), lib_dir) | |
| # test for pythonxx.lib? | |
| self.assertNotEqual(sysconfig.get_python_lib(), | |
| sysconfig.get_python_lib(prefix=TESTFN)) | |
| def test_get_config_vars(self): | |
| cvars = sysconfig.get_config_vars() | |
| self.assertIsInstance(cvars, dict) | |
| self.assertTrue(cvars) | |
| def test_srcdir(self): | |
| # See Issues #15322, #15364. | |
| srcdir = sysconfig.get_config_var('srcdir') | |
| self.assertTrue(os.path.isabs(srcdir), srcdir) | |
| self.assertTrue(os.path.isdir(srcdir), srcdir) | |
| if sysconfig.python_build: | |
| # The python executable has not been installed so srcdir | |
| # should be a full source checkout. | |
| Python_h = os.path.join(srcdir, 'Include', 'Python.h') | |
| self.assertTrue(os.path.exists(Python_h), Python_h) | |
| # <srcdir>/PC/pyconfig.h always exists even if unused on POSIX. | |
| pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') | |
| self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) | |
| pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') | |
| self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) | |
| elif os.name == 'posix': | |
| self.assertEqual( | |
| os.path.dirname(sysconfig.get_makefile_filename()), | |
| srcdir) | |
| def test_srcdir_independent_of_cwd(self): | |
| # srcdir should be independent of the current working directory | |
| # See Issues #15322, #15364. | |
| srcdir = sysconfig.get_config_var('srcdir') | |
| cwd = os.getcwd() | |
| try: | |
| os.chdir('..') | |
| srcdir2 = sysconfig.get_config_var('srcdir') | |
| finally: | |
| os.chdir(cwd) | |
| self.assertEqual(srcdir, srcdir2) | |
| def customize_compiler(self): | |
| # make sure AR gets caught | |
| class compiler: | |
| compiler_type = 'unix' | |
| def set_executables(self, **kw): | |
| self.exes = kw | |
| sysconfig_vars = { | |
| 'AR': 'sc_ar', | |
| 'CC': 'sc_cc', | |
| 'CXX': 'sc_cxx', | |
| 'ARFLAGS': '--sc-arflags', | |
| 'CFLAGS': '--sc-cflags', | |
| 'CCSHARED': '--sc-ccshared', | |
| 'LDSHARED': 'sc_ldshared', | |
| 'SHLIB_SUFFIX': 'sc_shutil_suffix', | |
| # On macOS, disable _osx_support.customize_compiler() | |
| 'CUSTOMIZED_OSX_COMPILER': 'True', | |
| } | |
| comp = compiler() | |
| with contextlib.ExitStack() as cm: | |
| for key, value in sysconfig_vars.items(): | |
| cm.enter_context(swap_item(sysconfig._config_vars, key, value)) | |
| sysconfig.customize_compiler(comp) | |
| return comp | |
| def test_customize_compiler(self): | |
| # Make sure that sysconfig._config_vars is initialized | |
| sysconfig.get_config_vars() | |
| os.environ['AR'] = 'env_ar' | |
| os.environ['CC'] = 'env_cc' | |
| os.environ['CPP'] = 'env_cpp' | |
| os.environ['CXX'] = 'env_cxx --env-cxx-flags' | |
| os.environ['LDSHARED'] = 'env_ldshared' | |
| os.environ['LDFLAGS'] = '--env-ldflags' | |
| os.environ['ARFLAGS'] = '--env-arflags' | |
| os.environ['CFLAGS'] = '--env-cflags' | |
| os.environ['CPPFLAGS'] = '--env-cppflags' | |
| comp = self.customize_compiler() | |
| self.assertEqual(comp.exes['archiver'], | |
| 'env_ar --env-arflags') | |
| self.assertEqual(comp.exes['preprocessor'], | |
| 'env_cpp --env-cppflags') | |
| self.assertEqual(comp.exes['compiler'], | |
| 'env_cc --sc-cflags --env-cflags --env-cppflags') | |
| self.assertEqual(comp.exes['compiler_so'], | |
| ('env_cc --sc-cflags ' | |
| '--env-cflags ''--env-cppflags --sc-ccshared')) | |
| self.assertEqual(comp.exes['compiler_cxx'], | |
| 'env_cxx --env-cxx-flags') | |
| self.assertEqual(comp.exes['linker_exe'], | |
| 'env_cc') | |
| self.assertEqual(comp.exes['linker_so'], | |
| ('env_ldshared --env-ldflags --env-cflags' | |
| ' --env-cppflags')) | |
| self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') | |
| del os.environ['AR'] | |
| del os.environ['CC'] | |
| del os.environ['CPP'] | |
| del os.environ['CXX'] | |
| del os.environ['LDSHARED'] | |
| del os.environ['LDFLAGS'] | |
| del os.environ['ARFLAGS'] | |
| del os.environ['CFLAGS'] | |
| del os.environ['CPPFLAGS'] | |
| comp = self.customize_compiler() | |
| self.assertEqual(comp.exes['archiver'], | |
| 'sc_ar --sc-arflags') | |
| self.assertEqual(comp.exes['preprocessor'], | |
| 'sc_cc -E') | |
| self.assertEqual(comp.exes['compiler'], | |
| 'sc_cc --sc-cflags') | |
| self.assertEqual(comp.exes['compiler_so'], | |
| 'sc_cc --sc-cflags --sc-ccshared') | |
| self.assertEqual(comp.exes['compiler_cxx'], | |
| 'sc_cxx') | |
| self.assertEqual(comp.exes['linker_exe'], | |
| 'sc_cc') | |
| self.assertEqual(comp.exes['linker_so'], | |
| 'sc_ldshared') | |
| self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') | |
| def test_parse_makefile_base(self): | |
| self.makefile = TESTFN | |
| fd = open(self.makefile, 'w') | |
| try: | |
| fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB'" '\n') | |
| fd.write('VAR=$OTHER\nOTHER=foo') | |
| finally: | |
| fd.close() | |
| d = sysconfig.parse_makefile(self.makefile) | |
| self.assertEqual(d, {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'", | |
| 'OTHER': 'foo'}) | |
| def test_parse_makefile_literal_dollar(self): | |
| self.makefile = TESTFN | |
| fd = open(self.makefile, 'w') | |
| try: | |
| fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=\$$LIB'" '\n') | |
| fd.write('VAR=$OTHER\nOTHER=foo') | |
| finally: | |
| fd.close() | |
| d = sysconfig.parse_makefile(self.makefile) | |
| self.assertEqual(d, {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'", | |
| 'OTHER': 'foo'}) | |
| def test_sysconfig_module(self): | |
| import sysconfig as global_sysconfig | |
| self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), | |
| sysconfig.get_config_var('CFLAGS')) | |
| self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), | |
| sysconfig.get_config_var('LDFLAGS')) | |
| def test_sysconfig_compiler_vars(self): | |
| # On OS X, binary installers support extension module building on | |
| # various levels of the operating system with differing Xcode | |
| # configurations. This requires customization of some of the | |
| # compiler configuration directives to suit the environment on | |
| # the installed machine. Some of these customizations may require | |
| # running external programs and, so, are deferred until needed by | |
| # the first extension module build. With Python 3.3, only | |
| # the Distutils version of sysconfig is used for extension module | |
| # builds, which happens earlier in the Distutils tests. This may | |
| # cause the following tests to fail since no tests have caused | |
| # the global version of sysconfig to call the customization yet. | |
| # The solution for now is to simply skip this test in this case. | |
| # The longer-term solution is to only have one version of sysconfig. | |
| import sysconfig as global_sysconfig | |
| if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): | |
| self.skipTest('compiler flags customized') | |
| self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), | |
| sysconfig.get_config_var('LDSHARED')) | |
| self.assertEqual(global_sysconfig.get_config_var('CC'), | |
| sysconfig.get_config_var('CC')) | |
| def test_customize_compiler_before_get_config_vars(self): | |
| # Issue #21923: test that a Distribution compiler | |
| # instance can be called without an explicit call to | |
| # get_config_vars(). | |
| with open(TESTFN, 'w') as f: | |
| f.writelines(textwrap.dedent('''\ | |
| from distutils.core import Distribution | |
| config = Distribution().get_command_obj('config') | |
| # try_compile may pass or it may fail if no compiler | |
| # is found but it should not raise an exception. | |
| rc = config.try_compile('int x;') | |
| ''')) | |
| p = subprocess.Popen([str(sys.executable), TESTFN], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.STDOUT, | |
| universal_newlines=True) | |
| outs, errs = p.communicate() | |
| self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) | |
| def test_suite(): | |
| suite = unittest.TestSuite() | |
| suite.addTest(unittest.TestLoader().loadTestsFromTestCase(SysconfigTestCase)) | |
| return suite | |
| if __name__ == '__main__': | |
| run_unittest(test_suite()) | |