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
174 platlibdir = config.get('platlibdir') or PLATLIBDIR
175
176 if 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
189 elif 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
208 def 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
219 program_name = config.get('program_name')
220 home = config.get('home')
221 executable = config.get('executable')
222 base_executable = config.get('base_executable')
223 prefix = config.get('prefix')
224 exec_prefix = config.get('exec_prefix')
225 base_prefix = config.get('base_prefix')
226 base_exec_prefix = config.get('base_exec_prefix')
227 ENV_PYTHONPATH = config['pythonpath_env']
228 use_environment = config.get('use_environment', 1)
229
230 pythonpath = config.get('module_search_paths')
231 pythonpath_was_set = config.get('module_search_paths_set')
232
233 real_executable_dir = None
234 stdlib_dir = None
235 platstdlib_dir = None
236
237 # ******************************************************************************
238 # CALCULATE program_name
239 # ******************************************************************************
240
241 program_name_was_set = bool(program_name)
242
243 if not program_name:
244 try:
245 program_name = config.get('orig_argv', [])[0]
246 except IndexError:
247 pass
248
249 if not program_name:
250 program_name = DEFAULT_PROGRAM_NAME
251
252 if 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
260 if 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
266 if not executable and SEP in program_name:
267 # Resolve partial path program_name against current directory
268 executable = abspath(program_name)
269
270 if 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
274 elif 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
282 if 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
292 if 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
302 if 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
329 home_was_set = False
330
331 if home:
332 home_was_set = True
333 elif use_environment and ENV_PYTHONHOME and not py_setpath:
334 home = ENV_PYTHONHOME
335
336
337 # ******************************************************************************
338 # READ pyvenv.cfg
339 # ******************************************************************************
340
341 venv_prefix = None
342
343 # Calling Py_SetPythonHome(), Py_SetPath() or
344 # setting $PYTHONHOME will override venv detection.
345 if 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
406 if not base_executable:
407 base_executable = executable or real_executable or ''
408
409 if not real_executable:
410 real_executable = base_executable
411
412 try:
413 real_executable = realpath(real_executable)
414 except 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
420 if 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.
431 if 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.
436 if 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 calculation. Its presence also implies isolated mode and
445 # no-site (unless explicitly requested)
446 pth = None
447 pth_dir = None
448
449 # Calling Py_SetPythonHome() or Py_SetPath() will override ._pth search,
450 # but environment variables and command-line options cannot.
451 if 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
481 build_prefix = None
482
483 if ((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
535 if 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
540 else:
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
646 if 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
651 elif 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.
745 if 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
754 if 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
777 config['program_name'] = program_name
778 config['home'] = home
779 config['executable'] = executable
780 config['base_executable'] = base_executable
781 config['prefix'] = prefix
782 config['exec_prefix'] = exec_prefix
783 config['base_prefix'] = base_prefix or prefix
784 config['base_exec_prefix'] = base_exec_prefix or exec_prefix
785
786 config['platlibdir'] = platlibdir
787 # test_embed expects empty strings, not None
788 config['stdlib_dir'] = stdlib_dir or ''
789 config['platstdlib_dir'] = platstdlib_dir or ''