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