1*cda5da8dSAndroid Build Coastguard Worker"""Access to Python's configuration information.""" 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Workerimport os 4*cda5da8dSAndroid Build Coastguard Workerimport sys 5*cda5da8dSAndroid Build Coastguard Workerfrom os.path import pardir, realpath 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 8*cda5da8dSAndroid Build Coastguard Worker 'get_config_h_filename', 9*cda5da8dSAndroid Build Coastguard Worker 'get_config_var', 10*cda5da8dSAndroid Build Coastguard Worker 'get_config_vars', 11*cda5da8dSAndroid Build Coastguard Worker 'get_makefile_filename', 12*cda5da8dSAndroid Build Coastguard Worker 'get_path', 13*cda5da8dSAndroid Build Coastguard Worker 'get_path_names', 14*cda5da8dSAndroid Build Coastguard Worker 'get_paths', 15*cda5da8dSAndroid Build Coastguard Worker 'get_platform', 16*cda5da8dSAndroid Build Coastguard Worker 'get_python_version', 17*cda5da8dSAndroid Build Coastguard Worker 'get_scheme_names', 18*cda5da8dSAndroid Build Coastguard Worker 'parse_config_h', 19*cda5da8dSAndroid Build Coastguard Worker] 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Worker# Keys for get_config_var() that are never converted to Python integers. 22*cda5da8dSAndroid Build Coastguard Worker_ALWAYS_STR = { 23*cda5da8dSAndroid Build Coastguard Worker 'MACOSX_DEPLOYMENT_TARGET', 24*cda5da8dSAndroid Build Coastguard Worker} 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Worker_INSTALL_SCHEMES = { 27*cda5da8dSAndroid Build Coastguard Worker 'posix_prefix': { 28*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', 29*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', 30*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{base}/lib/python{py_version_short}/site-packages', 31*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', 32*cda5da8dSAndroid Build Coastguard Worker 'include': 33*cda5da8dSAndroid Build Coastguard Worker '{installed_base}/include/python{py_version_short}{abiflags}', 34*cda5da8dSAndroid Build Coastguard Worker 'platinclude': 35*cda5da8dSAndroid Build Coastguard Worker '{installed_platbase}/include/python{py_version_short}{abiflags}', 36*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{base}/bin', 37*cda5da8dSAndroid Build Coastguard Worker 'data': '{base}', 38*cda5da8dSAndroid Build Coastguard Worker }, 39*cda5da8dSAndroid Build Coastguard Worker 'posix_home': { 40*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{installed_base}/lib/python', 41*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{base}/lib/python', 42*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{base}/lib/python', 43*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{base}/lib/python', 44*cda5da8dSAndroid Build Coastguard Worker 'include': '{installed_base}/include/python', 45*cda5da8dSAndroid Build Coastguard Worker 'platinclude': '{installed_base}/include/python', 46*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{base}/bin', 47*cda5da8dSAndroid Build Coastguard Worker 'data': '{base}', 48*cda5da8dSAndroid Build Coastguard Worker }, 49*cda5da8dSAndroid Build Coastguard Worker 'nt': { 50*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{installed_base}/Lib', 51*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{base}/Lib', 52*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{base}/Lib/site-packages', 53*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{base}/Lib/site-packages', 54*cda5da8dSAndroid Build Coastguard Worker 'include': '{installed_base}/Include', 55*cda5da8dSAndroid Build Coastguard Worker 'platinclude': '{installed_base}/Include', 56*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{base}/Scripts', 57*cda5da8dSAndroid Build Coastguard Worker 'data': '{base}', 58*cda5da8dSAndroid Build Coastguard Worker }, 59*cda5da8dSAndroid Build Coastguard Worker # Downstream distributors can overwrite the default install scheme. 60*cda5da8dSAndroid Build Coastguard Worker # This is done to support downstream modifications where distributors change 61*cda5da8dSAndroid Build Coastguard Worker # the installation layout (eg. different site-packages directory). 62*cda5da8dSAndroid Build Coastguard Worker # So, distributors will change the default scheme to one that correctly 63*cda5da8dSAndroid Build Coastguard Worker # represents their layout. 64*cda5da8dSAndroid Build Coastguard Worker # This presents an issue for projects/people that need to bootstrap virtual 65*cda5da8dSAndroid Build Coastguard Worker # environments, like virtualenv. As distributors might now be customizing 66*cda5da8dSAndroid Build Coastguard Worker # the default install scheme, there is no guarantee that the information 67*cda5da8dSAndroid Build Coastguard Worker # returned by sysconfig.get_default_scheme/get_paths is correct for 68*cda5da8dSAndroid Build Coastguard Worker # a virtual environment, the only guarantee we have is that it is correct 69*cda5da8dSAndroid Build Coastguard Worker # for the *current* environment. When bootstrapping a virtual environment, 70*cda5da8dSAndroid Build Coastguard Worker # we need to know its layout, so that we can place the files in the 71*cda5da8dSAndroid Build Coastguard Worker # correct locations. 72*cda5da8dSAndroid Build Coastguard Worker # The "*_venv" install scheme is a scheme to bootstrap virtual environments, 73*cda5da8dSAndroid Build Coastguard Worker # essentially identical to the default posix_prefix/nt schemes. 74*cda5da8dSAndroid Build Coastguard Worker # Downstream distributors who patch posix_prefix/nt scheme are encouraged to 75*cda5da8dSAndroid Build Coastguard Worker # leave the following schemes unchanged 76*cda5da8dSAndroid Build Coastguard Worker 'posix_venv': { 77*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', 78*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', 79*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{base}/lib/python{py_version_short}/site-packages', 80*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', 81*cda5da8dSAndroid Build Coastguard Worker 'include': 82*cda5da8dSAndroid Build Coastguard Worker '{installed_base}/include/python{py_version_short}{abiflags}', 83*cda5da8dSAndroid Build Coastguard Worker 'platinclude': 84*cda5da8dSAndroid Build Coastguard Worker '{installed_platbase}/include/python{py_version_short}{abiflags}', 85*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{base}/bin', 86*cda5da8dSAndroid Build Coastguard Worker 'data': '{base}', 87*cda5da8dSAndroid Build Coastguard Worker }, 88*cda5da8dSAndroid Build Coastguard Worker 'nt_venv': { 89*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{installed_base}/Lib', 90*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{base}/Lib', 91*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{base}/Lib/site-packages', 92*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{base}/Lib/site-packages', 93*cda5da8dSAndroid Build Coastguard Worker 'include': '{installed_base}/Include', 94*cda5da8dSAndroid Build Coastguard Worker 'platinclude': '{installed_base}/Include', 95*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{base}/Scripts', 96*cda5da8dSAndroid Build Coastguard Worker 'data': '{base}', 97*cda5da8dSAndroid Build Coastguard Worker }, 98*cda5da8dSAndroid Build Coastguard Worker } 99*cda5da8dSAndroid Build Coastguard Worker 100*cda5da8dSAndroid Build Coastguard Worker# For the OS-native venv scheme, we essentially provide an alias: 101*cda5da8dSAndroid Build Coastguard Workerif os.name == 'nt': 102*cda5da8dSAndroid Build Coastguard Worker _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] 103*cda5da8dSAndroid Build Coastguard Workerelse: 104*cda5da8dSAndroid Build Coastguard Worker _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] 105*cda5da8dSAndroid Build Coastguard Worker 106*cda5da8dSAndroid Build Coastguard Worker 107*cda5da8dSAndroid Build Coastguard Worker# NOTE: site.py has copy of this function. 108*cda5da8dSAndroid Build Coastguard Worker# Sync it when modify this function. 109*cda5da8dSAndroid Build Coastguard Workerdef _getuserbase(): 110*cda5da8dSAndroid Build Coastguard Worker env_base = os.environ.get("PYTHONUSERBASE", None) 111*cda5da8dSAndroid Build Coastguard Worker if env_base: 112*cda5da8dSAndroid Build Coastguard Worker return env_base 113*cda5da8dSAndroid Build Coastguard Worker 114*cda5da8dSAndroid Build Coastguard Worker # Emscripten, VxWorks, and WASI have no home directories 115*cda5da8dSAndroid Build Coastguard Worker if sys.platform in {"emscripten", "vxworks", "wasi"}: 116*cda5da8dSAndroid Build Coastguard Worker return None 117*cda5da8dSAndroid Build Coastguard Worker 118*cda5da8dSAndroid Build Coastguard Worker def joinuser(*args): 119*cda5da8dSAndroid Build Coastguard Worker return os.path.expanduser(os.path.join(*args)) 120*cda5da8dSAndroid Build Coastguard Worker 121*cda5da8dSAndroid Build Coastguard Worker if os.name == "nt": 122*cda5da8dSAndroid Build Coastguard Worker base = os.environ.get("APPDATA") or "~" 123*cda5da8dSAndroid Build Coastguard Worker return joinuser(base, "Python") 124*cda5da8dSAndroid Build Coastguard Worker 125*cda5da8dSAndroid Build Coastguard Worker if sys.platform == "darwin" and sys._framework: 126*cda5da8dSAndroid Build Coastguard Worker return joinuser("~", "Library", sys._framework, 127*cda5da8dSAndroid Build Coastguard Worker f"{sys.version_info[0]}.{sys.version_info[1]}") 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Worker return joinuser("~", ".local") 130*cda5da8dSAndroid Build Coastguard Worker 131*cda5da8dSAndroid Build Coastguard Worker_HAS_USER_BASE = (_getuserbase() is not None) 132*cda5da8dSAndroid Build Coastguard Worker 133*cda5da8dSAndroid Build Coastguard Workerif _HAS_USER_BASE: 134*cda5da8dSAndroid Build Coastguard Worker _INSTALL_SCHEMES |= { 135*cda5da8dSAndroid Build Coastguard Worker # NOTE: When modifying "purelib" scheme, update site._get_path() too. 136*cda5da8dSAndroid Build Coastguard Worker 'nt_user': { 137*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{userbase}/Python{py_version_nodot_plat}', 138*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', 139*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 140*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 141*cda5da8dSAndroid Build Coastguard Worker 'include': '{userbase}/Python{py_version_nodot_plat}/Include', 142*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', 143*cda5da8dSAndroid Build Coastguard Worker 'data': '{userbase}', 144*cda5da8dSAndroid Build Coastguard Worker }, 145*cda5da8dSAndroid Build Coastguard Worker 'posix_user': { 146*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', 147*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', 148*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 149*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 150*cda5da8dSAndroid Build Coastguard Worker 'include': '{userbase}/include/python{py_version_short}', 151*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{userbase}/bin', 152*cda5da8dSAndroid Build Coastguard Worker 'data': '{userbase}', 153*cda5da8dSAndroid Build Coastguard Worker }, 154*cda5da8dSAndroid Build Coastguard Worker 'osx_framework_user': { 155*cda5da8dSAndroid Build Coastguard Worker 'stdlib': '{userbase}/lib/python', 156*cda5da8dSAndroid Build Coastguard Worker 'platstdlib': '{userbase}/lib/python', 157*cda5da8dSAndroid Build Coastguard Worker 'purelib': '{userbase}/lib/python/site-packages', 158*cda5da8dSAndroid Build Coastguard Worker 'platlib': '{userbase}/lib/python/site-packages', 159*cda5da8dSAndroid Build Coastguard Worker 'include': '{userbase}/include/python{py_version_short}', 160*cda5da8dSAndroid Build Coastguard Worker 'scripts': '{userbase}/bin', 161*cda5da8dSAndroid Build Coastguard Worker 'data': '{userbase}', 162*cda5da8dSAndroid Build Coastguard Worker }, 163*cda5da8dSAndroid Build Coastguard Worker } 164*cda5da8dSAndroid Build Coastguard Worker 165*cda5da8dSAndroid Build Coastguard Worker_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 166*cda5da8dSAndroid Build Coastguard Worker 'scripts', 'data') 167*cda5da8dSAndroid Build Coastguard Worker 168*cda5da8dSAndroid Build Coastguard Worker_PY_VERSION = sys.version.split()[0] 169*cda5da8dSAndroid Build Coastguard Worker_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' 170*cda5da8dSAndroid Build Coastguard Worker_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' 171*cda5da8dSAndroid Build Coastguard Worker_PREFIX = os.path.normpath(sys.prefix) 172*cda5da8dSAndroid Build Coastguard Worker_BASE_PREFIX = os.path.normpath(sys.base_prefix) 173*cda5da8dSAndroid Build Coastguard Worker_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) 174*cda5da8dSAndroid Build Coastguard Worker_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) 175*cda5da8dSAndroid Build Coastguard Worker_CONFIG_VARS = None 176*cda5da8dSAndroid Build Coastguard Worker_USER_BASE = None 177*cda5da8dSAndroid Build Coastguard Worker 178*cda5da8dSAndroid Build Coastguard Worker# Regexes needed for parsing Makefile (and similar syntaxes, 179*cda5da8dSAndroid Build Coastguard Worker# like old-style Setup files). 180*cda5da8dSAndroid Build Coastguard Worker_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" 181*cda5da8dSAndroid Build Coastguard Worker_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" 182*cda5da8dSAndroid Build Coastguard Worker_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" 183*cda5da8dSAndroid Build Coastguard Worker 184*cda5da8dSAndroid Build Coastguard Worker 185*cda5da8dSAndroid Build Coastguard Workerdef _safe_realpath(path): 186*cda5da8dSAndroid Build Coastguard Worker try: 187*cda5da8dSAndroid Build Coastguard Worker return realpath(path) 188*cda5da8dSAndroid Build Coastguard Worker except OSError: 189*cda5da8dSAndroid Build Coastguard Worker return path 190*cda5da8dSAndroid Build Coastguard Worker 191*cda5da8dSAndroid Build Coastguard Workerif sys.executable: 192*cda5da8dSAndroid Build Coastguard Worker _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) 193*cda5da8dSAndroid Build Coastguard Workerelse: 194*cda5da8dSAndroid Build Coastguard Worker # sys.executable can be empty if argv[0] has been changed and Python is 195*cda5da8dSAndroid Build Coastguard Worker # unable to retrieve the real program name 196*cda5da8dSAndroid Build Coastguard Worker _PROJECT_BASE = _safe_realpath(os.getcwd()) 197*cda5da8dSAndroid Build Coastguard Worker 198*cda5da8dSAndroid Build Coastguard Worker# In a virtual environment, `sys._home` gives us the target directory 199*cda5da8dSAndroid Build Coastguard Worker# `_PROJECT_BASE` for the executable that created it when the virtual 200*cda5da8dSAndroid Build Coastguard Worker# python is an actual executable ('venv --copies' or Windows). 201*cda5da8dSAndroid Build Coastguard Worker_sys_home = getattr(sys, '_home', None) 202*cda5da8dSAndroid Build Coastguard Workerif _sys_home: 203*cda5da8dSAndroid Build Coastguard Worker _PROJECT_BASE = _sys_home 204*cda5da8dSAndroid Build Coastguard Worker 205*cda5da8dSAndroid Build Coastguard Workerif os.name == 'nt': 206*cda5da8dSAndroid Build Coastguard Worker # In a source build, the executable is in a subdirectory of the root 207*cda5da8dSAndroid Build Coastguard Worker # that we want (<root>\PCbuild\<platname>). 208*cda5da8dSAndroid Build Coastguard Worker # `_BASE_PREFIX` is used as the base installation is where the source 209*cda5da8dSAndroid Build Coastguard Worker # will be. The realpath is needed to prevent mount point confusion 210*cda5da8dSAndroid Build Coastguard Worker # that can occur with just string comparisons. 211*cda5da8dSAndroid Build Coastguard Worker if _safe_realpath(_PROJECT_BASE).startswith( 212*cda5da8dSAndroid Build Coastguard Worker _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): 213*cda5da8dSAndroid Build Coastguard Worker _PROJECT_BASE = _BASE_PREFIX 214*cda5da8dSAndroid Build Coastguard Worker 215*cda5da8dSAndroid Build Coastguard Worker# set for cross builds 216*cda5da8dSAndroid Build Coastguard Workerif "_PYTHON_PROJECT_BASE" in os.environ: 217*cda5da8dSAndroid Build Coastguard Worker _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) 218*cda5da8dSAndroid Build Coastguard Worker 219*cda5da8dSAndroid Build Coastguard Workerdef is_python_build(check_home=None): 220*cda5da8dSAndroid Build Coastguard Worker if check_home is not None: 221*cda5da8dSAndroid Build Coastguard Worker import warnings 222*cda5da8dSAndroid Build Coastguard Worker warnings.warn("check_home argument is deprecated and ignored.", 223*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, stacklevel=2) 224*cda5da8dSAndroid Build Coastguard Worker for fn in ("Setup", "Setup.local"): 225*cda5da8dSAndroid Build Coastguard Worker if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): 226*cda5da8dSAndroid Build Coastguard Worker return True 227*cda5da8dSAndroid Build Coastguard Worker return False 228*cda5da8dSAndroid Build Coastguard Worker 229*cda5da8dSAndroid Build Coastguard Worker_PYTHON_BUILD = is_python_build() 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Workerif _PYTHON_BUILD: 232*cda5da8dSAndroid Build Coastguard Worker for scheme in ('posix_prefix', 'posix_home'): 233*cda5da8dSAndroid Build Coastguard Worker # On POSIX-y platforms, Python will: 234*cda5da8dSAndroid Build Coastguard Worker # - Build from .h files in 'headers' (which is only added to the 235*cda5da8dSAndroid Build Coastguard Worker # scheme when building CPython) 236*cda5da8dSAndroid Build Coastguard Worker # - Install .h files to 'include' 237*cda5da8dSAndroid Build Coastguard Worker scheme = _INSTALL_SCHEMES[scheme] 238*cda5da8dSAndroid Build Coastguard Worker scheme['headers'] = scheme['include'] 239*cda5da8dSAndroid Build Coastguard Worker scheme['include'] = '{srcdir}/Include' 240*cda5da8dSAndroid Build Coastguard Worker scheme['platinclude'] = '{projectbase}/.' 241*cda5da8dSAndroid Build Coastguard Worker del scheme 242*cda5da8dSAndroid Build Coastguard Worker 243*cda5da8dSAndroid Build Coastguard Worker 244*cda5da8dSAndroid Build Coastguard Workerdef _subst_vars(s, local_vars): 245*cda5da8dSAndroid Build Coastguard Worker try: 246*cda5da8dSAndroid Build Coastguard Worker return s.format(**local_vars) 247*cda5da8dSAndroid Build Coastguard Worker except KeyError as var: 248*cda5da8dSAndroid Build Coastguard Worker try: 249*cda5da8dSAndroid Build Coastguard Worker return s.format(**os.environ) 250*cda5da8dSAndroid Build Coastguard Worker except KeyError: 251*cda5da8dSAndroid Build Coastguard Worker raise AttributeError(f'{var}') from None 252*cda5da8dSAndroid Build Coastguard Worker 253*cda5da8dSAndroid Build Coastguard Workerdef _extend_dict(target_dict, other_dict): 254*cda5da8dSAndroid Build Coastguard Worker target_keys = target_dict.keys() 255*cda5da8dSAndroid Build Coastguard Worker for key, value in other_dict.items(): 256*cda5da8dSAndroid Build Coastguard Worker if key in target_keys: 257*cda5da8dSAndroid Build Coastguard Worker continue 258*cda5da8dSAndroid Build Coastguard Worker target_dict[key] = value 259*cda5da8dSAndroid Build Coastguard Worker 260*cda5da8dSAndroid Build Coastguard Worker 261*cda5da8dSAndroid Build Coastguard Workerdef _expand_vars(scheme, vars): 262*cda5da8dSAndroid Build Coastguard Worker res = {} 263*cda5da8dSAndroid Build Coastguard Worker if vars is None: 264*cda5da8dSAndroid Build Coastguard Worker vars = {} 265*cda5da8dSAndroid Build Coastguard Worker _extend_dict(vars, get_config_vars()) 266*cda5da8dSAndroid Build Coastguard Worker if os.name == 'nt': 267*cda5da8dSAndroid Build Coastguard Worker # On Windows we want to substitute 'lib' for schemes rather 268*cda5da8dSAndroid Build Coastguard Worker # than the native value (without modifying vars, in case it 269*cda5da8dSAndroid Build Coastguard Worker # was passed in) 270*cda5da8dSAndroid Build Coastguard Worker vars = vars | {'platlibdir': 'lib'} 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Worker for key, value in _INSTALL_SCHEMES[scheme].items(): 273*cda5da8dSAndroid Build Coastguard Worker if os.name in ('posix', 'nt'): 274*cda5da8dSAndroid Build Coastguard Worker value = os.path.expanduser(value) 275*cda5da8dSAndroid Build Coastguard Worker res[key] = os.path.normpath(_subst_vars(value, vars)) 276*cda5da8dSAndroid Build Coastguard Worker return res 277*cda5da8dSAndroid Build Coastguard Worker 278*cda5da8dSAndroid Build Coastguard Worker 279*cda5da8dSAndroid Build Coastguard Workerdef _get_preferred_schemes(): 280*cda5da8dSAndroid Build Coastguard Worker if os.name == 'nt': 281*cda5da8dSAndroid Build Coastguard Worker return { 282*cda5da8dSAndroid Build Coastguard Worker 'prefix': 'nt', 283*cda5da8dSAndroid Build Coastguard Worker 'home': 'posix_home', 284*cda5da8dSAndroid Build Coastguard Worker 'user': 'nt_user', 285*cda5da8dSAndroid Build Coastguard Worker } 286*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin' and sys._framework: 287*cda5da8dSAndroid Build Coastguard Worker return { 288*cda5da8dSAndroid Build Coastguard Worker 'prefix': 'posix_prefix', 289*cda5da8dSAndroid Build Coastguard Worker 'home': 'posix_home', 290*cda5da8dSAndroid Build Coastguard Worker 'user': 'osx_framework_user', 291*cda5da8dSAndroid Build Coastguard Worker } 292*cda5da8dSAndroid Build Coastguard Worker return { 293*cda5da8dSAndroid Build Coastguard Worker 'prefix': 'posix_prefix', 294*cda5da8dSAndroid Build Coastguard Worker 'home': 'posix_home', 295*cda5da8dSAndroid Build Coastguard Worker 'user': 'posix_user', 296*cda5da8dSAndroid Build Coastguard Worker } 297*cda5da8dSAndroid Build Coastguard Worker 298*cda5da8dSAndroid Build Coastguard Worker 299*cda5da8dSAndroid Build Coastguard Workerdef get_preferred_scheme(key): 300*cda5da8dSAndroid Build Coastguard Worker if key == 'prefix' and sys.prefix != sys.base_prefix: 301*cda5da8dSAndroid Build Coastguard Worker return 'venv' 302*cda5da8dSAndroid Build Coastguard Worker scheme = _get_preferred_schemes()[key] 303*cda5da8dSAndroid Build Coastguard Worker if scheme not in _INSTALL_SCHEMES: 304*cda5da8dSAndroid Build Coastguard Worker raise ValueError( 305*cda5da8dSAndroid Build Coastguard Worker f"{key!r} returned {scheme!r}, which is not a valid scheme " 306*cda5da8dSAndroid Build Coastguard Worker f"on this platform" 307*cda5da8dSAndroid Build Coastguard Worker ) 308*cda5da8dSAndroid Build Coastguard Worker return scheme 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Worker 311*cda5da8dSAndroid Build Coastguard Workerdef get_default_scheme(): 312*cda5da8dSAndroid Build Coastguard Worker return get_preferred_scheme('prefix') 313*cda5da8dSAndroid Build Coastguard Worker 314*cda5da8dSAndroid Build Coastguard Worker 315*cda5da8dSAndroid Build Coastguard Workerdef _parse_makefile(filename, vars=None, keep_unresolved=True): 316*cda5da8dSAndroid Build Coastguard Worker """Parse a Makefile-style file. 317*cda5da8dSAndroid Build Coastguard Worker 318*cda5da8dSAndroid Build Coastguard Worker A dictionary containing name/value pairs is returned. If an 319*cda5da8dSAndroid Build Coastguard Worker optional dictionary is passed in as the second argument, it is 320*cda5da8dSAndroid Build Coastguard Worker used instead of a new dictionary. 321*cda5da8dSAndroid Build Coastguard Worker """ 322*cda5da8dSAndroid Build Coastguard Worker import re 323*cda5da8dSAndroid Build Coastguard Worker 324*cda5da8dSAndroid Build Coastguard Worker if vars is None: 325*cda5da8dSAndroid Build Coastguard Worker vars = {} 326*cda5da8dSAndroid Build Coastguard Worker done = {} 327*cda5da8dSAndroid Build Coastguard Worker notdone = {} 328*cda5da8dSAndroid Build Coastguard Worker 329*cda5da8dSAndroid Build Coastguard Worker with open(filename, encoding=sys.getfilesystemencoding(), 330*cda5da8dSAndroid Build Coastguard Worker errors="surrogateescape") as f: 331*cda5da8dSAndroid Build Coastguard Worker lines = f.readlines() 332*cda5da8dSAndroid Build Coastguard Worker 333*cda5da8dSAndroid Build Coastguard Worker for line in lines: 334*cda5da8dSAndroid Build Coastguard Worker if line.startswith('#') or line.strip() == '': 335*cda5da8dSAndroid Build Coastguard Worker continue 336*cda5da8dSAndroid Build Coastguard Worker m = re.match(_variable_rx, line) 337*cda5da8dSAndroid Build Coastguard Worker if m: 338*cda5da8dSAndroid Build Coastguard Worker n, v = m.group(1, 2) 339*cda5da8dSAndroid Build Coastguard Worker v = v.strip() 340*cda5da8dSAndroid Build Coastguard Worker # `$$' is a literal `$' in make 341*cda5da8dSAndroid Build Coastguard Worker tmpv = v.replace('$$', '') 342*cda5da8dSAndroid Build Coastguard Worker 343*cda5da8dSAndroid Build Coastguard Worker if "$" in tmpv: 344*cda5da8dSAndroid Build Coastguard Worker notdone[n] = v 345*cda5da8dSAndroid Build Coastguard Worker else: 346*cda5da8dSAndroid Build Coastguard Worker try: 347*cda5da8dSAndroid Build Coastguard Worker if n in _ALWAYS_STR: 348*cda5da8dSAndroid Build Coastguard Worker raise ValueError 349*cda5da8dSAndroid Build Coastguard Worker 350*cda5da8dSAndroid Build Coastguard Worker v = int(v) 351*cda5da8dSAndroid Build Coastguard Worker except ValueError: 352*cda5da8dSAndroid Build Coastguard Worker # insert literal `$' 353*cda5da8dSAndroid Build Coastguard Worker done[n] = v.replace('$$', '$') 354*cda5da8dSAndroid Build Coastguard Worker else: 355*cda5da8dSAndroid Build Coastguard Worker done[n] = v 356*cda5da8dSAndroid Build Coastguard Worker 357*cda5da8dSAndroid Build Coastguard Worker # do variable interpolation here 358*cda5da8dSAndroid Build Coastguard Worker variables = list(notdone.keys()) 359*cda5da8dSAndroid Build Coastguard Worker 360*cda5da8dSAndroid Build Coastguard Worker # Variables with a 'PY_' prefix in the makefile. These need to 361*cda5da8dSAndroid Build Coastguard Worker # be made available without that prefix through sysconfig. 362*cda5da8dSAndroid Build Coastguard Worker # Special care is needed to ensure that variable expansion works, even 363*cda5da8dSAndroid Build Coastguard Worker # if the expansion uses the name without a prefix. 364*cda5da8dSAndroid Build Coastguard Worker renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') 365*cda5da8dSAndroid Build Coastguard Worker 366*cda5da8dSAndroid Build Coastguard Worker while len(variables) > 0: 367*cda5da8dSAndroid Build Coastguard Worker for name in tuple(variables): 368*cda5da8dSAndroid Build Coastguard Worker value = notdone[name] 369*cda5da8dSAndroid Build Coastguard Worker m1 = re.search(_findvar1_rx, value) 370*cda5da8dSAndroid Build Coastguard Worker m2 = re.search(_findvar2_rx, value) 371*cda5da8dSAndroid Build Coastguard Worker if m1 and m2: 372*cda5da8dSAndroid Build Coastguard Worker m = m1 if m1.start() < m2.start() else m2 373*cda5da8dSAndroid Build Coastguard Worker else: 374*cda5da8dSAndroid Build Coastguard Worker m = m1 if m1 else m2 375*cda5da8dSAndroid Build Coastguard Worker if m is not None: 376*cda5da8dSAndroid Build Coastguard Worker n = m.group(1) 377*cda5da8dSAndroid Build Coastguard Worker found = True 378*cda5da8dSAndroid Build Coastguard Worker if n in done: 379*cda5da8dSAndroid Build Coastguard Worker item = str(done[n]) 380*cda5da8dSAndroid Build Coastguard Worker elif n in notdone: 381*cda5da8dSAndroid Build Coastguard Worker # get it on a subsequent round 382*cda5da8dSAndroid Build Coastguard Worker found = False 383*cda5da8dSAndroid Build Coastguard Worker elif n in os.environ: 384*cda5da8dSAndroid Build Coastguard Worker # do it like make: fall back to environment 385*cda5da8dSAndroid Build Coastguard Worker item = os.environ[n] 386*cda5da8dSAndroid Build Coastguard Worker 387*cda5da8dSAndroid Build Coastguard Worker elif n in renamed_variables: 388*cda5da8dSAndroid Build Coastguard Worker if (name.startswith('PY_') and 389*cda5da8dSAndroid Build Coastguard Worker name[3:] in renamed_variables): 390*cda5da8dSAndroid Build Coastguard Worker item = "" 391*cda5da8dSAndroid Build Coastguard Worker 392*cda5da8dSAndroid Build Coastguard Worker elif 'PY_' + n in notdone: 393*cda5da8dSAndroid Build Coastguard Worker found = False 394*cda5da8dSAndroid Build Coastguard Worker 395*cda5da8dSAndroid Build Coastguard Worker else: 396*cda5da8dSAndroid Build Coastguard Worker item = str(done['PY_' + n]) 397*cda5da8dSAndroid Build Coastguard Worker 398*cda5da8dSAndroid Build Coastguard Worker else: 399*cda5da8dSAndroid Build Coastguard Worker done[n] = item = "" 400*cda5da8dSAndroid Build Coastguard Worker 401*cda5da8dSAndroid Build Coastguard Worker if found: 402*cda5da8dSAndroid Build Coastguard Worker after = value[m.end():] 403*cda5da8dSAndroid Build Coastguard Worker value = value[:m.start()] + item + after 404*cda5da8dSAndroid Build Coastguard Worker if "$" in after: 405*cda5da8dSAndroid Build Coastguard Worker notdone[name] = value 406*cda5da8dSAndroid Build Coastguard Worker else: 407*cda5da8dSAndroid Build Coastguard Worker try: 408*cda5da8dSAndroid Build Coastguard Worker if name in _ALWAYS_STR: 409*cda5da8dSAndroid Build Coastguard Worker raise ValueError 410*cda5da8dSAndroid Build Coastguard Worker value = int(value) 411*cda5da8dSAndroid Build Coastguard Worker except ValueError: 412*cda5da8dSAndroid Build Coastguard Worker done[name] = value.strip() 413*cda5da8dSAndroid Build Coastguard Worker else: 414*cda5da8dSAndroid Build Coastguard Worker done[name] = value 415*cda5da8dSAndroid Build Coastguard Worker variables.remove(name) 416*cda5da8dSAndroid Build Coastguard Worker 417*cda5da8dSAndroid Build Coastguard Worker if name.startswith('PY_') \ 418*cda5da8dSAndroid Build Coastguard Worker and name[3:] in renamed_variables: 419*cda5da8dSAndroid Build Coastguard Worker 420*cda5da8dSAndroid Build Coastguard Worker name = name[3:] 421*cda5da8dSAndroid Build Coastguard Worker if name not in done: 422*cda5da8dSAndroid Build Coastguard Worker done[name] = value 423*cda5da8dSAndroid Build Coastguard Worker 424*cda5da8dSAndroid Build Coastguard Worker else: 425*cda5da8dSAndroid Build Coastguard Worker # Adds unresolved variables to the done dict. 426*cda5da8dSAndroid Build Coastguard Worker # This is disabled when called from distutils.sysconfig 427*cda5da8dSAndroid Build Coastguard Worker if keep_unresolved: 428*cda5da8dSAndroid Build Coastguard Worker done[name] = value 429*cda5da8dSAndroid Build Coastguard Worker # bogus variable reference (e.g. "prefix=$/opt/python"); 430*cda5da8dSAndroid Build Coastguard Worker # just drop it since we can't deal 431*cda5da8dSAndroid Build Coastguard Worker variables.remove(name) 432*cda5da8dSAndroid Build Coastguard Worker 433*cda5da8dSAndroid Build Coastguard Worker # strip spurious spaces 434*cda5da8dSAndroid Build Coastguard Worker for k, v in done.items(): 435*cda5da8dSAndroid Build Coastguard Worker if isinstance(v, str): 436*cda5da8dSAndroid Build Coastguard Worker done[k] = v.strip() 437*cda5da8dSAndroid Build Coastguard Worker 438*cda5da8dSAndroid Build Coastguard Worker # save the results in the global dictionary 439*cda5da8dSAndroid Build Coastguard Worker vars.update(done) 440*cda5da8dSAndroid Build Coastguard Worker return vars 441*cda5da8dSAndroid Build Coastguard Worker 442*cda5da8dSAndroid Build Coastguard Worker 443*cda5da8dSAndroid Build Coastguard Workerdef get_makefile_filename(): 444*cda5da8dSAndroid Build Coastguard Worker """Return the path of the Makefile.""" 445*cda5da8dSAndroid Build Coastguard Worker if _PYTHON_BUILD: 446*cda5da8dSAndroid Build Coastguard Worker return os.path.join(_PROJECT_BASE, "Makefile") 447*cda5da8dSAndroid Build Coastguard Worker if hasattr(sys, 'abiflags'): 448*cda5da8dSAndroid Build Coastguard Worker config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' 449*cda5da8dSAndroid Build Coastguard Worker else: 450*cda5da8dSAndroid Build Coastguard Worker config_dir_name = 'config' 451*cda5da8dSAndroid Build Coastguard Worker if hasattr(sys.implementation, '_multiarch'): 452*cda5da8dSAndroid Build Coastguard Worker config_dir_name += f'-{sys.implementation._multiarch}' 453*cda5da8dSAndroid Build Coastguard Worker return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') 454*cda5da8dSAndroid Build Coastguard Worker 455*cda5da8dSAndroid Build Coastguard Worker 456*cda5da8dSAndroid Build Coastguard Workerdef _get_sysconfigdata_name(): 457*cda5da8dSAndroid Build Coastguard Worker multiarch = getattr(sys.implementation, '_multiarch', '') 458*cda5da8dSAndroid Build Coastguard Worker return os.environ.get( 459*cda5da8dSAndroid Build Coastguard Worker '_PYTHON_SYSCONFIGDATA_NAME', 460*cda5da8dSAndroid Build Coastguard Worker f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', 461*cda5da8dSAndroid Build Coastguard Worker ) 462*cda5da8dSAndroid Build Coastguard Worker 463*cda5da8dSAndroid Build Coastguard Worker 464*cda5da8dSAndroid Build Coastguard Workerdef _generate_posix_vars(): 465*cda5da8dSAndroid Build Coastguard Worker """Generate the Python module containing build-time variables.""" 466*cda5da8dSAndroid Build Coastguard Worker import pprint 467*cda5da8dSAndroid Build Coastguard Worker vars = {} 468*cda5da8dSAndroid Build Coastguard Worker # load the installed Makefile: 469*cda5da8dSAndroid Build Coastguard Worker makefile = get_makefile_filename() 470*cda5da8dSAndroid Build Coastguard Worker try: 471*cda5da8dSAndroid Build Coastguard Worker _parse_makefile(makefile, vars) 472*cda5da8dSAndroid Build Coastguard Worker except OSError as e: 473*cda5da8dSAndroid Build Coastguard Worker msg = f"invalid Python installation: unable to open {makefile}" 474*cda5da8dSAndroid Build Coastguard Worker if hasattr(e, "strerror"): 475*cda5da8dSAndroid Build Coastguard Worker msg = f"{msg} ({e.strerror})" 476*cda5da8dSAndroid Build Coastguard Worker raise OSError(msg) 477*cda5da8dSAndroid Build Coastguard Worker # load the installed pyconfig.h: 478*cda5da8dSAndroid Build Coastguard Worker config_h = get_config_h_filename() 479*cda5da8dSAndroid Build Coastguard Worker try: 480*cda5da8dSAndroid Build Coastguard Worker with open(config_h, encoding="utf-8") as f: 481*cda5da8dSAndroid Build Coastguard Worker parse_config_h(f, vars) 482*cda5da8dSAndroid Build Coastguard Worker except OSError as e: 483*cda5da8dSAndroid Build Coastguard Worker msg = f"invalid Python installation: unable to open {config_h}" 484*cda5da8dSAndroid Build Coastguard Worker if hasattr(e, "strerror"): 485*cda5da8dSAndroid Build Coastguard Worker msg = f"{msg} ({e.strerror})" 486*cda5da8dSAndroid Build Coastguard Worker raise OSError(msg) 487*cda5da8dSAndroid Build Coastguard Worker # On AIX, there are wrong paths to the linker scripts in the Makefile 488*cda5da8dSAndroid Build Coastguard Worker # -- these paths are relative to the Python source, but when installed 489*cda5da8dSAndroid Build Coastguard Worker # the scripts are in another directory. 490*cda5da8dSAndroid Build Coastguard Worker if _PYTHON_BUILD: 491*cda5da8dSAndroid Build Coastguard Worker vars['BLDSHARED'] = vars['LDSHARED'] 492*cda5da8dSAndroid Build Coastguard Worker 493*cda5da8dSAndroid Build Coastguard Worker # There's a chicken-and-egg situation on OS X with regards to the 494*cda5da8dSAndroid Build Coastguard Worker # _sysconfigdata module after the changes introduced by #15298: 495*cda5da8dSAndroid Build Coastguard Worker # get_config_vars() is called by get_platform() as part of the 496*cda5da8dSAndroid Build Coastguard Worker # `make pybuilddir.txt` target -- which is a precursor to the 497*cda5da8dSAndroid Build Coastguard Worker # _sysconfigdata.py module being constructed. Unfortunately, 498*cda5da8dSAndroid Build Coastguard Worker # get_config_vars() eventually calls _init_posix(), which attempts 499*cda5da8dSAndroid Build Coastguard Worker # to import _sysconfigdata, which we won't have built yet. In order 500*cda5da8dSAndroid Build Coastguard Worker # for _init_posix() to work, if we're on Darwin, just mock up the 501*cda5da8dSAndroid Build Coastguard Worker # _sysconfigdata module manually and populate it with the build vars. 502*cda5da8dSAndroid Build Coastguard Worker # This is more than sufficient for ensuring the subsequent call to 503*cda5da8dSAndroid Build Coastguard Worker # get_platform() succeeds. 504*cda5da8dSAndroid Build Coastguard Worker name = _get_sysconfigdata_name() 505*cda5da8dSAndroid Build Coastguard Worker if 'darwin' in sys.platform: 506*cda5da8dSAndroid Build Coastguard Worker import types 507*cda5da8dSAndroid Build Coastguard Worker module = types.ModuleType(name) 508*cda5da8dSAndroid Build Coastguard Worker module.build_time_vars = vars 509*cda5da8dSAndroid Build Coastguard Worker sys.modules[name] = module 510*cda5da8dSAndroid Build Coastguard Worker 511*cda5da8dSAndroid Build Coastguard Worker pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}' 512*cda5da8dSAndroid Build Coastguard Worker if hasattr(sys, "gettotalrefcount"): 513*cda5da8dSAndroid Build Coastguard Worker pybuilddir += '-pydebug' 514*cda5da8dSAndroid Build Coastguard Worker os.makedirs(pybuilddir, exist_ok=True) 515*cda5da8dSAndroid Build Coastguard Worker destfile = os.path.join(pybuilddir, name + '.py') 516*cda5da8dSAndroid Build Coastguard Worker 517*cda5da8dSAndroid Build Coastguard Worker with open(destfile, 'w', encoding='utf8') as f: 518*cda5da8dSAndroid Build Coastguard Worker f.write('# system configuration generated and used by' 519*cda5da8dSAndroid Build Coastguard Worker ' the sysconfig module\n') 520*cda5da8dSAndroid Build Coastguard Worker f.write('build_time_vars = ') 521*cda5da8dSAndroid Build Coastguard Worker pprint.pprint(vars, stream=f) 522*cda5da8dSAndroid Build Coastguard Worker 523*cda5da8dSAndroid Build Coastguard Worker # Create file used for sys.path fixup -- see Modules/getpath.c 524*cda5da8dSAndroid Build Coastguard Worker with open('pybuilddir.txt', 'w', encoding='utf8') as f: 525*cda5da8dSAndroid Build Coastguard Worker f.write(pybuilddir) 526*cda5da8dSAndroid Build Coastguard Worker 527*cda5da8dSAndroid Build Coastguard Workerdef _init_posix(vars): 528*cda5da8dSAndroid Build Coastguard Worker """Initialize the module as appropriate for POSIX systems.""" 529*cda5da8dSAndroid Build Coastguard Worker # _sysconfigdata is generated at build time, see _generate_posix_vars() 530*cda5da8dSAndroid Build Coastguard Worker name = _get_sysconfigdata_name() 531*cda5da8dSAndroid Build Coastguard Worker _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) 532*cda5da8dSAndroid Build Coastguard Worker build_time_vars = _temp.build_time_vars 533*cda5da8dSAndroid Build Coastguard Worker vars.update(build_time_vars) 534*cda5da8dSAndroid Build Coastguard Worker 535*cda5da8dSAndroid Build Coastguard Workerdef _init_non_posix(vars): 536*cda5da8dSAndroid Build Coastguard Worker """Initialize the module as appropriate for NT""" 537*cda5da8dSAndroid Build Coastguard Worker # set basic install directories 538*cda5da8dSAndroid Build Coastguard Worker import _imp 539*cda5da8dSAndroid Build Coastguard Worker vars['LIBDEST'] = get_path('stdlib') 540*cda5da8dSAndroid Build Coastguard Worker vars['BINLIBDEST'] = get_path('platstdlib') 541*cda5da8dSAndroid Build Coastguard Worker vars['INCLUDEPY'] = get_path('include') 542*cda5da8dSAndroid Build Coastguard Worker vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] 543*cda5da8dSAndroid Build Coastguard Worker vars['EXE'] = '.exe' 544*cda5da8dSAndroid Build Coastguard Worker vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT 545*cda5da8dSAndroid Build Coastguard Worker vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) 546*cda5da8dSAndroid Build Coastguard Worker vars['TZPATH'] = '' 547*cda5da8dSAndroid Build Coastguard Worker 548*cda5da8dSAndroid Build Coastguard Worker# 549*cda5da8dSAndroid Build Coastguard Worker# public APIs 550*cda5da8dSAndroid Build Coastguard Worker# 551*cda5da8dSAndroid Build Coastguard Worker 552*cda5da8dSAndroid Build Coastguard Worker 553*cda5da8dSAndroid Build Coastguard Workerdef parse_config_h(fp, vars=None): 554*cda5da8dSAndroid Build Coastguard Worker """Parse a config.h-style file. 555*cda5da8dSAndroid Build Coastguard Worker 556*cda5da8dSAndroid Build Coastguard Worker A dictionary containing name/value pairs is returned. If an 557*cda5da8dSAndroid Build Coastguard Worker optional dictionary is passed in as the second argument, it is 558*cda5da8dSAndroid Build Coastguard Worker used instead of a new dictionary. 559*cda5da8dSAndroid Build Coastguard Worker """ 560*cda5da8dSAndroid Build Coastguard Worker if vars is None: 561*cda5da8dSAndroid Build Coastguard Worker vars = {} 562*cda5da8dSAndroid Build Coastguard Worker import re 563*cda5da8dSAndroid Build Coastguard Worker define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") 564*cda5da8dSAndroid Build Coastguard Worker undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") 565*cda5da8dSAndroid Build Coastguard Worker 566*cda5da8dSAndroid Build Coastguard Worker while True: 567*cda5da8dSAndroid Build Coastguard Worker line = fp.readline() 568*cda5da8dSAndroid Build Coastguard Worker if not line: 569*cda5da8dSAndroid Build Coastguard Worker break 570*cda5da8dSAndroid Build Coastguard Worker m = define_rx.match(line) 571*cda5da8dSAndroid Build Coastguard Worker if m: 572*cda5da8dSAndroid Build Coastguard Worker n, v = m.group(1, 2) 573*cda5da8dSAndroid Build Coastguard Worker try: 574*cda5da8dSAndroid Build Coastguard Worker if n in _ALWAYS_STR: 575*cda5da8dSAndroid Build Coastguard Worker raise ValueError 576*cda5da8dSAndroid Build Coastguard Worker v = int(v) 577*cda5da8dSAndroid Build Coastguard Worker except ValueError: 578*cda5da8dSAndroid Build Coastguard Worker pass 579*cda5da8dSAndroid Build Coastguard Worker vars[n] = v 580*cda5da8dSAndroid Build Coastguard Worker else: 581*cda5da8dSAndroid Build Coastguard Worker m = undef_rx.match(line) 582*cda5da8dSAndroid Build Coastguard Worker if m: 583*cda5da8dSAndroid Build Coastguard Worker vars[m.group(1)] = 0 584*cda5da8dSAndroid Build Coastguard Worker return vars 585*cda5da8dSAndroid Build Coastguard Worker 586*cda5da8dSAndroid Build Coastguard Worker 587*cda5da8dSAndroid Build Coastguard Workerdef get_config_h_filename(): 588*cda5da8dSAndroid Build Coastguard Worker """Return the path of pyconfig.h.""" 589*cda5da8dSAndroid Build Coastguard Worker if _PYTHON_BUILD: 590*cda5da8dSAndroid Build Coastguard Worker if os.name == "nt": 591*cda5da8dSAndroid Build Coastguard Worker inc_dir = os.path.join(_PROJECT_BASE, "PC") 592*cda5da8dSAndroid Build Coastguard Worker else: 593*cda5da8dSAndroid Build Coastguard Worker inc_dir = _PROJECT_BASE 594*cda5da8dSAndroid Build Coastguard Worker else: 595*cda5da8dSAndroid Build Coastguard Worker inc_dir = get_path('platinclude') 596*cda5da8dSAndroid Build Coastguard Worker return os.path.join(inc_dir, 'pyconfig.h') 597*cda5da8dSAndroid Build Coastguard Worker 598*cda5da8dSAndroid Build Coastguard Worker 599*cda5da8dSAndroid Build Coastguard Workerdef get_scheme_names(): 600*cda5da8dSAndroid Build Coastguard Worker """Return a tuple containing the schemes names.""" 601*cda5da8dSAndroid Build Coastguard Worker return tuple(sorted(_INSTALL_SCHEMES)) 602*cda5da8dSAndroid Build Coastguard Worker 603*cda5da8dSAndroid Build Coastguard Worker 604*cda5da8dSAndroid Build Coastguard Workerdef get_path_names(): 605*cda5da8dSAndroid Build Coastguard Worker """Return a tuple containing the paths names.""" 606*cda5da8dSAndroid Build Coastguard Worker return _SCHEME_KEYS 607*cda5da8dSAndroid Build Coastguard Worker 608*cda5da8dSAndroid Build Coastguard Worker 609*cda5da8dSAndroid Build Coastguard Workerdef get_paths(scheme=get_default_scheme(), vars=None, expand=True): 610*cda5da8dSAndroid Build Coastguard Worker """Return a mapping containing an install scheme. 611*cda5da8dSAndroid Build Coastguard Worker 612*cda5da8dSAndroid Build Coastguard Worker ``scheme`` is the install scheme name. If not provided, it will 613*cda5da8dSAndroid Build Coastguard Worker return the default scheme for the current platform. 614*cda5da8dSAndroid Build Coastguard Worker """ 615*cda5da8dSAndroid Build Coastguard Worker if expand: 616*cda5da8dSAndroid Build Coastguard Worker return _expand_vars(scheme, vars) 617*cda5da8dSAndroid Build Coastguard Worker else: 618*cda5da8dSAndroid Build Coastguard Worker return _INSTALL_SCHEMES[scheme] 619*cda5da8dSAndroid Build Coastguard Worker 620*cda5da8dSAndroid Build Coastguard Worker 621*cda5da8dSAndroid Build Coastguard Workerdef get_path(name, scheme=get_default_scheme(), vars=None, expand=True): 622*cda5da8dSAndroid Build Coastguard Worker """Return a path corresponding to the scheme. 623*cda5da8dSAndroid Build Coastguard Worker 624*cda5da8dSAndroid Build Coastguard Worker ``scheme`` is the install scheme name. 625*cda5da8dSAndroid Build Coastguard Worker """ 626*cda5da8dSAndroid Build Coastguard Worker return get_paths(scheme, vars, expand)[name] 627*cda5da8dSAndroid Build Coastguard Worker 628*cda5da8dSAndroid Build Coastguard Worker 629*cda5da8dSAndroid Build Coastguard Workerdef get_config_vars(*args): 630*cda5da8dSAndroid Build Coastguard Worker """With no arguments, return a dictionary of all configuration 631*cda5da8dSAndroid Build Coastguard Worker variables relevant for the current platform. 632*cda5da8dSAndroid Build Coastguard Worker 633*cda5da8dSAndroid Build Coastguard Worker On Unix, this means every variable defined in Python's installed Makefile; 634*cda5da8dSAndroid Build Coastguard Worker On Windows it's a much smaller set. 635*cda5da8dSAndroid Build Coastguard Worker 636*cda5da8dSAndroid Build Coastguard Worker With arguments, return a list of values that result from looking up 637*cda5da8dSAndroid Build Coastguard Worker each argument in the configuration variable dictionary. 638*cda5da8dSAndroid Build Coastguard Worker """ 639*cda5da8dSAndroid Build Coastguard Worker global _CONFIG_VARS 640*cda5da8dSAndroid Build Coastguard Worker if _CONFIG_VARS is None: 641*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS = {} 642*cda5da8dSAndroid Build Coastguard Worker # Normalized versions of prefix and exec_prefix are handy to have; 643*cda5da8dSAndroid Build Coastguard Worker # in fact, these are the standard versions used most places in the 644*cda5da8dSAndroid Build Coastguard Worker # Distutils. 645*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['prefix'] = _PREFIX 646*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX 647*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['py_version'] = _PY_VERSION 648*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT 649*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT 650*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['installed_base'] = _BASE_PREFIX 651*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['base'] = _PREFIX 652*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX 653*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['platbase'] = _EXEC_PREFIX 654*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['projectbase'] = _PROJECT_BASE 655*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['platlibdir'] = sys.platlibdir 656*cda5da8dSAndroid Build Coastguard Worker try: 657*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['abiflags'] = sys.abiflags 658*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 659*cda5da8dSAndroid Build Coastguard Worker # sys.abiflags may not be defined on all platforms. 660*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['abiflags'] = '' 661*cda5da8dSAndroid Build Coastguard Worker try: 662*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') 663*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 664*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['py_version_nodot_plat'] = '' 665*cda5da8dSAndroid Build Coastguard Worker 666*cda5da8dSAndroid Build Coastguard Worker if os.name == 'nt': 667*cda5da8dSAndroid Build Coastguard Worker _init_non_posix(_CONFIG_VARS) 668*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['VPATH'] = sys._vpath 669*cda5da8dSAndroid Build Coastguard Worker if os.name == 'posix': 670*cda5da8dSAndroid Build Coastguard Worker _init_posix(_CONFIG_VARS) 671*cda5da8dSAndroid Build Coastguard Worker if _HAS_USER_BASE: 672*cda5da8dSAndroid Build Coastguard Worker # Setting 'userbase' is done below the call to the 673*cda5da8dSAndroid Build Coastguard Worker # init function to enable using 'get_config_var' in 674*cda5da8dSAndroid Build Coastguard Worker # the init-function. 675*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['userbase'] = _getuserbase() 676*cda5da8dSAndroid Build Coastguard Worker 677*cda5da8dSAndroid Build Coastguard Worker # Always convert srcdir to an absolute path 678*cda5da8dSAndroid Build Coastguard Worker srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) 679*cda5da8dSAndroid Build Coastguard Worker if os.name == 'posix': 680*cda5da8dSAndroid Build Coastguard Worker if _PYTHON_BUILD: 681*cda5da8dSAndroid Build Coastguard Worker # If srcdir is a relative path (typically '.' or '..') 682*cda5da8dSAndroid Build Coastguard Worker # then it should be interpreted relative to the directory 683*cda5da8dSAndroid Build Coastguard Worker # containing Makefile. 684*cda5da8dSAndroid Build Coastguard Worker base = os.path.dirname(get_makefile_filename()) 685*cda5da8dSAndroid Build Coastguard Worker srcdir = os.path.join(base, srcdir) 686*cda5da8dSAndroid Build Coastguard Worker else: 687*cda5da8dSAndroid Build Coastguard Worker # srcdir is not meaningful since the installation is 688*cda5da8dSAndroid Build Coastguard Worker # spread about the filesystem. We choose the 689*cda5da8dSAndroid Build Coastguard Worker # directory containing the Makefile since we know it 690*cda5da8dSAndroid Build Coastguard Worker # exists. 691*cda5da8dSAndroid Build Coastguard Worker srcdir = os.path.dirname(get_makefile_filename()) 692*cda5da8dSAndroid Build Coastguard Worker _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) 693*cda5da8dSAndroid Build Coastguard Worker 694*cda5da8dSAndroid Build Coastguard Worker # OS X platforms require special customization to handle 695*cda5da8dSAndroid Build Coastguard Worker # multi-architecture, multi-os-version installers 696*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 697*cda5da8dSAndroid Build Coastguard Worker import _osx_support 698*cda5da8dSAndroid Build Coastguard Worker _osx_support.customize_config_vars(_CONFIG_VARS) 699*cda5da8dSAndroid Build Coastguard Worker 700*cda5da8dSAndroid Build Coastguard Worker if args: 701*cda5da8dSAndroid Build Coastguard Worker vals = [] 702*cda5da8dSAndroid Build Coastguard Worker for name in args: 703*cda5da8dSAndroid Build Coastguard Worker vals.append(_CONFIG_VARS.get(name)) 704*cda5da8dSAndroid Build Coastguard Worker return vals 705*cda5da8dSAndroid Build Coastguard Worker else: 706*cda5da8dSAndroid Build Coastguard Worker return _CONFIG_VARS 707*cda5da8dSAndroid Build Coastguard Worker 708*cda5da8dSAndroid Build Coastguard Worker 709*cda5da8dSAndroid Build Coastguard Workerdef get_config_var(name): 710*cda5da8dSAndroid Build Coastguard Worker """Return the value of a single variable using the dictionary returned by 711*cda5da8dSAndroid Build Coastguard Worker 'get_config_vars()'. 712*cda5da8dSAndroid Build Coastguard Worker 713*cda5da8dSAndroid Build Coastguard Worker Equivalent to get_config_vars().get(name) 714*cda5da8dSAndroid Build Coastguard Worker """ 715*cda5da8dSAndroid Build Coastguard Worker return get_config_vars().get(name) 716*cda5da8dSAndroid Build Coastguard Worker 717*cda5da8dSAndroid Build Coastguard Worker 718*cda5da8dSAndroid Build Coastguard Workerdef get_platform(): 719*cda5da8dSAndroid Build Coastguard Worker """Return a string that identifies the current platform. 720*cda5da8dSAndroid Build Coastguard Worker 721*cda5da8dSAndroid Build Coastguard Worker This is used mainly to distinguish platform-specific build directories and 722*cda5da8dSAndroid Build Coastguard Worker platform-specific built distributions. Typically includes the OS name and 723*cda5da8dSAndroid Build Coastguard Worker version and the architecture (as supplied by 'os.uname()'), although the 724*cda5da8dSAndroid Build Coastguard Worker exact information included depends on the OS; on Linux, the kernel version 725*cda5da8dSAndroid Build Coastguard Worker isn't particularly important. 726*cda5da8dSAndroid Build Coastguard Worker 727*cda5da8dSAndroid Build Coastguard Worker Examples of returned values: 728*cda5da8dSAndroid Build Coastguard Worker linux-i586 729*cda5da8dSAndroid Build Coastguard Worker linux-alpha (?) 730*cda5da8dSAndroid Build Coastguard Worker solaris-2.6-sun4u 731*cda5da8dSAndroid Build Coastguard Worker 732*cda5da8dSAndroid Build Coastguard Worker Windows will return one of: 733*cda5da8dSAndroid Build Coastguard Worker win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) 734*cda5da8dSAndroid Build Coastguard Worker win32 (all others - specifically, sys.platform is returned) 735*cda5da8dSAndroid Build Coastguard Worker 736*cda5da8dSAndroid Build Coastguard Worker For other non-POSIX platforms, currently just returns 'sys.platform'. 737*cda5da8dSAndroid Build Coastguard Worker 738*cda5da8dSAndroid Build Coastguard Worker """ 739*cda5da8dSAndroid Build Coastguard Worker if os.name == 'nt': 740*cda5da8dSAndroid Build Coastguard Worker if 'amd64' in sys.version.lower(): 741*cda5da8dSAndroid Build Coastguard Worker return 'win-amd64' 742*cda5da8dSAndroid Build Coastguard Worker if '(arm)' in sys.version.lower(): 743*cda5da8dSAndroid Build Coastguard Worker return 'win-arm32' 744*cda5da8dSAndroid Build Coastguard Worker if '(arm64)' in sys.version.lower(): 745*cda5da8dSAndroid Build Coastguard Worker return 'win-arm64' 746*cda5da8dSAndroid Build Coastguard Worker return sys.platform 747*cda5da8dSAndroid Build Coastguard Worker 748*cda5da8dSAndroid Build Coastguard Worker if os.name != "posix" or not hasattr(os, 'uname'): 749*cda5da8dSAndroid Build Coastguard Worker # XXX what about the architecture? NT is Intel or Alpha 750*cda5da8dSAndroid Build Coastguard Worker return sys.platform 751*cda5da8dSAndroid Build Coastguard Worker 752*cda5da8dSAndroid Build Coastguard Worker # Set for cross builds explicitly 753*cda5da8dSAndroid Build Coastguard Worker if "_PYTHON_HOST_PLATFORM" in os.environ: 754*cda5da8dSAndroid Build Coastguard Worker return os.environ["_PYTHON_HOST_PLATFORM"] 755*cda5da8dSAndroid Build Coastguard Worker 756*cda5da8dSAndroid Build Coastguard Worker # Try to distinguish various flavours of Unix 757*cda5da8dSAndroid Build Coastguard Worker osname, host, release, version, machine = os.uname() 758*cda5da8dSAndroid Build Coastguard Worker 759*cda5da8dSAndroid Build Coastguard Worker # Convert the OS name to lowercase, remove '/' characters, and translate 760*cda5da8dSAndroid Build Coastguard Worker # spaces (for "Power Macintosh") 761*cda5da8dSAndroid Build Coastguard Worker osname = osname.lower().replace('/', '') 762*cda5da8dSAndroid Build Coastguard Worker machine = machine.replace(' ', '_') 763*cda5da8dSAndroid Build Coastguard Worker machine = machine.replace('/', '-') 764*cda5da8dSAndroid Build Coastguard Worker 765*cda5da8dSAndroid Build Coastguard Worker if osname[:5] == "linux": 766*cda5da8dSAndroid Build Coastguard Worker # At least on Linux/Intel, 'machine' is the processor -- 767*cda5da8dSAndroid Build Coastguard Worker # i386, etc. 768*cda5da8dSAndroid Build Coastguard Worker # XXX what about Alpha, SPARC, etc? 769*cda5da8dSAndroid Build Coastguard Worker return f"{osname}-{machine}" 770*cda5da8dSAndroid Build Coastguard Worker elif osname[:5] == "sunos": 771*cda5da8dSAndroid Build Coastguard Worker if release[0] >= "5": # SunOS 5 == Solaris 2 772*cda5da8dSAndroid Build Coastguard Worker osname = "solaris" 773*cda5da8dSAndroid Build Coastguard Worker release = f"{int(release[0]) - 3}.{release[2:]}" 774*cda5da8dSAndroid Build Coastguard Worker # We can't use "platform.architecture()[0]" because a 775*cda5da8dSAndroid Build Coastguard Worker # bootstrap problem. We use a dict to get an error 776*cda5da8dSAndroid Build Coastguard Worker # if some suspicious happens. 777*cda5da8dSAndroid Build Coastguard Worker bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} 778*cda5da8dSAndroid Build Coastguard Worker machine += f".{bitness[sys.maxsize]}" 779*cda5da8dSAndroid Build Coastguard Worker # fall through to standard osname-release-machine representation 780*cda5da8dSAndroid Build Coastguard Worker elif osname[:3] == "aix": 781*cda5da8dSAndroid Build Coastguard Worker from _aix_support import aix_platform 782*cda5da8dSAndroid Build Coastguard Worker return aix_platform() 783*cda5da8dSAndroid Build Coastguard Worker elif osname[:6] == "cygwin": 784*cda5da8dSAndroid Build Coastguard Worker osname = "cygwin" 785*cda5da8dSAndroid Build Coastguard Worker import re 786*cda5da8dSAndroid Build Coastguard Worker rel_re = re.compile(r'[\d.]+') 787*cda5da8dSAndroid Build Coastguard Worker m = rel_re.match(release) 788*cda5da8dSAndroid Build Coastguard Worker if m: 789*cda5da8dSAndroid Build Coastguard Worker release = m.group() 790*cda5da8dSAndroid Build Coastguard Worker elif osname[:6] == "darwin": 791*cda5da8dSAndroid Build Coastguard Worker import _osx_support 792*cda5da8dSAndroid Build Coastguard Worker osname, release, machine = _osx_support.get_platform_osx( 793*cda5da8dSAndroid Build Coastguard Worker get_config_vars(), 794*cda5da8dSAndroid Build Coastguard Worker osname, release, machine) 795*cda5da8dSAndroid Build Coastguard Worker 796*cda5da8dSAndroid Build Coastguard Worker return f"{osname}-{release}-{machine}" 797*cda5da8dSAndroid Build Coastguard Worker 798*cda5da8dSAndroid Build Coastguard Worker 799*cda5da8dSAndroid Build Coastguard Workerdef get_python_version(): 800*cda5da8dSAndroid Build Coastguard Worker return _PY_VERSION_SHORT 801*cda5da8dSAndroid Build Coastguard Worker 802*cda5da8dSAndroid Build Coastguard Worker 803*cda5da8dSAndroid Build Coastguard Workerdef expand_makefile_vars(s, vars): 804*cda5da8dSAndroid Build Coastguard Worker """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in 805*cda5da8dSAndroid Build Coastguard Worker 'string' according to 'vars' (a dictionary mapping variable names to 806*cda5da8dSAndroid Build Coastguard Worker values). Variables not present in 'vars' are silently expanded to the 807*cda5da8dSAndroid Build Coastguard Worker empty string. The variable values in 'vars' should not contain further 808*cda5da8dSAndroid Build Coastguard Worker variable expansions; if 'vars' is the output of 'parse_makefile()', 809*cda5da8dSAndroid Build Coastguard Worker you're fine. Returns a variable-expanded version of 's'. 810*cda5da8dSAndroid Build Coastguard Worker """ 811*cda5da8dSAndroid Build Coastguard Worker import re 812*cda5da8dSAndroid Build Coastguard Worker 813*cda5da8dSAndroid Build Coastguard Worker # This algorithm does multiple expansion, so if vars['foo'] contains 814*cda5da8dSAndroid Build Coastguard Worker # "${bar}", it will expand ${foo} to ${bar}, and then expand 815*cda5da8dSAndroid Build Coastguard Worker # ${bar}... and so forth. This is fine as long as 'vars' comes from 816*cda5da8dSAndroid Build Coastguard Worker # 'parse_makefile()', which takes care of such expansions eagerly, 817*cda5da8dSAndroid Build Coastguard Worker # according to make's variable expansion semantics. 818*cda5da8dSAndroid Build Coastguard Worker 819*cda5da8dSAndroid Build Coastguard Worker while True: 820*cda5da8dSAndroid Build Coastguard Worker m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) 821*cda5da8dSAndroid Build Coastguard Worker if m: 822*cda5da8dSAndroid Build Coastguard Worker (beg, end) = m.span() 823*cda5da8dSAndroid Build Coastguard Worker s = s[0:beg] + vars.get(m.group(1)) + s[end:] 824*cda5da8dSAndroid Build Coastguard Worker else: 825*cda5da8dSAndroid Build Coastguard Worker break 826*cda5da8dSAndroid Build Coastguard Worker return s 827*cda5da8dSAndroid Build Coastguard Worker 828*cda5da8dSAndroid Build Coastguard Worker 829*cda5da8dSAndroid Build Coastguard Workerdef _print_dict(title, data): 830*cda5da8dSAndroid Build Coastguard Worker for index, (key, value) in enumerate(sorted(data.items())): 831*cda5da8dSAndroid Build Coastguard Worker if index == 0: 832*cda5da8dSAndroid Build Coastguard Worker print(f'{title}: ') 833*cda5da8dSAndroid Build Coastguard Worker print(f'\t{key} = "{value}"') 834*cda5da8dSAndroid Build Coastguard Worker 835*cda5da8dSAndroid Build Coastguard Worker 836*cda5da8dSAndroid Build Coastguard Workerdef _main(): 837*cda5da8dSAndroid Build Coastguard Worker """Display all information sysconfig detains.""" 838*cda5da8dSAndroid Build Coastguard Worker if '--generate-posix-vars' in sys.argv: 839*cda5da8dSAndroid Build Coastguard Worker _generate_posix_vars() 840*cda5da8dSAndroid Build Coastguard Worker return 841*cda5da8dSAndroid Build Coastguard Worker print(f'Platform: "{get_platform()}"') 842*cda5da8dSAndroid Build Coastguard Worker print(f'Python version: "{get_python_version()}"') 843*cda5da8dSAndroid Build Coastguard Worker print(f'Current installation scheme: "{get_default_scheme()}"') 844*cda5da8dSAndroid Build Coastguard Worker print() 845*cda5da8dSAndroid Build Coastguard Worker _print_dict('Paths', get_paths()) 846*cda5da8dSAndroid Build Coastguard Worker print() 847*cda5da8dSAndroid Build Coastguard Worker _print_dict('Variables', get_config_vars()) 848*cda5da8dSAndroid Build Coastguard Worker 849*cda5da8dSAndroid Build Coastguard Worker 850*cda5da8dSAndroid Build Coastguard Workerif __name__ == '__main__': 851*cda5da8dSAndroid Build Coastguard Worker _main() 852