python (3.12.0)

(root)/
lib/
python3.12/
test/
test_sysconfig.py
       1  import unittest
       2  import sys
       3  import os
       4  import subprocess
       5  import shutil
       6  from copy import copy
       7  
       8  from test.support import (
       9      captured_stdout, PythonSymlink, requires_subprocess, is_wasi
      10  )
      11  from test.support.import_helper import import_module
      12  from test.support.os_helper import (TESTFN, unlink, skip_unless_symlink,
      13                                      change_cwd)
      14  
      15  import sysconfig
      16  from sysconfig import (get_paths, get_platform, get_config_vars,
      17                         get_path, get_path_names, _INSTALL_SCHEMES,
      18                         get_default_scheme, get_scheme_names, get_config_var,
      19                         _expand_vars, _get_preferred_schemes, _main)
      20  import _osx_support
      21  
      22  
      23  HAS_USER_BASE = sysconfig._HAS_USER_BASE
      24  
      25  
      26  class ESC[4;38;5;81mTestSysConfig(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      27  
      28      def setUp(self):
      29          super(TestSysConfig, self).setUp()
      30          self.sys_path = sys.path[:]
      31          # patching os.uname
      32          if hasattr(os, 'uname'):
      33              self.uname = os.uname
      34              self._uname = os.uname()
      35          else:
      36              self.uname = None
      37              self._set_uname(('',)*5)
      38          os.uname = self._get_uname
      39          # saving the environment
      40          self.name = os.name
      41          self.platform = sys.platform
      42          self.version = sys.version
      43          self.sep = os.sep
      44          self.join = os.path.join
      45          self.isabs = os.path.isabs
      46          self.splitdrive = os.path.splitdrive
      47          self._config_vars = sysconfig._CONFIG_VARS, copy(sysconfig._CONFIG_VARS)
      48          self._added_envvars = []
      49          self._changed_envvars = []
      50          for var in ('MACOSX_DEPLOYMENT_TARGET', 'PATH'):
      51              if var in os.environ:
      52                  self._changed_envvars.append((var, os.environ[var]))
      53              else:
      54                  self._added_envvars.append(var)
      55  
      56      def tearDown(self):
      57          sys.path[:] = self.sys_path
      58          self._cleanup_testfn()
      59          if self.uname is not None:
      60              os.uname = self.uname
      61          else:
      62              del os.uname
      63          os.name = self.name
      64          sys.platform = self.platform
      65          sys.version = self.version
      66          os.sep = self.sep
      67          os.path.join = self.join
      68          os.path.isabs = self.isabs
      69          os.path.splitdrive = self.splitdrive
      70          sysconfig._CONFIG_VARS = self._config_vars[0]
      71          sysconfig._CONFIG_VARS.clear()
      72          sysconfig._CONFIG_VARS.update(self._config_vars[1])
      73          for var, value in self._changed_envvars:
      74              os.environ[var] = value
      75          for var in self._added_envvars:
      76              os.environ.pop(var, None)
      77  
      78          super(TestSysConfig, self).tearDown()
      79  
      80      def _set_uname(self, uname):
      81          self._uname = os.uname_result(uname)
      82  
      83      def _get_uname(self):
      84          return self._uname
      85  
      86      def _cleanup_testfn(self):
      87          path = TESTFN
      88          if os.path.isfile(path):
      89              os.remove(path)
      90          elif os.path.isdir(path):
      91              shutil.rmtree(path)
      92  
      93      def test_get_path_names(self):
      94          self.assertEqual(get_path_names(), sysconfig._SCHEME_KEYS)
      95  
      96      def test_get_paths(self):
      97          scheme = get_paths()
      98          default_scheme = get_default_scheme()
      99          wanted = _expand_vars(default_scheme, None)
     100          wanted = sorted(wanted.items())
     101          scheme = sorted(scheme.items())
     102          self.assertEqual(scheme, wanted)
     103  
     104      def test_get_path(self):
     105          config_vars = get_config_vars()
     106          if os.name == 'nt':
     107              # On Windows, we replace the native platlibdir name with the
     108              # default so that POSIX schemes resolve correctly
     109              config_vars = config_vars | {'platlibdir': 'lib'}
     110          for scheme in _INSTALL_SCHEMES:
     111              for name in _INSTALL_SCHEMES[scheme]:
     112                  expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
     113                  self.assertEqual(
     114                      os.path.normpath(get_path(name, scheme)),
     115                      os.path.normpath(expected),
     116                  )
     117  
     118      def test_get_default_scheme(self):
     119          self.assertIn(get_default_scheme(), _INSTALL_SCHEMES)
     120  
     121      def test_get_preferred_schemes(self):
     122          expected_schemes = {'prefix', 'home', 'user'}
     123  
     124          # Windows.
     125          os.name = 'nt'
     126          schemes = _get_preferred_schemes()
     127          self.assertIsInstance(schemes, dict)
     128          self.assertEqual(set(schemes), expected_schemes)
     129  
     130          # Mac and Linux, shared library build.
     131          os.name = 'posix'
     132          schemes = _get_preferred_schemes()
     133          self.assertIsInstance(schemes, dict)
     134          self.assertEqual(set(schemes), expected_schemes)
     135  
     136          # Mac, framework build.
     137          os.name = 'posix'
     138          sys.platform = 'darwin'
     139          sys._framework = True
     140          self.assertIsInstance(schemes, dict)
     141          self.assertEqual(set(schemes), expected_schemes)
     142  
     143      def test_posix_venv_scheme(self):
     144          # The following directories were hardcoded in the venv module
     145          # before bpo-45413, here we assert the posix_venv scheme does not regress
     146          binpath = 'bin'
     147          incpath = 'include'
     148          libpath = os.path.join('lib',
     149                                 'python%d.%d' % sys.version_info[:2],
     150                                 'site-packages')
     151  
     152          # Resolve the paths in prefix
     153          binpath = os.path.join(sys.prefix, binpath)
     154          incpath = os.path.join(sys.prefix, incpath)
     155          libpath = os.path.join(sys.prefix, libpath)
     156  
     157          self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='posix_venv'))
     158          self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='posix_venv'))
     159  
     160          # The include directory on POSIX isn't exactly the same as before,
     161          # but it is "within"
     162          sysconfig_includedir = sysconfig.get_path('include', scheme='posix_venv')
     163          self.assertTrue(sysconfig_includedir.startswith(incpath + os.sep))
     164  
     165      def test_nt_venv_scheme(self):
     166          # The following directories were hardcoded in the venv module
     167          # before bpo-45413, here we assert the posix_venv scheme does not regress
     168          binpath = 'Scripts'
     169          incpath = 'Include'
     170          libpath = os.path.join('Lib', 'site-packages')
     171  
     172          # Resolve the paths in prefix
     173          binpath = os.path.join(sys.prefix, binpath)
     174          incpath = os.path.join(sys.prefix, incpath)
     175          libpath = os.path.join(sys.prefix, libpath)
     176  
     177          self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='nt_venv'))
     178          self.assertEqual(incpath, sysconfig.get_path('include', scheme='nt_venv'))
     179          self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv'))
     180  
     181      def test_venv_scheme(self):
     182          if sys.platform == 'win32':
     183              self.assertEqual(
     184                  sysconfig.get_path('scripts', scheme='venv'),
     185                  sysconfig.get_path('scripts', scheme='nt_venv')
     186              )
     187              self.assertEqual(
     188                  sysconfig.get_path('include', scheme='venv'),
     189                  sysconfig.get_path('include', scheme='nt_venv')
     190              )
     191              self.assertEqual(
     192                  sysconfig.get_path('purelib', scheme='venv'),
     193                  sysconfig.get_path('purelib', scheme='nt_venv')
     194              )
     195          else:
     196              self.assertEqual(
     197                  sysconfig.get_path('scripts', scheme='venv'),
     198                  sysconfig.get_path('scripts', scheme='posix_venv')
     199              )
     200              self.assertEqual(
     201                  sysconfig.get_path('include', scheme='venv'),
     202                  sysconfig.get_path('include', scheme='posix_venv')
     203              )
     204              self.assertEqual(
     205                  sysconfig.get_path('purelib', scheme='venv'),
     206                  sysconfig.get_path('purelib', scheme='posix_venv')
     207              )
     208  
     209      def test_get_config_vars(self):
     210          cvars = get_config_vars()
     211          self.assertIsInstance(cvars, dict)
     212          self.assertTrue(cvars)
     213  
     214      def test_get_platform(self):
     215          # windows XP, 32bits
     216          os.name = 'nt'
     217          sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
     218                         '[MSC v.1310 32 bit (Intel)]')
     219          sys.platform = 'win32'
     220          self.assertEqual(get_platform(), 'win32')
     221  
     222          # windows XP, amd64
     223          os.name = 'nt'
     224          sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
     225                         '[MSC v.1310 32 bit (Amd64)]')
     226          sys.platform = 'win32'
     227          self.assertEqual(get_platform(), 'win-amd64')
     228  
     229          # macbook
     230          os.name = 'posix'
     231          sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) '
     232                         '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]')
     233          sys.platform = 'darwin'
     234          self._set_uname(('Darwin', 'macziade', '8.11.1',
     235                     ('Darwin Kernel Version 8.11.1: '
     236                      'Wed Oct 10 18:23:28 PDT 2007; '
     237                      'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC'))
     238          _osx_support._remove_original_values(get_config_vars())
     239          get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
     240  
     241          get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
     242                                         '-fwrapv -O3 -Wall -Wstrict-prototypes')
     243  
     244          maxint = sys.maxsize
     245          try:
     246              sys.maxsize = 2147483647
     247              self.assertEqual(get_platform(), 'macosx-10.3-ppc')
     248              sys.maxsize = 9223372036854775807
     249              self.assertEqual(get_platform(), 'macosx-10.3-ppc64')
     250          finally:
     251              sys.maxsize = maxint
     252  
     253          self._set_uname(('Darwin', 'macziade', '8.11.1',
     254                     ('Darwin Kernel Version 8.11.1: '
     255                      'Wed Oct 10 18:23:28 PDT 2007; '
     256                      'root:xnu-792.25.20~1/RELEASE_I386'), 'i386'))
     257          _osx_support._remove_original_values(get_config_vars())
     258          get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
     259  
     260          get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
     261                                         '-fwrapv -O3 -Wall -Wstrict-prototypes')
     262          maxint = sys.maxsize
     263          try:
     264              sys.maxsize = 2147483647
     265              self.assertEqual(get_platform(), 'macosx-10.3-i386')
     266              sys.maxsize = 9223372036854775807
     267              self.assertEqual(get_platform(), 'macosx-10.3-x86_64')
     268          finally:
     269              sys.maxsize = maxint
     270  
     271          # macbook with fat binaries (fat, universal or fat64)
     272          _osx_support._remove_original_values(get_config_vars())
     273          get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
     274          get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot '
     275                                         '/Developer/SDKs/MacOSX10.4u.sdk  '
     276                                         '-fno-strict-aliasing -fno-common '
     277                                         '-dynamic -DNDEBUG -g -O3')
     278  
     279          self.assertEqual(get_platform(), 'macosx-10.4-fat')
     280  
     281          _osx_support._remove_original_values(get_config_vars())
     282          get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot '
     283                                         '/Developer/SDKs/MacOSX10.4u.sdk  '
     284                                         '-fno-strict-aliasing -fno-common '
     285                                         '-dynamic -DNDEBUG -g -O3')
     286  
     287          self.assertEqual(get_platform(), 'macosx-10.4-intel')
     288  
     289          _osx_support._remove_original_values(get_config_vars())
     290          get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot '
     291                                         '/Developer/SDKs/MacOSX10.4u.sdk  '
     292                                         '-fno-strict-aliasing -fno-common '
     293                                         '-dynamic -DNDEBUG -g -O3')
     294          self.assertEqual(get_platform(), 'macosx-10.4-fat3')
     295  
     296          _osx_support._remove_original_values(get_config_vars())
     297          get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot '
     298                                         '/Developer/SDKs/MacOSX10.4u.sdk  '
     299                                         '-fno-strict-aliasing -fno-common '
     300                                         '-dynamic -DNDEBUG -g -O3')
     301          self.assertEqual(get_platform(), 'macosx-10.4-universal')
     302  
     303          _osx_support._remove_original_values(get_config_vars())
     304          get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot '
     305                                         '/Developer/SDKs/MacOSX10.4u.sdk  '
     306                                         '-fno-strict-aliasing -fno-common '
     307                                         '-dynamic -DNDEBUG -g -O3')
     308  
     309          self.assertEqual(get_platform(), 'macosx-10.4-fat64')
     310  
     311          for arch in ('ppc', 'i386', 'x86_64', 'ppc64'):
     312              _osx_support._remove_original_values(get_config_vars())
     313              get_config_vars()['CFLAGS'] = ('-arch %s -isysroot '
     314                                             '/Developer/SDKs/MacOSX10.4u.sdk  '
     315                                             '-fno-strict-aliasing -fno-common '
     316                                             '-dynamic -DNDEBUG -g -O3' % arch)
     317  
     318              self.assertEqual(get_platform(), 'macosx-10.4-%s' % arch)
     319  
     320          # linux debian sarge
     321          os.name = 'posix'
     322          sys.version = ('2.3.5 (#1, Jul  4 2007, 17:28:59) '
     323                         '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]')
     324          sys.platform = 'linux2'
     325          self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7',
     326                      '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686'))
     327  
     328          self.assertEqual(get_platform(), 'linux-i686')
     329  
     330          # XXX more platforms to tests here
     331  
     332      @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
     333      def test_get_config_h_filename(self):
     334          config_h = sysconfig.get_config_h_filename()
     335          self.assertTrue(os.path.isfile(config_h), config_h)
     336  
     337      def test_get_scheme_names(self):
     338          wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv']
     339          if HAS_USER_BASE:
     340              wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
     341          self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
     342  
     343      @skip_unless_symlink
     344      @requires_subprocess()
     345      def test_symlink(self): # Issue 7880
     346          with PythonSymlink() as py:
     347              cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
     348              self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
     349  
     350      def test_user_similar(self):
     351          # Issue #8759: make sure the posix scheme for the users
     352          # is similar to the global posix_prefix one
     353          base = get_config_var('base')
     354          if HAS_USER_BASE:
     355              user = get_config_var('userbase')
     356          # the global scheme mirrors the distinction between prefix and
     357          # exec-prefix but not the user scheme, so we have to adapt the paths
     358          # before comparing (issue #9100)
     359          adapt = sys.base_prefix != sys.base_exec_prefix
     360          for name in ('stdlib', 'platstdlib', 'purelib', 'platlib'):
     361              global_path = get_path(name, 'posix_prefix')
     362              if adapt:
     363                  global_path = global_path.replace(sys.exec_prefix, sys.base_prefix)
     364                  base = base.replace(sys.exec_prefix, sys.base_prefix)
     365              elif sys.base_prefix != sys.prefix:
     366                  # virtual environment? Likewise, we have to adapt the paths
     367                  # before comparing
     368                  global_path = global_path.replace(sys.base_prefix, sys.prefix)
     369                  base = base.replace(sys.base_prefix, sys.prefix)
     370              if HAS_USER_BASE:
     371                  user_path = get_path(name, 'posix_user')
     372                  expected = os.path.normpath(global_path.replace(base, user, 1))
     373                  # bpo-44860: platlib of posix_user doesn't use sys.platlibdir,
     374                  # whereas posix_prefix does.
     375                  if name == 'platlib':
     376                      # Replace "/lib64/python3.11/site-packages" suffix
     377                      # with "/lib/python3.11/site-packages".
     378                      py_version_short = sysconfig.get_python_version()
     379                      suffix = f'python{py_version_short}/site-packages'
     380                      expected = expected.replace(f'/{sys.platlibdir}/{suffix}',
     381                                                  f'/lib/{suffix}')
     382                  self.assertEqual(user_path, expected)
     383  
     384      def test_main(self):
     385          # just making sure _main() runs and returns things in the stdout
     386          with captured_stdout() as output:
     387              _main()
     388          self.assertTrue(len(output.getvalue().split('\n')) > 0)
     389  
     390      @unittest.skipIf(sys.platform == "win32", "Does not apply to Windows")
     391      def test_ldshared_value(self):
     392          ldflags = sysconfig.get_config_var('LDFLAGS')
     393          ldshared = sysconfig.get_config_var('LDSHARED')
     394  
     395          self.assertIn(ldflags, ldshared)
     396  
     397      @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX")
     398      @requires_subprocess()
     399      def test_platform_in_subprocess(self):
     400          my_platform = sysconfig.get_platform()
     401  
     402          # Test without MACOSX_DEPLOYMENT_TARGET in the environment
     403  
     404          env = os.environ.copy()
     405          if 'MACOSX_DEPLOYMENT_TARGET' in env:
     406              del env['MACOSX_DEPLOYMENT_TARGET']
     407  
     408          p = subprocess.Popen([
     409                  sys.executable, '-c',
     410                  'import sysconfig; print(sysconfig.get_platform())',
     411              ],
     412              stdout=subprocess.PIPE,
     413              stderr=subprocess.DEVNULL,
     414              env=env)
     415          test_platform = p.communicate()[0].strip()
     416          test_platform = test_platform.decode('utf-8')
     417          status = p.wait()
     418  
     419          self.assertEqual(status, 0)
     420          self.assertEqual(my_platform, test_platform)
     421  
     422          # Test with MACOSX_DEPLOYMENT_TARGET in the environment, and
     423          # using a value that is unlikely to be the default one.
     424          env = os.environ.copy()
     425          env['MACOSX_DEPLOYMENT_TARGET'] = '10.1'
     426  
     427          p = subprocess.Popen([
     428                  sys.executable, '-c',
     429                  'import sysconfig; print(sysconfig.get_platform())',
     430              ],
     431              stdout=subprocess.PIPE,
     432              stderr=subprocess.DEVNULL,
     433              env=env)
     434          test_platform = p.communicate()[0].strip()
     435          test_platform = test_platform.decode('utf-8')
     436          status = p.wait()
     437  
     438          self.assertEqual(status, 0)
     439          self.assertEqual(my_platform, test_platform)
     440  
     441      @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
     442      def test_srcdir(self):
     443          # See Issues #15322, #15364.
     444          srcdir = sysconfig.get_config_var('srcdir')
     445  
     446          self.assertTrue(os.path.isabs(srcdir), srcdir)
     447          self.assertTrue(os.path.isdir(srcdir), srcdir)
     448  
     449          if sysconfig._PYTHON_BUILD:
     450              # The python executable has not been installed so srcdir
     451              # should be a full source checkout.
     452              Python_h = os.path.join(srcdir, 'Include', 'Python.h')
     453              self.assertTrue(os.path.exists(Python_h), Python_h)
     454              # <srcdir>/PC/pyconfig.h always exists even if unused on POSIX.
     455              pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h')
     456              self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h)
     457              pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in')
     458              self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in)
     459          elif os.name == 'posix':
     460              makefile_dir = os.path.dirname(sysconfig.get_makefile_filename())
     461              # Issue #19340: srcdir has been realpath'ed already
     462              makefile_dir = os.path.realpath(makefile_dir)
     463              self.assertEqual(makefile_dir, srcdir)
     464  
     465      def test_srcdir_independent_of_cwd(self):
     466          # srcdir should be independent of the current working directory
     467          # See Issues #15322, #15364.
     468          srcdir = sysconfig.get_config_var('srcdir')
     469          with change_cwd(os.pardir):
     470              srcdir2 = sysconfig.get_config_var('srcdir')
     471          self.assertEqual(srcdir, srcdir2)
     472  
     473      @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None,
     474                       'EXT_SUFFIX required for this test')
     475      def test_EXT_SUFFIX_in_vars(self):
     476          import _imp
     477          if not _imp.extension_suffixes():
     478              self.skipTest("stub loader has no suffixes")
     479          vars = sysconfig.get_config_vars()
     480          self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0])
     481  
     482      @unittest.skipUnless(sys.platform == 'linux' and
     483                           hasattr(sys.implementation, '_multiarch'),
     484                           'multiarch-specific test')
     485      def test_triplet_in_ext_suffix(self):
     486          ctypes = import_module('ctypes')
     487          import platform, re
     488          machine = platform.machine()
     489          suffix = sysconfig.get_config_var('EXT_SUFFIX')
     490          if re.match('(aarch64|arm|mips|ppc|powerpc|s390|sparc)', machine):
     491              self.assertTrue('linux' in suffix, suffix)
     492          if re.match('(i[3-6]86|x86_64)$', machine):
     493              if ctypes.sizeof(ctypes.c_char_p()) == 4:
     494                  expected_suffixes = 'i386-linux-gnu.so', 'x86_64-linux-gnux32.so', 'i386-linux-musl.so'
     495              else: # 8 byte pointer size
     496                  expected_suffixes = 'x86_64-linux-gnu.so', 'x86_64-linux-musl.so'
     497              self.assertTrue(suffix.endswith(expected_suffixes),
     498                              f'unexpected suffix {suffix!r}')
     499  
     500      @unittest.skipUnless(sys.platform == 'darwin', 'OS X-specific test')
     501      def test_osx_ext_suffix(self):
     502          suffix = sysconfig.get_config_var('EXT_SUFFIX')
     503          self.assertTrue(suffix.endswith('-darwin.so'), suffix)
     504  
     505  class ESC[4;38;5;81mMakefileTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     506  
     507      @unittest.skipIf(sys.platform.startswith('win'),
     508                       'Test is not Windows compatible')
     509      @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
     510      def test_get_makefile_filename(self):
     511          makefile = sysconfig.get_makefile_filename()
     512          self.assertTrue(os.path.isfile(makefile), makefile)
     513  
     514      def test_parse_makefile(self):
     515          self.addCleanup(unlink, TESTFN)
     516          with open(TESTFN, "w") as makefile:
     517              print("var1=a$(VAR2)", file=makefile)
     518              print("VAR2=b$(var3)", file=makefile)
     519              print("var3=42", file=makefile)
     520              print("var4=$/invalid", file=makefile)
     521              print("var5=dollar$$5", file=makefile)
     522              print("var6=${var3}/lib/python3.5/config-$(VAR2)$(var5)"
     523                    "-x86_64-linux-gnu", file=makefile)
     524          vars = sysconfig._parse_makefile(TESTFN)
     525          self.assertEqual(vars, {
     526              'var1': 'ab42',
     527              'VAR2': 'b42',
     528              'var3': 42,
     529              'var4': '$/invalid',
     530              'var5': 'dollar$5',
     531              'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
     532          })
     533  
     534  
     535  if __name__ == "__main__":
     536      unittest.main()