1"""Tests for distutils.sysconfig."""
2import os
3import test
4import unittest
5import shutil
6import subprocess
7import sys
8import textwrap
9
10from distutils import sysconfig
11from distutils.tests import support
12from test.test_support import TESTFN
13
14class SysconfigTestCase(support.EnvironGuard,
15                        unittest.TestCase):
16    def setUp(self):
17        super(SysconfigTestCase, self).setUp()
18        self.makefile = None
19
20    def tearDown(self):
21        if self.makefile is not None:
22            os.unlink(self.makefile)
23        self.cleanup_testfn()
24        super(SysconfigTestCase, self).tearDown()
25
26    def cleanup_testfn(self):
27        path = test.test_support.TESTFN
28        if os.path.isfile(path):
29            os.remove(path)
30        elif os.path.isdir(path):
31            shutil.rmtree(path)
32
33    def test_get_python_lib(self):
34        lib_dir = sysconfig.get_python_lib()
35        # XXX doesn't work on Linux when Python was never installed before
36        #self.assertTrue(os.path.isdir(lib_dir), lib_dir)
37        # test for pythonxx.lib?
38        self.assertNotEqual(sysconfig.get_python_lib(),
39                            sysconfig.get_python_lib(prefix=TESTFN))
40        _sysconfig = __import__('sysconfig')
41        res = sysconfig.get_python_lib(True, True)
42        self.assertEqual(_sysconfig.get_path('platstdlib'), res)
43
44    def test_get_python_inc(self):
45        inc_dir = sysconfig.get_python_inc()
46        # This is not much of a test.  We make sure Python.h exists
47        # in the directory returned by get_python_inc() but we don't know
48        # it is the correct file.
49        self.assertTrue(os.path.isdir(inc_dir), inc_dir)
50        python_h = os.path.join(inc_dir, "Python.h")
51        self.assertTrue(os.path.isfile(python_h), python_h)
52
53    def test_parse_makefile_base(self):
54        self.makefile = test.test_support.TESTFN
55        fd = open(self.makefile, 'w')
56        try:
57            fd.write(r"CONFIG_ARGS=  '--arg1=optarg1' 'ENV=LIB'" '\n')
58            fd.write('VAR=$OTHER\nOTHER=foo')
59        finally:
60            fd.close()
61        d = sysconfig.parse_makefile(self.makefile)
62        self.assertEqual(d, {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'",
63                             'OTHER': 'foo'})
64
65    def test_parse_makefile_literal_dollar(self):
66        self.makefile = test.test_support.TESTFN
67        fd = open(self.makefile, 'w')
68        try:
69            fd.write(r"CONFIG_ARGS=  '--arg1=optarg1' 'ENV=\$$LIB'" '\n')
70            fd.write('VAR=$OTHER\nOTHER=foo')
71        finally:
72            fd.close()
73        d = sysconfig.parse_makefile(self.makefile)
74        self.assertEqual(d, {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'",
75                             'OTHER': 'foo'})
76
77
78    def test_sysconfig_module(self):
79        import sysconfig as global_sysconfig
80        self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), sysconfig.get_config_var('CFLAGS'))
81        self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), sysconfig.get_config_var('LDFLAGS'))
82
83    @unittest.skipIf(sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'),'compiler flags customized')
84    def test_sysconfig_compiler_vars(self):
85        # On OS X, binary installers support extension module building on
86        # various levels of the operating system with differing Xcode
87        # configurations.  This requires customization of some of the
88        # compiler configuration directives to suit the environment on
89        # the installed machine.  Some of these customizations may require
90        # running external programs and, so, are deferred until needed by
91        # the first extension module build.  With Python 3.3, only
92        # the Distutils version of sysconfig is used for extension module
93        # builds, which happens earlier in the Distutils tests.  This may
94        # cause the following tests to fail since no tests have caused
95        # the global version of sysconfig to call the customization yet.
96        # The solution for now is to simply skip this test in this case.
97        # The longer-term solution is to only have one version of sysconfig.
98
99        import sysconfig as global_sysconfig
100        if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'):
101            self.skipTest('compiler flags customized')
102        self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), sysconfig.get_config_var('LDSHARED'))
103        self.assertEqual(global_sysconfig.get_config_var('CC'), sysconfig.get_config_var('CC'))
104
105    def test_customize_compiler_before_get_config_vars(self):
106        # Issue #21923: test that a Distribution compiler
107        # instance can be called without an explicit call to
108        # get_config_vars().
109        with open(TESTFN, 'w') as f:
110            f.writelines(textwrap.dedent('''\
111                from distutils.core import Distribution
112                config = Distribution().get_command_obj('config')
113                # try_compile may pass or it may fail if no compiler
114                # is found but it should not raise an exception.
115                rc = config.try_compile('int x;')
116                '''))
117        p = subprocess.Popen([str(sys.executable), TESTFN],
118                stdout=subprocess.PIPE,
119                stderr=subprocess.STDOUT,
120                universal_newlines=True)
121        outs, errs = p.communicate()
122        self.assertEqual(0, p.returncode, "Subprocess failed: " + outs)
123
124
125def test_suite():
126    suite = unittest.TestSuite()
127    suite.addTest(unittest.makeSuite(SysconfigTestCase))
128    return suite
129
130
131if __name__ == '__main__':
132    test.test_support.run_unittest(test_suite())
133