(root)/
Python-3.11.7/
Lib/
test/
test__osx_support.py
       1  """
       2  Test suite for _osx_support: shared OS X support functions.
       3  """
       4  
       5  import os
       6  import platform
       7  import stat
       8  import sys
       9  import unittest
      10  
      11  from test.support import os_helper
      12  
      13  import _osx_support
      14  
      15  @unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
      16  class ESC[4;38;5;81mTest_OSXSupport(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      17  
      18      def setUp(self):
      19          self.maxDiff = None
      20          self.prog_name = 'bogus_program_xxxx'
      21          self.temp_path_dir = os.path.abspath(os.getcwd())
      22          self.env = self.enterContext(os_helper.EnvironmentVarGuard())
      23          for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
      24                              'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
      25                              'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
      26                              'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
      27              if cv in self.env:
      28                  self.env.unset(cv)
      29  
      30      def add_expected_saved_initial_values(self, config_vars, expected_vars):
      31          # Ensure that the initial values for all modified config vars
      32          # are also saved with modified keys.
      33          expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
      34                  config_vars[k]) for k in config_vars
      35                      if config_vars[k] != expected_vars[k])
      36  
      37      def test__find_executable(self):
      38          if self.env['PATH']:
      39              self.env['PATH'] = self.env['PATH'] + ':'
      40          self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
      41          os_helper.unlink(self.prog_name)
      42          self.assertIsNone(_osx_support._find_executable(self.prog_name))
      43          self.addCleanup(os_helper.unlink, self.prog_name)
      44          with open(self.prog_name, 'w') as f:
      45              f.write("#!/bin/sh\n/bin/echo OK\n")
      46          os.chmod(self.prog_name, stat.S_IRWXU)
      47          self.assertEqual(self.prog_name,
      48                              _osx_support._find_executable(self.prog_name))
      49  
      50      def test__read_output(self):
      51          if self.env['PATH']:
      52              self.env['PATH'] = self.env['PATH'] + ':'
      53          self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
      54          os_helper.unlink(self.prog_name)
      55          self.addCleanup(os_helper.unlink, self.prog_name)
      56          with open(self.prog_name, 'w') as f:
      57              f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
      58          os.chmod(self.prog_name, stat.S_IRWXU)
      59          self.assertEqual('ExpectedOutput',
      60                              _osx_support._read_output(self.prog_name))
      61  
      62      def test__find_build_tool(self):
      63          out = _osx_support._find_build_tool('cc')
      64          self.assertTrue(os.path.isfile(out),
      65                              'cc not found - check xcode-select')
      66  
      67      def test__get_system_version(self):
      68          self.assertTrue(platform.mac_ver()[0].startswith(
      69                                      _osx_support._get_system_version()))
      70  
      71      def test__remove_original_values(self):
      72          config_vars = {
      73          'CC': 'gcc-test -pthreads',
      74          }
      75          expected_vars = {
      76          'CC': 'clang -pthreads',
      77          }
      78          cv = 'CC'
      79          newvalue = 'clang -pthreads'
      80          _osx_support._save_modified_value(config_vars, cv, newvalue)
      81          self.assertNotEqual(expected_vars, config_vars)
      82          _osx_support._remove_original_values(config_vars)
      83          self.assertEqual(expected_vars, config_vars)
      84  
      85      def test__save_modified_value(self):
      86          config_vars = {
      87          'CC': 'gcc-test -pthreads',
      88          }
      89          expected_vars = {
      90          'CC': 'clang -pthreads',
      91          }
      92          self.add_expected_saved_initial_values(config_vars, expected_vars)
      93          cv = 'CC'
      94          newvalue = 'clang -pthreads'
      95          _osx_support._save_modified_value(config_vars, cv, newvalue)
      96          self.assertEqual(expected_vars, config_vars)
      97  
      98      def test__save_modified_value_unchanged(self):
      99          config_vars = {
     100          'CC': 'gcc-test -pthreads',
     101          }
     102          expected_vars = config_vars.copy()
     103          cv = 'CC'
     104          newvalue = 'gcc-test -pthreads'
     105          _osx_support._save_modified_value(config_vars, cv, newvalue)
     106          self.assertEqual(expected_vars, config_vars)
     107  
     108      def test__supports_universal_builds(self):
     109          import platform
     110          mac_ver_tuple = tuple(int(i) for i in
     111                              platform.mac_ver()[0].split('.')[0:2])
     112          self.assertEqual(mac_ver_tuple >= (10, 4),
     113                              _osx_support._supports_universal_builds())
     114  
     115      def test__find_appropriate_compiler(self):
     116          compilers = (
     117                          ('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
     118                          ('clang', 'clang version 3.1'),
     119                      )
     120          config_vars = {
     121          'CC': 'gcc-test -pthreads',
     122          'CXX': 'cc++-test',
     123          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     124          'LDFLAGS': '-arch ppc -arch i386   -g',
     125          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     126          'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
     127          'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
     128                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     129          }
     130          expected_vars = {
     131          'CC': 'clang -pthreads',
     132          'CXX': 'clang++',
     133          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     134          'LDFLAGS': '-arch ppc -arch i386   -g',
     135          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     136          'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
     137          'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
     138                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     139          }
     140          self.add_expected_saved_initial_values(config_vars, expected_vars)
     141  
     142          suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
     143          self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
     144          for c_name, c_output in compilers:
     145              os_helper.unlink(c_name)
     146              self.addCleanup(os_helper.unlink, c_name)
     147              with open(c_name, 'w') as f:
     148                  f.write("#!/bin/sh\n/bin/echo " + c_output)
     149              os.chmod(c_name, stat.S_IRWXU)
     150          self.assertEqual(expected_vars,
     151                              _osx_support._find_appropriate_compiler(
     152                                      config_vars))
     153  
     154      def test__remove_universal_flags(self):
     155          config_vars = {
     156          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     157          'LDFLAGS': '-arch ppc -arch i386   -g',
     158          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     159          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     160          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     161                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     162          }
     163          expected_vars = {
     164          'CFLAGS': '-fno-strict-aliasing  -g -O3    ',
     165          'LDFLAGS': '    -g',
     166          'CPPFLAGS': '-I.  ',
     167          'BLDSHARED': 'gcc-4.0 -bundle    -g',
     168          'LDSHARED': 'gcc-4.0 -bundle      -g',
     169          }
     170          self.add_expected_saved_initial_values(config_vars, expected_vars)
     171  
     172          self.assertEqual(expected_vars,
     173                              _osx_support._remove_universal_flags(
     174                                      config_vars))
     175  
     176      def test__remove_universal_flags_alternate(self):
     177          # bpo-38360: also test the alternate single-argument form of -isysroot
     178          config_vars = {
     179          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     180          'LDFLAGS': '-arch ppc -arch i386   -g',
     181          'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
     182          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     183          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     184                          '-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
     185          }
     186          expected_vars = {
     187          'CFLAGS': '-fno-strict-aliasing  -g -O3    ',
     188          'LDFLAGS': '    -g',
     189          'CPPFLAGS': '-I.  ',
     190          'BLDSHARED': 'gcc-4.0 -bundle    -g',
     191          'LDSHARED': 'gcc-4.0 -bundle      -g',
     192          }
     193          self.add_expected_saved_initial_values(config_vars, expected_vars)
     194  
     195          self.assertEqual(expected_vars,
     196                              _osx_support._remove_universal_flags(
     197                                      config_vars))
     198  
     199      def test__remove_unsupported_archs(self):
     200          config_vars = {
     201          'CC': 'clang',
     202          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     203          'LDFLAGS': '-arch ppc -arch i386   -g',
     204          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     205          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     206          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     207                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     208          }
     209          expected_vars = {
     210          'CC': 'clang',
     211          'CFLAGS': '-fno-strict-aliasing  -g -O3  -arch i386  ',
     212          'LDFLAGS': ' -arch i386   -g',
     213          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     214          'BLDSHARED': 'gcc-4.0 -bundle   -arch i386 -g',
     215          'LDSHARED': 'gcc-4.0 -bundle   -arch i386 '
     216                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     217          }
     218          self.add_expected_saved_initial_values(config_vars, expected_vars)
     219  
     220          suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
     221          self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
     222          c_name = 'clang'
     223          os_helper.unlink(c_name)
     224          self.addCleanup(os_helper.unlink, c_name)
     225          # exit status 255 means no PPC support in this compiler chain
     226          with open(c_name, 'w') as f:
     227              f.write("#!/bin/sh\nexit 255")
     228          os.chmod(c_name, stat.S_IRWXU)
     229          self.assertEqual(expected_vars,
     230                              _osx_support._remove_unsupported_archs(
     231                                      config_vars))
     232  
     233      def test__override_all_archs(self):
     234          self.env['ARCHFLAGS'] = '-arch x86_64'
     235          config_vars = {
     236          'CC': 'clang',
     237          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
     238          'LDFLAGS': '-arch ppc -arch i386   -g',
     239          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     240          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     241          'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
     242                          '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
     243          }
     244          expected_vars = {
     245          'CC': 'clang',
     246          'CFLAGS': '-fno-strict-aliasing  -g -O3     -arch x86_64',
     247          'LDFLAGS': '    -g -arch x86_64',
     248          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
     249          'BLDSHARED': 'gcc-4.0 -bundle    -g -arch x86_64',
     250          'LDSHARED': 'gcc-4.0 -bundle   -isysroot '
     251                          '/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
     252          }
     253          self.add_expected_saved_initial_values(config_vars, expected_vars)
     254  
     255          self.assertEqual(expected_vars,
     256                              _osx_support._override_all_archs(
     257                                      config_vars))
     258  
     259      def test__check_for_unavailable_sdk(self):
     260          config_vars = {
     261          'CC': 'clang',
     262          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
     263                          '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
     264          'LDFLAGS': '-arch ppc -arch i386   -g',
     265          'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
     266          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     267          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     268                          '-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
     269          }
     270          expected_vars = {
     271          'CC': 'clang',
     272          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
     273                          ' ',
     274          'LDFLAGS': '-arch ppc -arch i386   -g',
     275          'CPPFLAGS': '-I.  ',
     276          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     277          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     278                          ' -g',
     279          }
     280          self.add_expected_saved_initial_values(config_vars, expected_vars)
     281  
     282          self.assertEqual(expected_vars,
     283                              _osx_support._check_for_unavailable_sdk(
     284                                      config_vars))
     285  
     286      def test__check_for_unavailable_sdk_alternate(self):
     287          # bpo-38360: also test the alternate single-argument form of -isysroot
     288          config_vars = {
     289          'CC': 'clang',
     290          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
     291                          '-isysroot/Developer/SDKs/MacOSX10.1.sdk',
     292          'LDFLAGS': '-arch ppc -arch i386   -g',
     293          'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
     294          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     295          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     296                          '-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
     297          }
     298          expected_vars = {
     299          'CC': 'clang',
     300          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
     301                          ' ',
     302          'LDFLAGS': '-arch ppc -arch i386   -g',
     303          'CPPFLAGS': '-I.  ',
     304          'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
     305          'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
     306                          ' -g',
     307          }
     308          self.add_expected_saved_initial_values(config_vars, expected_vars)
     309  
     310          self.assertEqual(expected_vars,
     311                              _osx_support._check_for_unavailable_sdk(
     312                                      config_vars))
     313  
     314      def test_get_platform_osx(self):
     315          # Note, get_platform_osx is currently tested more extensively
     316          # indirectly by test_sysconfig and test_distutils
     317          config_vars = {
     318          'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
     319                          '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
     320          'MACOSX_DEPLOYMENT_TARGET': '10.6',
     321          }
     322          result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
     323          self.assertEqual(('macosx', '10.6', 'fat'), result)
     324  
     325  if __name__ == "__main__":
     326      unittest.main()