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