diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 307bac65ae50a8..d4d3c7f1aefa66 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1716,9 +1716,10 @@ def _platform_specific(self): )) self._env = {k.upper(): os.getenv(k) for k in os.environ} - self._env["PYTHONHOME"] = os.path.dirname(self.real) + home = os.path.dirname(self.real) if sysconfig.is_python_build(): - self._env["PYTHONPATH"] = STDLIB_DIR + home = os.path.join(home, sysconfig.get_config_var('VPATH')) + self._env["PYTHONHOME"] = home else: def _platform_specific(self): pass diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 35246d7c484439..a8ff40222ae46a 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1479,6 +1479,10 @@ def test_init_setpythonhome(self): stdlib = os.path.join(home, sys.platlibdir, f'python{version}{ABI_THREAD}') expected_paths = self.module_search_paths(prefix=home, exec_prefix=home) + # Create the expected paths to avoid the bad stdlib dir warning + for entry in expected_paths: + os.makedirs(entry, exist_ok=True) + config = { 'home': home, 'module_search_paths': expected_paths, @@ -1520,6 +1524,10 @@ def test_init_is_python_build_with_home(self): stdlib = os.path.join(home, sys.platlibdir, f'python{version}{ABI_THREAD}') expected_paths = self.module_search_paths(prefix=home, exec_prefix=home) + # Create the expected paths to avoid the bad stdlib dir warning + for entry in expected_paths: + os.makedirs(entry, exist_ok=True) + config = { 'home': home, 'module_search_paths': expected_paths, @@ -1575,6 +1583,8 @@ def test_init_pybuilddir(self): # The stdlib dir is dirname(executable) + VPATH + 'Lib' stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib')) os.mkdir(libdir) + # Create the directory to avoid the bad stdlib dir warning + os.makedirs(stdlibdir) filename = os.path.join(tmpdir, 'pybuilddir.txt') with open(filename, "w", encoding="utf8") as fp: @@ -1613,6 +1623,9 @@ def test_init_pybuilddir_win32(self): # The stdlib dir is dirname(executable) + VPATH + 'Lib' stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib')) + # Create the directory to avoid the bad stdlib dir warning + os.makedirs(stdlibdir) + filename = os.path.join(tmpdir, 'pybuilddir.txt') with open(filename, "w", encoding="utf8") as fp: fp.write(tmpdir) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst new file mode 100644 index 00000000000000..8d9e4a872d0d7a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst @@ -0,0 +1,2 @@ +A warning is now shown during :ref:`sys-path-init` if it can't find a valid +standard library. diff --git a/Modules/getpath.py b/Modules/getpath.py index ceb605a75c85f4..e06297b7b63a7b 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -236,6 +236,7 @@ def search_up(prefix, *landmarks, test=isfile): real_executable_dir = None platstdlib_dir = None +stdlib_zip = None # ****************************************************************************** # CALCULATE program_name @@ -697,12 +698,13 @@ def search_up(prefix, *landmarks, test=isfile): library_dir = dirname(library) else: library_dir = executable_dir - pythonpath.append(joinpath(library_dir, ZIP_LANDMARK)) + stdlib_zip = joinpath(library_dir, ZIP_LANDMARK) elif build_prefix: # QUIRK: POSIX uses the default prefix when in the build directory - pythonpath.append(joinpath(PREFIX, ZIP_LANDMARK)) + stdlib_zip = joinpath(PREFIX, ZIP_LANDMARK) else: - pythonpath.append(joinpath(base_prefix, ZIP_LANDMARK)) + stdlib_zip = joinpath(base_prefix, ZIP_LANDMARK) + pythonpath.append(stdlib_zip) if os_name == 'nt' and use_environment and winreg: # QUIRK: Windows also lists paths in the registry. Paths are stored @@ -767,6 +769,21 @@ def search_up(prefix, *landmarks, test=isfile): config['module_search_paths_set'] = 1 +# ****************************************************************************** +# SANITY CHECKS +# ****************************************************************************** + +# Warn if the standard library is missing +if not stdlib_zip or not isfile(stdlib_zip): + home_hint = f"The Python 'home' directory was set to {home!r}, is this correct?" + if not stdlib_dir or not isdir(stdlib_dir): + hint = home_hint if home else f'sys.prefix is set to {prefix}, is this correct?' + warn('WARN: Could not find the standard library directory! ' + hint) + elif (not platstdlib_dir and not build_prefix) or not isdir(platstdlib_dir): + hint = home_hint if home else f'sys.exec_prefix is set to {exec_prefix}, is this correct?' + warn('WARN: Could not find the platform standard library directory! ' + hint) + + # ****************************************************************************** # POSIX prefix/exec_prefix QUIRKS # ******************************************************************************