import platform
import re
import unittest
import sys
import os
import subprocess
import shutil
import json
import textwrap
from unittest.mock import patch
from copy import copy

from test import support
from test.support import (
    captured_stdout,
    is_android,
    is_apple_mobile,
    is_wasi,
    PythonSymlink,
    requires_subprocess,
)
from test.support.import_helper import import_module
from test.support.os_helper import (TESTFN, unlink, skip_unless_symlink,
                                    change_cwd, EnvironmentVarGuard)
from test.support.venv import VirtualEnvironmentMixin

import sysconfig
from sysconfig import (get_paths, get_platform, get_config_vars,
                       get_path, get_path_names, _INSTALL_SCHEMES,
                       get_default_scheme, get_scheme_names, get_config_var,
                       _expand_vars, _get_preferred_schemes,
                       is_python_build, _PROJECT_BASE)
from sysconfig.__main__ import _main, _parse_makefile, _get_pybuilddir, _get_json_data_name
import _imp
import _osx_support


HAS_USER_BASE = sysconfig._HAS_USER_BASE


class TestSysConfig(unittest.TestCase, VirtualEnvironmentMixin):

    def setUp(self):
        super(TestSysConfig, self).setUp()
        self.maxDiff = None
        self.sys_path = sys.path[:]
        # patching os.uname
        if hasattr(os, 'uname'):
            self.uname = os.uname
            self._uname = os.uname()
        else:
            self.uname = None
            self._set_uname(('',)*5)
        os.uname = self._get_uname
        # saving the environment
        self.name = os.name
        self.prefix = sys.prefix
        self.exec_prefix = sys.exec_prefix
        self.platform = sys.platform
        self.version = sys.version
        self._framework = sys._framework
        self.sep = os.sep
        self.join = os.path.join
        self.isabs = os.path.isabs
        self.splitdrive = os.path.splitdrive
        self._config_vars = sysconfig._CONFIG_VARS, copy(sysconfig._CONFIG_VARS)
        self._added_envvars = []
        self._changed_envvars = []
        for var in ('MACOSX_DEPLOYMENT_TARGET', 'PATH'):
            if var in os.environ:
                self._changed_envvars.append((var, os.environ[var]))
            else:
                self._added_envvars.append(var)

    def tearDown(self):
        sys.path[:] = self.sys_path
        self._cleanup_testfn()
        if self.uname is not None:
            os.uname = self.uname
        else:
            del os.uname
        os.name = self.name
        sys.prefix = self.prefix
        sys.exec_prefix = self.exec_prefix
        sys.platform = self.platform
        sys.version = self.version
        sys._framework = self._framework
        os.sep = self.sep
        os.path.join = self.join
        os.path.isabs = self.isabs
        os.path.splitdrive = self.splitdrive
        sysconfig._CONFIG_VARS = self._config_vars[0]
        sysconfig._CONFIG_VARS.clear()
        sysconfig._CONFIG_VARS.update(self._config_vars[1])
        for var, value in self._changed_envvars:
            os.environ[var] = value
        for var in self._added_envvars:
            os.environ.pop(var, None)

        super(TestSysConfig, self).tearDown()

    def _set_uname(self, uname):
        self._uname = os.uname_result(uname)

    def _get_uname(self):
        return self._uname

    def _cleanup_testfn(self):
        path = TESTFN
        if os.path.isfile(path):
            os.remove(path)
        elif os.path.isdir(path):
            shutil.rmtree(path)

    def test_get_path_names(self):
        self.assertEqual(get_path_names(), sysconfig._SCHEME_KEYS)

    def test_get_paths(self):
        scheme = get_paths()
        default_scheme = get_default_scheme()
        wanted = _expand_vars(default_scheme, None)
        wanted = sorted(wanted.items())
        scheme = sorted(scheme.items())
        self.assertEqual(scheme, wanted)

    def test_get_path(self):
        config_vars = get_config_vars()
        if os.name == 'nt':
            # On Windows, we replace the native platlibdir name with the
            # default so that POSIX schemes resolve correctly
            config_vars = config_vars | {'platlibdir': 'lib'}
        for scheme in _INSTALL_SCHEMES:
            for name in _INSTALL_SCHEMES[scheme]:
                expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
                self.assertEqual(
                    os.path.normpath(get_path(name, scheme)),
                    os.path.normpath(expected),
                )

    def test_get_default_scheme(self):
        self.assertIn(get_default_scheme(), _INSTALL_SCHEMES)

    def test_get_preferred_schemes(self):
        expected_schemes = {'prefix', 'home', 'user'}

        # Windows.
        os.name = 'nt'
        schemes = _get_preferred_schemes()
        self.assertIsInstance(schemes, dict)
        self.assertEqual(set(schemes), expected_schemes)

        # Mac and Linux, shared library build.
        os.name = 'posix'
        schemes = _get_preferred_schemes()
        self.assertIsInstance(schemes, dict)
        self.assertEqual(set(schemes), expected_schemes)

        # Mac, framework build.
        os.name = 'posix'
        sys.platform = 'darwin'
        sys._framework = "MyPython"
        self.assertIsInstance(schemes, dict)
        self.assertEqual(set(schemes), expected_schemes)

    def test_posix_venv_scheme(self):
        # The following directories were hardcoded in the venv module
        # before bpo-45413, here we assert the posix_venv scheme does not regress
        binpath = 'bin'
        incpath = 'include'
        libpath = os.path.join('lib',
                               f'python{sysconfig._get_python_version_abi()}',
                               'site-packages')

        # Resolve the paths in an imaginary venv/ directory
        binpath = os.path.join('venv', binpath)
        incpath = os.path.join('venv', incpath)
        libpath = os.path.join('venv', libpath)

        # Mimic the venv module, set all bases to the venv directory
        bases = ('base', 'platbase', 'installed_base', 'installed_platbase')
        vars = {base: 'venv' for base in bases}

        self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='posix_venv', vars=vars))
        self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='posix_venv', vars=vars))

        # The include directory on POSIX isn't exactly the same as before,
        # but it is "within"
        sysconfig_includedir = sysconfig.get_path('include', scheme='posix_venv', vars=vars)
        self.assertStartsWith(sysconfig_includedir, incpath + os.sep)

    def test_nt_venv_scheme(self):
        # The following directories were hardcoded in the venv module
        # before bpo-45413, here we assert the posix_venv scheme does not regress
        binpath = 'Scripts'
        incpath = 'Include'
        libpath = os.path.join('Lib', 'site-packages')

        # Resolve the paths in an imaginary venv\ directory
        venv = 'venv'
        binpath = os.path.join(venv, binpath)
        incpath = os.path.join(venv, incpath)
        libpath = os.path.join(venv, libpath)

        # Mimic the venv module, set all bases to the venv directory
        bases = ('base', 'platbase', 'installed_base', 'installed_platbase')
        vars = {base: 'venv' for base in bases}

        self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='nt_venv', vars=vars))
        self.assertEqual(incpath, sysconfig.get_path('include', scheme='nt_venv', vars=vars))
        self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv', vars=vars))

    def test_venv_scheme(self):
        if sys.platform == 'win32':
            self.assertEqual(
                sysconfig.get_path('scripts', scheme='venv'),
                sysconfig.get_path('scripts', scheme='nt_venv')
            )
            self.assertEqual(
                sysconfig.get_path('include', scheme='venv'),
                sysconfig.get_path('include', scheme='nt_venv')
            )
            self.assertEqual(
                sysconfig.get_path('purelib', scheme='venv'),
                sysconfig.get_path('purelib', scheme='nt_venv')
            )
        else:
            self.assertEqual(
                sysconfig.get_path('scripts', scheme='venv'),
                sysconfig.get_path('scripts', scheme='posix_venv')
            )
            self.assertEqual(
                sysconfig.get_path('include', scheme='venv'),
                sysconfig.get_path('include', scheme='posix_venv')
            )
            self.assertEqual(
                sysconfig.get_path('purelib', scheme='venv'),
                sysconfig.get_path('purelib', scheme='posix_venv')
            )

    def test_get_config_vars(self):
        cvars = get_config_vars()
        self.assertIsInstance(cvars, dict)
        self.assertTrue(cvars)

    def test_get_platform(self):
        # Check the actual platform returns something reasonable.
        actual_platform = get_platform()
        self.assertIsInstance(actual_platform, str)
        self.assertTrue(actual_platform)

        # Windows
        os.name = 'nt'
        with patch('_sysconfig.get_platform', create=True, return_value='win32'):
            self.assertEqual(get_platform(), 'win32')
        with patch('_sysconfig.get_platform', create=True, return_value='win-amd64'):
            self.assertEqual(get_platform(), 'win-amd64')
        sys.platform = 'test-plaform'
        with patch('_sysconfig.get_platform', create=True, return_value=None):
            self.assertEqual(get_platform(), 'test-plaform')

        # macbook
        os.name = 'posix'
        sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) '
                       '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]')
        sys.platform = 'darwin'
        self._set_uname(('Darwin', 'macziade', '8.11.1',
                   ('Darwin Kernel Version 8.11.1: '
                    'Wed Oct 10 18:23:28 PDT 2007; '
                    'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC'))
        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'

        get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
                                       '-fwrapv -O3 -Wall -Wstrict-prototypes')

        maxint = sys.maxsize
        try:
            sys.maxsize = 2147483647
            self.assertEqual(get_platform(), 'macosx-10.3-ppc')
            sys.maxsize = 9223372036854775807
            self.assertEqual(get_platform(), 'macosx-10.3-ppc64')
        finally:
            sys.maxsize = maxint

        self._set_uname(('Darwin', 'macziade', '8.11.1',
                   ('Darwin Kernel Version 8.11.1: '
                    'Wed Oct 10 18:23:28 PDT 2007; '
                    'root:xnu-792.25.20~1/RELEASE_I386'), 'i386'))
        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'

        get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
                                       '-fwrapv -O3 -Wall -Wstrict-prototypes')
        maxint = sys.maxsize
        try:
            sys.maxsize = 2147483647
            self.assertEqual(get_platform(), 'macosx-10.3-i386')
            sys.maxsize = 9223372036854775807
            self.assertEqual(get_platform(), 'macosx-10.3-x86_64')
        finally:
            sys.maxsize = maxint

        # macbook with fat binaries (fat, universal or fat64)
        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
        get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot '
                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
                                       '-fno-strict-aliasing -fno-common '
                                       '-dynamic -DNDEBUG -g -O3')

        self.assertEqual(get_platform(), 'macosx-10.4-fat')

        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot '
                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
                                       '-fno-strict-aliasing -fno-common '
                                       '-dynamic -DNDEBUG -g -O3')

        self.assertEqual(get_platform(), 'macosx-10.4-intel')

        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot '
                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
                                       '-fno-strict-aliasing -fno-common '
                                       '-dynamic -DNDEBUG -g -O3')
        self.assertEqual(get_platform(), 'macosx-10.4-fat3')

        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot '
                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
                                       '-fno-strict-aliasing -fno-common '
                                       '-dynamic -DNDEBUG -g -O3')
        self.assertEqual(get_platform(), 'macosx-10.4-universal')

        _osx_support._remove_original_values(get_config_vars())
        get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot '
                                       '/Developer/SDKs/MacOSX10.4u.sdk  '
                                       '-fno-strict-aliasing -fno-common '
                                       '-dynamic -DNDEBUG -g -O3')

        self.assertEqual(get_platform(), 'macosx-10.4-fat64')

        for arch in ('ppc', 'i386', 'x86_64', 'ppc64'):
            _osx_support._remove_original_values(get_config_vars())
            get_config_vars()['CFLAGS'] = ('-arch %s -isysroot '
                                           '/Developer/SDKs/MacOSX10.4u.sdk  '
                                           '-fno-strict-aliasing -fno-common '
                                           '-dynamic -DNDEBUG -g -O3' % arch)

            self.assertEqual(get_platform(), 'macosx-10.4-%s' % arch)

        for macver in range(11, 16):
            _osx_support._remove_original_values(get_config_vars())
            get_config_vars()['CFLAGS'] = ('-fno-strict-overflow -Wsign-compare -Wunreachable-code'
                                        '-arch arm64 -fno-common -dynamic -DNDEBUG -g -O3 -Wall')
            get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = f"{macver}.0"
            self.assertEqual(get_platform(), 'macosx-%d.0-arm64' % macver)

        # linux debian sarge
        os.name = 'posix'
        sys.version = ('2.3.5 (#1, Jul  4 2007, 17:28:59) '
                       '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]')
        sys.platform = 'linux2'
        self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7',
                    '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686'))

        self.assertEqual(get_platform(), 'linux-i686')

        # Android
        os.name = 'posix'
        sys.platform = 'android'
        get_config_vars()['ANDROID_API_LEVEL'] = 9
        for machine, abi in {
            'x86_64': 'x86_64',
            'i686': 'x86',
            'aarch64': 'arm64_v8a',
            'armv7l': 'armeabi_v7a',
            'armv8l': 'armeabi_v7a',
        }.items():
            with self.subTest(machine):
                self._set_uname(('Linux', 'localhost', '3.18.91+',
                                '#1 Tue Jan 9 20:35:43 UTC 2018', machine))
                self.assertEqual(get_platform(), f'android-9-{abi}')

        # XXX more platforms to tests here

    @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
    @unittest.skipIf(is_apple_mobile,
                     f"{sys.platform} doesn't distribute header files in the runtime environment")
    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_scheme_names(self):
        wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv']
        if HAS_USER_BASE:
            wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
        self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))

    @skip_unless_symlink
    @requires_subprocess()
    def test_symlink(self): # Issue 7880
        with PythonSymlink() as py:
            cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
            self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))

    def test_user_similar(self):
        # Issue #8759: make sure the posix scheme for the users
        # is similar to the global posix_prefix one
        base = get_config_var('base')
        if HAS_USER_BASE:
            user = get_config_var('userbase')
        # the global scheme mirrors the distinction between prefix and
        # exec-prefix but not the user scheme, so we have to adapt the paths
        # before comparing (issue #9100)
        adapt = sys.base_prefix != sys.base_exec_prefix
        for name in ('stdlib', 'platstdlib', 'purelib', 'platlib'):
            global_path = get_path(name, 'posix_prefix')
            if adapt:
                global_path = global_path.replace(sys.exec_prefix, sys.base_prefix)
                base = base.replace(sys.exec_prefix, sys.base_prefix)
            elif sys.base_prefix != sys.prefix:
                # virtual environment? Likewise, we have to adapt the paths
                # before comparing
                global_path = global_path.replace(sys.base_prefix, sys.prefix)
                base = base.replace(sys.base_prefix, sys.prefix)
            if HAS_USER_BASE:
                user_path = get_path(name, 'posix_user')
                expected = os.path.normpath(global_path.replace(base, user, 1))
                # bpo-44860: platlib of posix_user doesn't use sys.platlibdir,
                # whereas posix_prefix does.
                if name == 'platlib':
                    # Replace "/lib64/python3.11/site-packages" suffix
                    # with "/lib/python3.11/site-packages".
                    py_version_abi = sysconfig._get_python_version_abi()
                    suffix = f'python{py_version_abi}/site-packages'
                    expected = expected.replace(f'/{sys.platlibdir}/{suffix}',
                                                f'/lib/{suffix}')
                self.assertEqual(user_path, expected)

    def test_main(self):
        # just making sure _main() runs and returns things in the stdout
        with captured_stdout() as output:
            _main()
        self.assertTrue(len(output.getvalue().split('\n')) > 0)

    @unittest.skipIf(sys.platform == "win32", "Does not apply to Windows")
    def test_ldshared_value(self):
        ldflags = sysconfig.get_config_var('LDFLAGS')
        ldshared = sysconfig.get_config_var('LDSHARED')

        self.assertIn(ldflags, ldshared)

    @unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes")
    def test_soabi(self):
        soabi = sysconfig.get_config_var('SOABI')
        self.assertIn(soabi, _imp.extension_suffixes()[0])

    def test_library(self):
        library = sysconfig.get_config_var('LIBRARY')
        ldlibrary = sysconfig.get_config_var('LDLIBRARY')
        major, minor = sys.version_info[:2]
        abiflags = sysconfig.get_config_var('ABIFLAGS')
        if sys.platform.startswith('win'):
            self.assertEqual(library, f'python{major}{minor}{abiflags}.dll')
            self.assertEqual(library, ldlibrary)
        elif is_apple_mobile:
            framework = sysconfig.get_config_var('PYTHONFRAMEWORK')
            self.assertEqual(ldlibrary, f"{framework}.framework/{framework}")
        else:
            self.assertStartsWith(library, f'libpython{major}.{minor}')
            self.assertEndsWith(library, '.a')
            if sys.platform == 'darwin' and sys._framework:
                self.skipTest('gh-110824: skip LDLIBRARY test for framework build')
            else:
                self.assertStartsWith(ldlibrary, f'libpython{major}.{minor}')

    @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX")
    @requires_subprocess()
    def test_platform_in_subprocess(self):
        my_platform = sysconfig.get_platform()

        # Test without MACOSX_DEPLOYMENT_TARGET in the environment

        env = os.environ.copy()
        if 'MACOSX_DEPLOYMENT_TARGET' in env:
            del env['MACOSX_DEPLOYMENT_TARGET']

        p = subprocess.Popen([
                sys.executable, '-c',
                'import sysconfig; print(sysconfig.get_platform())',
            ],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            env=env)
        test_platform = p.communicate()[0].strip()
        test_platform = test_platform.decode('utf-8')
        status = p.wait()

        self.assertEqual(status, 0)
        self.assertEqual(my_platform, test_platform)

        # Test with MACOSX_DEPLOYMENT_TARGET in the environment, and
        # using a value that is unlikely to be the default one.
        env = os.environ.copy()
        env['MACOSX_DEPLOYMENT_TARGET'] = '10.1'

        p = subprocess.Popen([
                sys.executable, '-c',
                'import sysconfig; print(sysconfig.get_platform())',
            ],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            env=env)
        test_platform = p.communicate()[0].strip()
        test_platform = test_platform.decode('utf-8')
        status = p.wait()

        self.assertEqual(status, 0)
        self.assertEqual(my_platform, test_platform)

    @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
    @unittest.skipIf(is_apple_mobile,
                     f"{sys.platform} doesn't include config folder at runtime")
    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.in always exists even if unused
            pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in')
            self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in)
            if os.name == 'nt':
                pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h')
                self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h)
        elif os.name == 'posix':
            makefile_dir = os.path.dirname(sysconfig.get_makefile_filename())
            # Issue #19340: srcdir has been realpath'ed already
            makefile_dir = os.path.realpath(makefile_dir)
            self.assertEqual(makefile_dir, 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')
        with change_cwd(os.pardir):
            srcdir2 = sysconfig.get_config_var('srcdir')
        self.assertEqual(srcdir, srcdir2)

    @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None,
                     'EXT_SUFFIX required for this test')
    @unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes")
    def test_EXT_SUFFIX_in_vars(self):
        vars = sysconfig.get_config_vars()
        self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0])

    @unittest.skipUnless(sys.platform == 'linux', 'Linux-specific test')
    def test_linux_ext_suffix(self):
        ctypes = import_module('ctypes')
        machine = platform.machine()
        suffix = sysconfig.get_config_var('EXT_SUFFIX')
        if re.match('(aarch64|arm|mips|ppc|powerpc|s390|sparc)', machine):
            self.assertTrue('linux' in suffix, suffix)
        if re.match('(i[3-6]86|x86_64)$', machine):
            if ctypes.sizeof(ctypes.c_char_p()) == 4:
                expected_suffixes = 'i386-linux-gnu.so', 'x86_64-linux-gnux32.so', 'i386-linux-musl.so'
            else: # 8 byte pointer size
                expected_suffixes = 'x86_64-linux-gnu.so', 'x86_64-linux-musl.so'
            self.assertEndsWith(suffix, expected_suffixes)

    @unittest.skipUnless(sys.platform == 'android', 'Android-specific test')
    def test_android_ext_suffix(self):
        machine = platform.machine()
        suffix = sysconfig.get_config_var('EXT_SUFFIX')
        expected_triplet = {
            "x86_64": "x86_64-linux-android",
            "i686": "i686-linux-android",
            "aarch64": "aarch64-linux-android",
            "armv7l": "arm-linux-androideabi",
            "armv8l": "arm-linux-androideabi",
        }[machine]
        self.assertEndsWith(suffix, f"-{expected_triplet}.so")

    @unittest.skipUnless(sys.platform == 'darwin', 'OS X-specific test')
    def test_osx_ext_suffix(self):
        suffix = sysconfig.get_config_var('EXT_SUFFIX')
        self.assertEndsWith(suffix, '-darwin.so')

    def test_always_set_py_debug(self):
        self.assertIn('Py_DEBUG', sysconfig.get_config_vars())
        Py_DEBUG = sysconfig.get_config_var('Py_DEBUG')
        self.assertIn(Py_DEBUG, (0, 1))
        self.assertEqual(Py_DEBUG, support.Py_DEBUG)

    def test_always_set_py_gil_disabled(self):
        self.assertIn('Py_GIL_DISABLED', sysconfig.get_config_vars())
        Py_GIL_DISABLED = sysconfig.get_config_var('Py_GIL_DISABLED')
        self.assertIn(Py_GIL_DISABLED, (0, 1))
        self.assertEqual(Py_GIL_DISABLED, support.Py_GIL_DISABLED)

    def test_abiflags(self):
        # If this test fails on some platforms, maintainers should update the
        # test to make it pass, rather than changing the definition of ABIFLAGS.
        self.assertIn('abiflags', sysconfig.get_config_vars())
        self.assertIn('ABIFLAGS', sysconfig.get_config_vars())
        abiflags = sysconfig.get_config_var('abiflags')
        ABIFLAGS = sysconfig.get_config_var('ABIFLAGS')
        self.assertIsInstance(abiflags, str)
        self.assertIsInstance(ABIFLAGS, str)
        self.assertIn(abiflags, ABIFLAGS)
        if os.name == 'nt':
            self.assertEqual(abiflags, '')

        if not sys.platform.startswith('win'):
            valid_abiflags = ('', 't', 'd', 'td')
        else:
            # Windows uses '_d' rather than 'd'; see also test_abi_debug below
            valid_abiflags = ('', 't', '_d', 't_d')

        self.assertIn(ABIFLAGS, valid_abiflags)

    def test_abi_debug(self):
        ABIFLAGS = sysconfig.get_config_var('ABIFLAGS')
        if support.Py_DEBUG:
            self.assertIn('d', ABIFLAGS)
        else:
            self.assertNotIn('d', ABIFLAGS)

        # The 'd' flag should always be the last one on Windows.
        # On Windows, the debug flag is used differently with a underscore prefix.
        # For example, `python{X}.{Y}td` on Unix and `python{X}.{Y}t_d.exe` on Windows.
        if support.Py_DEBUG and sys.platform.startswith('win'):
            self.assertEndsWith(ABIFLAGS, '_d')

    def test_abi_thread(self):
        abi_thread = sysconfig.get_config_var('abi_thread')
        ABIFLAGS = sysconfig.get_config_var('ABIFLAGS')
        self.assertIsInstance(abi_thread, str)
        if support.Py_GIL_DISABLED:
            self.assertEqual(abi_thread, 't')
            self.assertIn('t', ABIFLAGS)
        else:
            self.assertEqual(abi_thread, '')
            self.assertNotIn('t', ABIFLAGS)

    @requires_subprocess()
    def test_makefile_overwrites_config_vars(self):
        script = textwrap.dedent("""
            import sys, sysconfig

            data = {
                'prefix': sys.prefix,
                'exec_prefix': sys.exec_prefix,
                'base_prefix': sys.base_prefix,
                'base_exec_prefix': sys.base_exec_prefix,
                'config_vars': sysconfig.get_config_vars(),
            }

            import json
            print(json.dumps(data, indent=2))
        """)

        # We need to run the test inside a virtual environment so that
        # sys.prefix/sys.exec_prefix have a different value from the
        # prefix/exec_prefix Makefile variables.
        with self.venv() as venv:
            data = json.loads(venv.run('-c', script).stdout)

        # We expect sysconfig.get_config_vars to correctly reflect sys.prefix/sys.exec_prefix
        self.assertEqual(data['prefix'], data['config_vars']['prefix'])
        self.assertEqual(data['exec_prefix'], data['config_vars']['exec_prefix'])
        # As a sanity check, just make sure sys.prefix/sys.exec_prefix really
        # are different from the Makefile values.
        # sys.base_prefix/sys.base_exec_prefix should reflect the value of the
        # prefix/exec_prefix Makefile variables, so we use them in the comparison.
        self.assertNotEqual(data['prefix'], data['base_prefix'])
        self.assertNotEqual(data['exec_prefix'], data['base_exec_prefix'])

    @unittest.skipIf(os.name != 'posix', '_sysconfig-vars JSON file is only available on POSIX')
    @unittest.skipIf(is_wasi, "_sysconfig-vars JSON file currently isn't available on WASI")
    @unittest.skipIf(is_android or is_apple_mobile, 'Android and iOS change the prefix')
    def test_sysconfigdata_json(self):
        if '_PYTHON_SYSCONFIGDATA_PATH' in os.environ:
            data_dir = os.environ['_PYTHON_SYSCONFIGDATA_PATH']
        elif is_python_build():
            data_dir = os.path.join(_PROJECT_BASE, _get_pybuilddir())
        else:
            data_dir = sys._stdlib_dir

        json_data_path = os.path.join(data_dir, _get_json_data_name())

        with open(json_data_path) as f:
            json_config_vars = json.load(f)

        system_config_vars = get_config_vars()

        # Keys dependent on uncontrollable external context
        ignore_keys = {'userbase'}
        # Keys dependent on Python being run outside the build directrory
        if sysconfig.is_python_build():
            ignore_keys |= {'srcdir'}
        # Keys dependent on the executable location
        if os.path.dirname(sys.executable) != system_config_vars['BINDIR']:
            ignore_keys |= {'projectbase'}
        # Keys dependent on the environment (different inside virtual environments)
        if sys.prefix != sys.base_prefix:
            ignore_keys |= {'prefix', 'exec_prefix', 'base', 'platbase'}
        # Keys dependent on Python being run from the prefix targetted when building (different on relocatable installs)
        if sysconfig._installation_is_relocated():
            ignore_keys |= {'prefix', 'exec_prefix', 'base', 'platbase', 'installed_base', 'installed_platbase', 'srcdir'}

        for key in ignore_keys:
            json_config_vars.pop(key, None)
            system_config_vars.pop(key, None)

        self.assertEqual(system_config_vars, json_config_vars)

    def test_sysconfig_config_vars_no_prefix_cache(self):
        sys.prefix = 'prefix-AAA'
        sys.exec_prefix = 'exec-prefix-AAA'

        config_vars = sysconfig.get_config_vars()

        self.assertEqual(config_vars['prefix'], sys.prefix)
        self.assertEqual(config_vars['base'], sys.prefix)
        self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
        self.assertEqual(config_vars['platbase'], sys.exec_prefix)

        sys.prefix = 'prefix-BBB'
        sys.exec_prefix = 'exec-prefix-BBB'

        config_vars = sysconfig.get_config_vars()

        self.assertEqual(config_vars['prefix'], sys.prefix)
        self.assertEqual(config_vars['base'], sys.prefix)
        self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
        self.assertEqual(config_vars['platbase'], sys.exec_prefix)


