1# ****************************************************************************** 2# getpath.py 3# ****************************************************************************** 4 5# This script is designed to be precompiled to bytecode, frozen into the 6# main binary, and then directly evaluated. It is not an importable module, 7# and does not import any other modules (besides winreg on Windows). 8# Rather, the values listed below must be specified in the globals dict 9# used when evaluating the bytecode. 10 11# See _PyConfig_InitPathConfig in Modules/getpath.c for the execution. 12 13# ****************************************************************************** 14# REQUIRED GLOBALS 15# ****************************************************************************** 16 17# ** Helper functions ** 18# abspath(path) -- make relative paths absolute against CWD 19# basename(path) -- the filename of path 20# dirname(path) -- the directory name of path 21# hassuffix(path, suffix) -- returns True if path has suffix 22# isabs(path) -- path is absolute or not 23# isdir(path) -- path exists and is a directory 24# isfile(path) -- path exists and is a file 25# isxfile(path) -- path exists and is an executable file 26# joinpath(*paths) -- combine the paths 27# readlines(path) -- a list of each line of text in the UTF-8 encoded file 28# realpath(path) -- resolves symlinks in path 29# warn(message) -- print a warning (if enabled) 30 31# ** Values known at compile time ** 32# os_name -- [in] one of 'nt', 'posix', 'darwin' 33# PREFIX -- [in] sysconfig.get_config_var(...) 34# EXEC_PREFIX -- [in] sysconfig.get_config_var(...) 35# PYTHONPATH -- [in] sysconfig.get_config_var(...) 36# WITH_NEXT_FRAMEWORK -- [in] sysconfig.get_config_var(...) 37# VPATH -- [in] sysconfig.get_config_var(...) 38# PLATLIBDIR -- [in] sysconfig.get_config_var(...) 39# PYDEBUGEXT -- [in, opt] '_d' on Windows for debug builds 40# EXE_SUFFIX -- [in, opt] '.exe' on Windows/Cygwin/similar 41# VERSION_MAJOR -- [in] sys.version_info.major 42# VERSION_MINOR -- [in] sys.version_info.minor 43# ABI_THREAD -- [in] either 't' for free-threaded builds or '' 44# PYWINVER -- [in] the Windows platform-specific version (e.g. 3.8-32) 45 46# ** Values read from the environment ** 47# There is no need to check the use_environment flag before reading 48# these, as the flag will be tested in this script. 49# Also note that ENV_PYTHONPATH is read from config['pythonpath_env'] 50# to allow for embedders who choose to specify it via that struct. 51# ENV_PATH -- [in] getenv(...) 52# ENV_PYTHONHOME -- [in] getenv(...) 53# ENV_PYTHONEXECUTABLE -- [in] getenv(...) 54# ENV___PYVENV_LAUNCHER__ -- [in] getenv(...) 55 56# ** Values calculated at runtime ** 57# config -- [in/out] dict of the PyConfig structure 58# real_executable -- [in, optional] resolved path to main process 59# On Windows and macOS, read directly from the running process 60# Otherwise, leave None and it will be calculated from executable 61# executable_dir -- [in, optional] real directory containing binary 62# If None, will be calculated from real_executable or executable 63# py_setpath -- [in] argument provided to Py_SetPath 64# If None, 'prefix' and 'exec_prefix' may be updated in config 65# library -- [in, optional] path of dylib/DLL/so 66# Only used for locating ._pth files 67# winreg -- [in, optional] the winreg module (only on Windows) 68 69# ****************************************************************************** 70# HIGH-LEVEL ALGORITHM 71# ****************************************************************************** 72 73# IMPORTANT: The code is the actual specification at time of writing. 74# This prose description is based on the original comment from the old 75# getpath.c to help capture the intent, but should not be considered 76# a specification. 77 78# Search in some common locations for the associated Python libraries. 79 80# Two directories must be found, the platform independent directory 81# (prefix), containing the common .py and .pyc files, and the platform 82# dependent directory (exec_prefix), containing the shared library 83# modules. Note that prefix and exec_prefix can be the same directory, 84# but for some installations, they are different. 85 86# This script carries out separate searches for prefix and exec_prefix. 87# Each search tries a number of different locations until a ``landmark'' 88# file or directory is found. If no prefix or exec_prefix is found, a 89# warning message is issued and the preprocessor defined PREFIX and 90# EXEC_PREFIX are used (even though they will not work); python carries on 91# as best as is possible, but most imports will fail. 92 93# Before any searches are done, the location of the executable is 94# determined. If Py_SetPath() was called, or if we are running on 95# Windows, the 'real_executable' path is used (if known). Otherwise, 96# we use the config-specified program name or default to argv[0]. 97# If this has one or more slashes in it, it is made absolute against 98# the current working directory. If it only contains a name, it must 99# have been invoked from the shell's path, so we search $PATH for the 100# named executable and use that. If the executable was not found on 101# $PATH (or there was no $PATH environment variable), the original 102# argv[0] string is used. 103 104# At this point, provided Py_SetPath was not used, the 105# __PYVENV_LAUNCHER__ variable may override the executable (on macOS, 106# the PYTHON_EXECUTABLE variable may also override). This allows 107# certain launchers that run Python as a subprocess to properly 108# specify the executable path. They are not intended for users. 109 110# Next, the executable location is examined to see if it is a symbolic 111# link. If so, the link is realpath-ed and the directory of the link 112# target is used for the remaining searches. The same steps are 113# performed for prefix and for exec_prefix, but with different landmarks. 114 115# Step 1. Are we running in a virtual environment? Unless 'home' has 116# been specified another way, check for a pyvenv.cfg and use its 'home' 117# property to override the executable dir used later for prefix searches. 118# We do not activate the venv here - that is performed later by site.py. 119 120# Step 2. Is there a ._pth file? A ._pth file lives adjacent to the 121# runtime library (if any) or the actual executable (not the symlink), 122# and contains precisely the intended contents of sys.path as relative 123# paths (to its own location). Its presence also enables isolated mode 124# and suppresses other environment variable usage. Unless already 125# specified by Py_SetHome(), the directory containing the ._pth file is 126# set as 'home'. 127 128# Step 3. Are we running python out of the build directory? This is 129# checked by looking for the BUILDDIR_TXT file, which contains the 130# relative path to the platlib dir. The executable_dir value is 131# derived from joining the VPATH preprocessor variable to the 132# directory containing pybuilddir.txt. If it is not found, the 133# BUILD_LANDMARK file is found, which is part of the source tree. 134# prefix is then found by searching up for a file that should only 135# exist in the source tree, and the stdlib dir is set to prefix/Lib. 136 137# Step 4. If 'home' is set, either by Py_SetHome(), ENV_PYTHONHOME, 138# a pyvenv.cfg file, ._pth file, or by detecting a build directory, it 139# is assumed to point to prefix and exec_prefix. $PYTHONHOME can be a 140# single directory, which is used for both, or the prefix and exec_prefix 141# directories separated by DELIM (colon on POSIX; semicolon on Windows). 142 143# Step 5. Try to find prefix and exec_prefix relative to executable_dir, 144# backtracking up the path until it is exhausted. This is the most common 145# step to succeed. Note that if prefix and exec_prefix are different, 146# exec_prefix is more likely to be found; however if exec_prefix is a 147# subdirectory of prefix, both will be found. 148 149# Step 6. Search the directories pointed to by the preprocessor variables 150# PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be 151# passed in as options to the configure script. 152 153# That's it! 154 155# Well, almost. Once we have determined prefix and exec_prefix, the 156# preprocessor variable PYTHONPATH is used to construct a path. Each 157# relative path on PYTHONPATH is prefixed with prefix. Then the directory 158# containing the shared library modules is appended. The environment 159# variable $PYTHONPATH is inserted in front of it all. On POSIX, if we are 160# in a build directory, both prefix and exec_prefix are reset to the 161# corresponding preprocessor variables (so sys.prefix will reflect the 162# installation location, even though sys.path points into the build 163# directory). This seems to make more sense given that currently the only 164# known use of sys.prefix and sys.exec_prefix is for the ILU installation 165# process to find the installed Python tree. 166 167# An embedding application can use Py_SetPath() to override all of 168# these automatic path computations. 169 170 171# ****************************************************************************** 172# PLATFORM CONSTANTS 173# ****************************************************************************** 174 175platlibdir = config.get('platlibdir') or PLATLIBDIR 176ABI_THREAD = ABI_THREAD or '' 177 178if os_name == 'posix' or os_name == 'darwin': 179 BUILDDIR_TXT = 'pybuilddir.txt' 180 BUILD_LANDMARK = 'Modules/Setup.local' 181 DEFAULT_PROGRAM_NAME = f'python{VERSION_MAJOR}' 182 STDLIB_SUBDIR = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}{ABI_THREAD}' 183 STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}/os.py', f'{STDLIB_SUBDIR}/os.pyc'] 184 PLATSTDLIB_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}{ABI_THREAD}/lib-dynload' 185 BUILDSTDLIB_LANDMARKS = ['Lib/os.py'] 186 VENV_LANDMARK = 'pyvenv.cfg' 187 ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}{ABI_THREAD}.zip' 188 DELIM = ':' 189 SEP = '/' 190 191elif os_name == 'nt': 192 BUILDDIR_TXT = 'pybuilddir.txt' 193 BUILD_LANDMARK = f'{VPATH}\\Modules\\Setup.local' 194 DEFAULT_PROGRAM_NAME = f'python' 195 STDLIB_SUBDIR = 'Lib' 196 STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}\\os.py', f'{STDLIB_SUBDIR}\\os.pyc'] 197 PLATSTDLIB_LANDMARK = f'{platlibdir}' 198 BUILDSTDLIB_LANDMARKS = ['Lib\\os.py'] 199 VENV_LANDMARK = 'pyvenv.cfg' 200 ZIP_LANDMARK = f'python{VERSION_MAJOR}{VERSION_MINOR}{PYDEBUGEXT or ""}.zip' 201 WINREG_KEY = f'SOFTWARE\\Python\\PythonCore\\{PYWINVER}\\PythonPath' 202 DELIM = ';' 203 SEP = '\\' 204 205 206# ****************************************************************************** 207# HELPER FUNCTIONS (note that we prefer C functions for performance) 208# ****************************************************************************** 209 210def search_up(prefix, *landmarks, test=isfile): 211 while prefix: 212 if any(test(joinpath(prefix, f)) for f in landmarks): 213 return prefix 214 prefix = dirname(prefix) 215 216 217# ****************************************************************************** 218# READ VARIABLES FROM config 219# ****************************************************************************** 220 221program_name = config.get('program_name') 222home = config.get('home') 223executable = config.get('executable') 224base_executable = config.get('base_executable') 225prefix = config.get('prefix') 226exec_prefix = config.get('exec_prefix') 227base_prefix = config.get('base_prefix') 228base_exec_prefix = config.get('base_exec_prefix') 229ENV_PYTHONPATH = config['pythonpath_env'] 230use_environment = config.get('use_environment', 1) 231 232pythonpath = config.get('module_search_paths') 233pythonpath_was_set = config.get('module_search_paths_set') 234stdlib_dir = config.get('stdlib_dir') 235stdlib_dir_was_set_in_config = bool(stdlib_dir) 236 237real_executable_dir = None 238platstdlib_dir = None 239 240# ****************************************************************************** 241# CALCULATE program_name 242# ****************************************************************************** 243 244if not program_name: 245 try: 246 program_name = config.get('orig_argv', [])[0] 247 except IndexError: 248 pass 249 250if not program_name: 251 program_name = DEFAULT_PROGRAM_NAME 252 253if EXE_SUFFIX and not hassuffix(program_name, EXE_SUFFIX) and isxfile(program_name + EXE_SUFFIX): 254 program_name = program_name + EXE_SUFFIX 255 256 257# ****************************************************************************** 258# CALCULATE executable 259# ****************************************************************************** 260 261if py_setpath: 262 # When Py_SetPath has been called, executable defaults to 263 # the real executable path. 264 if not executable: 265 executable = real_executable 266 267if not executable and SEP in program_name: 268 # Resolve partial path program_name against current directory 269 executable = abspath(program_name) 270 271if not executable: 272 # All platforms default to real_executable if known at this 273 # stage. POSIX does not set this value. 274 executable = real_executable 275elif os_name == 'darwin': 276 # QUIRK: On macOS we may know the real executable path, but 277 # if our caller has lied to us about it (e.g. most of 278 # test_embed), we need to use their path in order to detect 279 # whether we are in a build tree. This is true even if the 280 # executable path was provided in the config. 281 real_executable = executable 282 283if not executable and program_name and ENV_PATH: 284 # Resolve names against PATH. 285 # NOTE: The use_environment value is ignored for this lookup. 286 # To properly isolate, launch Python with a full path. 287 for p in ENV_PATH.split(DELIM): 288 p = joinpath(p, program_name) 289 if isxfile(p): 290 executable = p 291 break 292 293if not executable: 294 executable = '' 295 # When we cannot calculate the executable, subsequent searches 296 # look in the current working directory. Here, we emulate that 297 # (the former getpath.c would do it apparently by accident). 298 executable_dir = abspath('.') 299 # Also need to set this fallback in case we are running from a 300 # build directory with an invalid argv0 (i.e. test_sys.test_executable) 301 real_executable_dir = executable_dir 302 303if ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__: 304 # If set, these variables imply that we should be using them as 305 # sys.executable and when searching for venvs. However, we should 306 # use the argv0 path for prefix calculation 307 308 if os_name == 'darwin' and WITH_NEXT_FRAMEWORK: 309 # In a framework build the binary in {sys.exec_prefix}/bin is 310 # a stub executable that execs the real interpreter in an 311 # embedded app bundle. That bundle is an implementation detail 312 # and should not affect base_executable. 313 base_executable = f"{dirname(library)}/bin/python{VERSION_MAJOR}.{VERSION_MINOR}" 314 else: 315 # Use the real executable as our base, or argv[0] otherwise 316 # (on Windows, argv[0] is likely to be ENV___PYVENV_LAUNCHER__; on 317 # other platforms, real_executable is likely to be empty) 318 base_executable = real_executable or executable 319 320 if not real_executable: 321 real_executable = base_executable 322 #real_executable_dir = dirname(real_executable) 323 executable = ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__ 324 executable_dir = dirname(executable) 325 326 327# ****************************************************************************** 328# CALCULATE (default) home 329# ****************************************************************************** 330 331# Used later to distinguish between Py_SetPythonHome and other 332# ways that it may have been set 333home_was_set = False 334 335if home: 336 home_was_set = True 337elif use_environment and ENV_PYTHONHOME and not py_setpath: 338 home = ENV_PYTHONHOME 339 340 341# ****************************************************************************** 342# READ pyvenv.cfg 343# ****************************************************************************** 344 345venv_prefix = None 346 347# Calling Py_SetPythonHome(), Py_SetPath() or 348# setting $PYTHONHOME will override venv detection. 349if not home and not py_setpath: 350 try: 351 # prefix2 is just to avoid calculating dirname again later, 352 # as the path in venv_prefix is the more common case. 353 venv_prefix2 = executable_dir or dirname(executable) 354 venv_prefix = dirname(venv_prefix2) 355 try: 356 # Read pyvenv.cfg from one level above executable 357 pyvenvcfg = readlines(joinpath(venv_prefix, VENV_LANDMARK)) 358 except (FileNotFoundError, PermissionError): 359 # Try the same directory as executable 360 pyvenvcfg = readlines(joinpath(venv_prefix2, VENV_LANDMARK)) 361 venv_prefix = venv_prefix2 362 except (FileNotFoundError, PermissionError): 363 venv_prefix = None 364 pyvenvcfg = [] 365 366 for line in pyvenvcfg: 367 key, had_equ, value = line.partition('=') 368 if had_equ and key.strip().lower() == 'home': 369 executable_dir = real_executable_dir = value.strip() 370 if not base_executable: 371 # First try to resolve symlinked executables, since that may be 372 # more accurate than assuming the executable in 'home'. 373 try: 374 base_executable = realpath(executable) 375 if base_executable == executable: 376 # No change, so probably not a link. Clear it and fall back 377 base_executable = '' 378 except OSError: 379 pass 380 if not base_executable: 381 base_executable = joinpath(executable_dir, basename(executable)) 382 # It's possible "python" is executed from within a posix venv but that 383 # "python" is not available in the "home" directory as the standard 384 # `make install` does not create it and distros often do not provide it. 385 # 386 # In this case, try to fall back to known alternatives 387 if os_name != 'nt' and not isfile(base_executable): 388 base_exe = basename(executable) 389 for candidate in (DEFAULT_PROGRAM_NAME, f'python{VERSION_MAJOR}.{VERSION_MINOR}'): 390 candidate += EXE_SUFFIX if EXE_SUFFIX else '' 391 if base_exe == candidate: 392 continue 393 candidate = joinpath(executable_dir, candidate) 394 # Only set base_executable if the candidate exists. 395 # If no candidate succeeds, subsequent errors related to 396 # base_executable (like FileNotFoundError) remain in the 397 # context of the original executable name 398 if isfile(candidate): 399 base_executable = candidate 400 break 401 break 402 else: 403 venv_prefix = None 404 405 406# ****************************************************************************** 407# CALCULATE base_executable, real_executable AND executable_dir 408# ****************************************************************************** 409 410if not base_executable: 411 base_executable = executable or real_executable or '' 412 413if not real_executable: 414 real_executable = base_executable 415 416if real_executable: 417 try: 418 real_executable = realpath(real_executable) 419 except OSError as ex: 420 # Only warn if the file actually exists and was unresolvable 421 # Otherwise users who specify a fake executable may get spurious warnings. 422 if isfile(real_executable): 423 warn(f'Failed to find real location of {base_executable}') 424 425if not executable_dir and os_name == 'darwin' and library: 426 # QUIRK: macOS checks adjacent to its library early 427 library_dir = dirname(library) 428 if any(isfile(joinpath(library_dir, p)) for p in STDLIB_LANDMARKS): 429 # Exceptions here should abort the whole process (to match 430 # previous behavior) 431 executable_dir = realpath(library_dir) 432 real_executable_dir = executable_dir 433 434# If we do not have the executable's directory, we can calculate it. 435# This is the directory used to find prefix/exec_prefix if necessary. 436if not executable_dir and real_executable: 437 executable_dir = real_executable_dir = dirname(real_executable) 438 439# If we do not have the real executable's directory, we calculate it. 440# This is the directory used to detect build layouts. 441if not real_executable_dir and real_executable: 442 real_executable_dir = dirname(real_executable) 443 444# ****************************************************************************** 445# DETECT _pth FILE 446# ****************************************************************************** 447 448# The contents of an optional ._pth file are used to totally override 449# sys.path calculation. Its presence also implies isolated mode and 450# no-site (unless explicitly requested) 451pth = None 452pth_dir = None 453 454# Calling Py_SetPythonHome() or Py_SetPath() will override ._pth search, 455# but environment variables and command-line options cannot. 456if not py_setpath and not home_was_set: 457 # 1. Check adjacent to the main DLL/dylib/so (if set) 458 # 2. Check adjacent to the original executable 459 # 3. Check adjacent to our actual executable 460 # This may allow a venv to override the base_executable's 461 # ._pth file, but it cannot override the library's one. 462 for p in [library, executable, real_executable]: 463 if p: 464 if os_name == 'nt' and (hassuffix(p, 'exe') or hassuffix(p, 'dll')): 465 p = p.rpartition('.')[0] 466 p += '._pth' 467 try: 468 pth = readlines(p) 469 pth_dir = dirname(p) 470 break 471 except OSError: 472 pass 473 474 # If we found a ._pth file, disable environment and home 475 # detection now. Later, we will do the rest. 476 if pth_dir: 477 use_environment = 0 478 home = pth_dir 479 pythonpath = [] 480 481 482# ****************************************************************************** 483# CHECK FOR BUILD DIRECTORY 484# ****************************************************************************** 485 486build_prefix = None 487 488if ((not home_was_set and real_executable_dir and not py_setpath) 489 or config.get('_is_python_build', 0) > 0): 490 # Detect a build marker and use it to infer prefix, exec_prefix, 491 # stdlib_dir and the platstdlib_dir directories. 492 try: 493 platstdlib_dir = joinpath( 494 real_executable_dir, 495 readlines(joinpath(real_executable_dir, BUILDDIR_TXT))[0], 496 ) 497 build_prefix = joinpath(real_executable_dir, VPATH) 498 except IndexError: 499 # File exists but is empty 500 platstdlib_dir = real_executable_dir 501 build_prefix = joinpath(real_executable_dir, VPATH) 502 except (FileNotFoundError, PermissionError): 503 if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)): 504 build_prefix = joinpath(real_executable_dir, VPATH) 505 if os_name == 'nt': 506 # QUIRK: Windows builds need platstdlib_dir to be the executable 507 # dir. Normally the builddir marker handles this, but in this 508 # case we need to correct manually. 509 platstdlib_dir = real_executable_dir 510 511 if build_prefix: 512 if os_name == 'nt': 513 # QUIRK: No searching for more landmarks on Windows 514 build_stdlib_prefix = build_prefix 515 else: 516 build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) 517 # Use the build prefix for stdlib when not explicitly set 518 if not stdlib_dir_was_set_in_config: 519 if build_stdlib_prefix: 520 stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') 521 else: 522 stdlib_dir = joinpath(build_prefix, 'Lib') 523 # Only use the build prefix for prefix if it hasn't already been set 524 if not prefix: 525 prefix = build_stdlib_prefix 526 # Do not warn, because 'prefix' never equals 'build_prefix' on POSIX 527 #elif not venv_prefix and prefix != build_prefix: 528 # warn('Detected development environment but prefix is already set') 529 if not exec_prefix: 530 exec_prefix = build_prefix 531 # Do not warn, because 'exec_prefix' never equals 'build_prefix' on POSIX 532 #elif not venv_prefix and exec_prefix != build_prefix: 533 # warn('Detected development environment but exec_prefix is already set') 534 config['_is_python_build'] = 1 535 536 537# ****************************************************************************** 538# CALCULATE prefix AND exec_prefix 539# ****************************************************************************** 540 541if py_setpath: 542 # As documented, calling Py_SetPath will force both prefix 543 # and exec_prefix to the empty string. 544 prefix = exec_prefix = '' 545 546else: 547 # Read prefix and exec_prefix from explicitly set home 548 if home: 549 # When multiple paths are listed with ':' or ';' delimiters, 550 # split into prefix:exec_prefix 551 prefix, had_delim, exec_prefix = home.partition(DELIM) 552 if not had_delim: 553 exec_prefix = prefix 554 # Reset the standard library directory if it was not explicitly set 555 if not stdlib_dir_was_set_in_config: 556 stdlib_dir = None 557 558 559 # First try to detect prefix by looking alongside our runtime library, if known 560 if library and not prefix: 561 library_dir = dirname(library) 562 if ZIP_LANDMARK: 563 if os_name == 'nt': 564 # QUIRK: Windows does not search up for ZIP file 565 if isfile(joinpath(library_dir, ZIP_LANDMARK)): 566 prefix = library_dir 567 else: 568 prefix = search_up(library_dir, ZIP_LANDMARK) 569 if STDLIB_SUBDIR and STDLIB_LANDMARKS and not prefix: 570 if any(isfile(joinpath(library_dir, f)) for f in STDLIB_LANDMARKS): 571 prefix = library_dir 572 if not stdlib_dir_was_set_in_config: 573 stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) 574 575 576 # Detect prefix by looking for zip file 577 if ZIP_LANDMARK and executable_dir and not prefix: 578 if os_name == 'nt': 579 # QUIRK: Windows does not search up for ZIP file 580 if isfile(joinpath(executable_dir, ZIP_LANDMARK)): 581 prefix = executable_dir 582 else: 583 prefix = search_up(executable_dir, ZIP_LANDMARK) 584 if prefix and not stdlib_dir_was_set_in_config: 585 stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) 586 if not isdir(stdlib_dir): 587 stdlib_dir = None 588 589 590 # Detect prefix by searching from our executable location for the stdlib_dir 591 if STDLIB_SUBDIR and STDLIB_LANDMARKS and executable_dir and not prefix: 592 prefix = search_up(executable_dir, *STDLIB_LANDMARKS) 593 if prefix and not stdlib_dir: 594 stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) 595 596 if PREFIX and not prefix: 597 prefix = PREFIX 598 if not any(isfile(joinpath(prefix, f)) for f in STDLIB_LANDMARKS): 599 warn('Could not find platform independent libraries <prefix>') 600 601 if not prefix: 602 prefix = abspath('') 603 warn('Could not find platform independent libraries <prefix>') 604 605 606 # Detect exec_prefix by searching from executable for the platstdlib_dir 607 if PLATSTDLIB_LANDMARK and not exec_prefix: 608 if os_name == 'nt': 609 # QUIRK: Windows always assumed these were the same 610 # gh-100320: Our PYDs are assumed to be relative to the Lib directory 611 # (that is, prefix) rather than the executable (that is, executable_dir) 612 exec_prefix = prefix 613 if not exec_prefix and executable_dir: 614 exec_prefix = search_up(executable_dir, PLATSTDLIB_LANDMARK, test=isdir) 615 if not exec_prefix and EXEC_PREFIX: 616 exec_prefix = EXEC_PREFIX 617 if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)): 618 if os_name == 'nt': 619 # QUIRK: If DLLs is missing on Windows, don't warn, just assume 620 # that they're in exec_prefix 621 if not platstdlib_dir: 622 # gh-98790: We set platstdlib_dir here to avoid adding "DLLs" into 623 # sys.path when it doesn't exist in the platstdlib place, which 624 # would give Lib packages precedence over executable_dir where our 625 # PYDs *probably* live. Ideally, whoever changes our layout will tell 626 # us what the layout is, but in the past this worked, so it should 627 # keep working. 628 platstdlib_dir = exec_prefix 629 else: 630 warn('Could not find platform dependent libraries <exec_prefix>') 631 632 633 # Fallback: assume exec_prefix == prefix 634 if not exec_prefix: 635 exec_prefix = prefix 636 637 638 if not prefix or not exec_prefix: 639 warn('Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]') 640 641 642# For a venv, update the main prefix/exec_prefix but leave the base ones unchanged 643# XXX: We currently do not update prefix here, but it happens in site.py 644#if venv_prefix: 645# base_prefix = prefix 646# base_exec_prefix = exec_prefix 647# prefix = exec_prefix = venv_prefix 648 649 650# ****************************************************************************** 651# UPDATE pythonpath (sys.path) 652# ****************************************************************************** 653 654if py_setpath: 655 # If Py_SetPath was called then it overrides any existing search path 656 config['module_search_paths'] = py_setpath.split(DELIM) 657 config['module_search_paths_set'] = 1 658 659elif not pythonpath_was_set: 660 # If pythonpath was already explicitly set or calculated, we leave it alone. 661 # This won't matter in normal use, but if an embedded host is trying to 662 # recalculate paths while running then we do not want to change it. 663 pythonpath = [] 664 665 # First add entries from the process environment 666 if use_environment and ENV_PYTHONPATH: 667 for p in ENV_PYTHONPATH.split(DELIM): 668 pythonpath.append(abspath(p)) 669 670 # Then add the default zip file 671 if os_name == 'nt': 672 # QUIRK: Windows uses the library directory rather than the prefix 673 if library: 674 library_dir = dirname(library) 675 else: 676 library_dir = executable_dir 677 pythonpath.append(joinpath(library_dir, ZIP_LANDMARK)) 678 elif build_prefix: 679 # QUIRK: POSIX uses the default prefix when in the build directory 680 pythonpath.append(joinpath(PREFIX, ZIP_LANDMARK)) 681 else: 682 pythonpath.append(joinpath(prefix, ZIP_LANDMARK)) 683 684 if os_name == 'nt' and use_environment and winreg: 685 # QUIRK: Windows also lists paths in the registry. Paths are stored 686 # as the default value of each subkey of 687 # {HKCU,HKLM}\Software\Python\PythonCore\{winver}\PythonPath 688 # where winver is sys.winver (typically '3.x' or '3.x-32') 689 for hk in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE): 690 try: 691 key = winreg.OpenKeyEx(hk, WINREG_KEY) 692 try: 693 i = 0 694 while True: 695 try: 696 v = winreg.QueryValue(key, winreg.EnumKey(key, i)) 697 except OSError: 698 break 699 if isinstance(v, str): 700 pythonpath.extend(v.split(DELIM)) 701 i += 1 702 # Paths from the core key get appended last, but only 703 # when home was not set and we haven't found our stdlib 704 # some other way. 705 if not home and not stdlib_dir: 706 v = winreg.QueryValue(key, None) 707 if isinstance(v, str): 708 pythonpath.extend(v.split(DELIM)) 709 finally: 710 winreg.CloseKey(key) 711 except OSError: 712 pass 713 714 # Then add any entries compiled into the PYTHONPATH macro. 715 if PYTHONPATH: 716 for p in PYTHONPATH.split(DELIM): 717 pythonpath.append(joinpath(prefix, p)) 718 719 # Then add stdlib_dir and platstdlib_dir 720 if not stdlib_dir and prefix: 721 stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) 722 if not platstdlib_dir and exec_prefix: 723 platstdlib_dir = joinpath(exec_prefix, PLATSTDLIB_LANDMARK) 724 725 if os_name == 'nt': 726 # QUIRK: Windows generates paths differently 727 if platstdlib_dir: 728 pythonpath.append(platstdlib_dir) 729 if stdlib_dir: 730 pythonpath.append(stdlib_dir) 731 if executable_dir and executable_dir not in pythonpath: 732 # QUIRK: the executable directory is on sys.path 733 # We keep it low priority, so that properly installed modules are 734 # found first. It may be earlier in the order if we found some 735 # reason to put it there. 736 pythonpath.append(executable_dir) 737 else: 738 if stdlib_dir: 739 pythonpath.append(stdlib_dir) 740 if platstdlib_dir: 741 pythonpath.append(platstdlib_dir) 742 743 config['module_search_paths'] = pythonpath 744 config['module_search_paths_set'] = 1 745 746 747# ****************************************************************************** 748# POSIX prefix/exec_prefix QUIRKS 749# ****************************************************************************** 750 751# QUIRK: Non-Windows replaces prefix/exec_prefix with defaults when running 752# in build directory. This happens after pythonpath calculation. 753if os_name != 'nt' and build_prefix: 754 prefix = config.get('prefix') or PREFIX 755 exec_prefix = config.get('exec_prefix') or EXEC_PREFIX or prefix 756 757 758# ****************************************************************************** 759# SET pythonpath FROM _PTH FILE 760# ****************************************************************************** 761 762if pth: 763 config['isolated'] = 1 764 config['use_environment'] = 0 765 config['site_import'] = 0 766 config['safe_path'] = 1 767 pythonpath = [] 768 for line in pth: 769 line = line.partition('#')[0].strip() 770 if not line: 771 pass 772 elif line == 'import site': 773 config['site_import'] = 1 774 elif line.startswith('import '): 775 warn("unsupported 'import' line in ._pth file") 776 else: 777 pythonpath.append(joinpath(pth_dir, line)) 778 config['module_search_paths'] = pythonpath 779 config['module_search_paths_set'] = 1 780 781# ****************************************************************************** 782# UPDATE config FROM CALCULATED VALUES 783# ****************************************************************************** 784 785config['program_name'] = program_name 786config['home'] = home 787config['executable'] = executable 788config['base_executable'] = base_executable 789config['prefix'] = prefix 790config['exec_prefix'] = exec_prefix 791config['base_prefix'] = base_prefix or prefix 792config['base_exec_prefix'] = base_exec_prefix or exec_prefix 793 794config['platlibdir'] = platlibdir 795# test_embed expects empty strings, not None 796config['stdlib_dir'] = stdlib_dir or '' 797config['platstdlib_dir'] = platstdlib_dir or '' 798