https://github.com/python/cpython/commit/3ab39d2308c591b8dcee60e5e733ab0b5e5d8ad3
commit: 3ab39d2308c591b8dcee60e5e733ab0b5e5d8ad3
branch: main
author: Filipe LaĆns <[email protected]>
committer: FFY00 <[email protected]>
date: 2026-03-02T18:51:45Z
summary:
GH-145273: warn when we can't find the standard library (#145274)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst
M Lib/test/support/__init__.py
M Lib/test/test_embed.py
M Modules/getpath.py
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..b3f0cb5d35de5d 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -1491,8 +1491,12 @@ def test_init_setpythonhome(self):
}
self.default_program_name(config)
env = {'TESTHOME': home, 'PYTHONPATH': paths_str}
+ # When running from source, TESTHOME will be the build directory, which
+ # isn't a valid home unless _is_python_build is set. getpath will then
+ # fail to find the standard library and show a warning, so we need to
+ # ignore stderr.
self.check_all_configs("test_init_setpythonhome", config,
- api=API_COMPAT, env=env)
+ api=API_COMPAT, env=env, ignore_stderr=True)
def test_init_is_python_build_with_home(self):
# Test _Py_path_config._is_python_build configuration (gh-91985)
@@ -1528,15 +1532,26 @@ def test_init_is_python_build_with_home(self):
'exec_prefix': exec_prefix,
'base_exec_prefix': exec_prefix,
'pythonpath_env': paths_str,
- 'stdlib_dir': stdlib,
+ 'stdlib_dir': stdlib, # Only correct on _is_python_build==0!
}
# The code above is taken from test_init_setpythonhome()
env = {'TESTHOME': home, 'PYTHONPATH': paths_str}
env['NEGATIVE_ISPYTHONBUILD'] = '1'
config['_is_python_build'] = 0
+ # This configuration doesn't set a valid stdlibdir/plststdlibdir
because
+ # with _is_python_build=0 getpath doesn't check for the build directory
+ # landmarks in PYTHONHOME/Py_SetPythonHome.
+ # getpath correctly shows a warning, which messes up check_all_configs,
+ # so we need to ignore stderr.
self.check_all_configs("test_init_is_python_build", config,
- api=API_COMPAT, env=env)
+ api=API_COMPAT, env=env, ignore_stderr=True)
+
+ # config['stdlib_dir'] = os.path.join(home, 'Lib')
+ # FIXME: This test does not check if stdlib_dir is calculated
correctly.
+ # test_init_is_python_build runs the initialization twice,
+ # setting stdlib_dir in _Py_path_config on the first run, which
+ # then overrides the stdlib_dir calculation (as of GH-108730).
env['NEGATIVE_ISPYTHONBUILD'] = '0'
config['_is_python_build'] = 1
@@ -1551,8 +1566,14 @@ def test_init_is_python_build_with_home(self):
expected_paths[0] = self.module_search_paths(prefix=prefix)[0]
config.update(prefix=prefix, base_prefix=prefix,
exec_prefix=exec_prefix,
base_exec_prefix=exec_prefix)
+ # This also shows the bad stdlib warning, getpath is run twice. The
+ # first time with _is_python_build=0, which results in the warning just
+ # as explained above. However, the second time a valid standard library
+ # should be found, but the stdlib_dir is cached in _Py_path_config from
+ # the first run, which ovewrites it, so it also shows the warning.
+ # Also ignore stderr.
self.check_all_configs("test_init_is_python_build", config,
- api=API_COMPAT, env=env)
+ api=API_COMPAT, env=env, ignore_stderr=True)
def copy_paths_by_env(self, config):
all_configs = self._get_expected_config()
@@ -1612,6 +1633,7 @@ def test_init_pybuilddir_win32(self):
prefix = os.path.normpath(os.path.join(tmpdir, vpath))
# The stdlib dir is dirname(executable) + VPATH + 'Lib'
stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib'))
+ os.mkdir(stdlibdir)
filename = os.path.join(tmpdir, 'pybuilddir.txt')
with open(filename, "w", encoding="utf8") as fp:
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
#
******************************************************************************
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]