class MakefileTests(unittest.TestCase):

    @unittest.skipIf(sys.platform.startswith('win'),
                     'Test is not Windows compatible')
    @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds")
    @unittest.skipIf(is_apple_mobile,
                     f"{sys.platform} doesn't include config folder at runtime")
    def test_get_makefile_filename(self):
        makefile = sysconfig.get_makefile_filename()
        self.assertTrue(os.path.isfile(makefile), makefile)

    def test_parse_makefile(self):
        self.addCleanup(unlink, TESTFN)
        with open(TESTFN, "w") as makefile:
            print("var1=a$(VAR2)", file=makefile)
            print("VAR2=b$(var3)", file=makefile)
            print("var3=42", file=makefile)
            print("var4=$/invalid", file=makefile)
            print("var5=dollar$$5", file=makefile)
            print("var6=${var7}/lib/python3.5/config-$(VAR2)$(var5)"
                  "-x86_64-linux-gnu", file=makefile)
            print("var7=${var3}", file=makefile)
            print("var8=$$(var3)", file=makefile)
            print("var9=$(var10)(var3)", file=makefile)
            print("var10=$$", file=makefile)
            print("var11=$${ORIGIN}${var5}", file=makefile)
        vars = _parse_makefile(TESTFN)
        self.assertEqual(vars, {
            'var1': 'ab42',
            'VAR2': 'b42',
            'var3': 42,
            'var4': '$/invalid',
            'var5': 'dollar$5',
            'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
            'var7': 42,
            'var8': '$(var3)',
            'var9': '$(var3)',
            'var10': '$',
            'var11': '${ORIGIN}dollar$5',
        })

    def _test_parse_makefile_recursion(self):
        self.addCleanup(unlink, TESTFN)
        with open(TESTFN, "w") as makefile:
            print("var1=var1=$(var1)", file=makefile)
            print("var2=var3=$(var3)", file=makefile)
            print("var3=var2=$(var2)", file=makefile)
        vars = _parse_makefile(TESTFN)
        self.assertEqual(vars, {
            'var1': 'var1=',
            'var2': 'var3=var2=',
            'var3': 'var2=',
        })

    def test_parse_makefile_renamed_vars(self):
        self.addCleanup(unlink, TESTFN)
        with open(TESTFN, "w") as makefile:
            print("var1=$(CFLAGS)", file=makefile)
            print("PY_CFLAGS=-Wall $(CPPFLAGS)", file=makefile)
            print("PY_LDFLAGS=-lm", file=makefile)
            print("var2=$(LDFLAGS)", file=makefile)
            print("var3=$(CPPFLAGS)", file=makefile)
        with EnvironmentVarGuard() as env:
            env.clear()
            vars = _parse_makefile(TESTFN)
        self.assertEqual(vars, {
            'var1': '-Wall',
            'CFLAGS': '-Wall',
            'PY_CFLAGS': '-Wall',
            'LDFLAGS': '-lm',
            'PY_LDFLAGS': '-lm',
            'var2': '-lm',
            'var3': '',
        })

    def test_parse_makefile_keep_unresolved(self):
        self.addCleanup(unlink, TESTFN)
        with open(TESTFN, "w") as makefile:
            print("var1=value", file=makefile)
            print("var2=$/", file=makefile)
            print("var3=$/$(var1)", file=makefile)
            print("var4=var5=$(var5)", file=makefile)
            print("var5=$/$(var1)", file=makefile)
            print("var6=$(var1)$/", file=makefile)
            print("var7=var8=$(var8)", file=makefile)
            print("var8=$(var1)$/", file=makefile)
        vars = _parse_makefile(TESTFN)
        self.assertEqual(vars, {
            'var1': 'value',
            'var2': '$/',
            'var3': '$/value',
            'var4': 'var5=$/value',
            'var5': '$/value',
            'var6': 'value$/',
            'var7': 'var8=value$/',
            'var8': 'value$/',
        })
        vars = _parse_makefile(TESTFN, keep_unresolved=False)
        self.assertEqual(vars, {
            'var1': 'value',
            'var4': 'var5=',
            'var7': 'var8=',
        })


class DeprecationTests(unittest.TestCase):
    def deprecated(self, removal_version, deprecation_msg=None, error=Exception, error_msg=None):
        if sys.version_info >= removal_version:
            return self.assertRaises(error, msg=error_msg)
        else:
            return self.assertWarns(DeprecationWarning, msg=deprecation_msg)

    def test_expand_makefile_vars(self):
        with self.deprecated(
            removal_version=(3, 16),
            deprecation_msg=(
                'sysconfig.expand_makefile_vars is deprecated and will be removed in '
                'Python 3.16. Use sysconfig.get_paths(vars=...) instead.',
            ),
            error=AttributeError,
            error_msg="module 'sysconfig' has no attribute 'expand_makefile_vars'",
        ):
            sysconfig.expand_makefile_vars('', {})

    def test_is_python_build_check_home(self):
        with self.deprecated(
            removal_version=(3, 15),
            deprecation_msg=(
                'The check_home argument of sysconfig.is_python_build is '
                'deprecated and its value is ignored. '
                'It will be removed in Python 3.15.'
            ),
            error=TypeError,
            error_msg="is_python_build() takes 0 positional arguments but 1 were given",
        ):
            sysconfig.is_python_build('foo')


if __name__ == "__main__":
    unittest.main()
