diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 209d37095a6c0b..797615c915c3d5 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -1018,6 +1018,17 @@ def res2int(self, res): out = res.out.strip().decode("utf-8") return tuple(int(i) for i in out.split()) + def test_dump_path_config(self): + # gh-151253: At the first import (import encodings) during Python + # startup, if the import fails, dump the Python path configuration. + nonexistent = '/nonexistent-python-path' + # Use -X frozen_modules=off to disable frozen encodings module + # on release build. + cmd = ["-X", "frozen_modules=off", "-c", "pass"] + proc = assert_python_failure(*cmd, PYTHONHOME=nonexistent) + self.assertIn(b'Python path configuration:', proc.err) + self.assertIn(f"PYTHONHOME = '{nonexistent}'".encode(), proc.err) + @unittest.skipIf(interpreter_requires_environment(), 'Cannot run -I tests when PYTHON env vars are required.') diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-42-46.gh-issue-151253.7MMQ8P.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-42-46.gh-issue-151253.7MMQ8P.rst new file mode 100644 index 00000000000000..56d2f3b2633bb0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-10-15-42-46.gh-issue-151253.7MMQ8P.rst @@ -0,0 +1,3 @@ +If ``import encodings`` (first import) fails at Python startup, dump the +Python path configuration to help users debugging their configuration. Patch +by Victor Stinner. diff --git a/Python/codecs.c b/Python/codecs.c index d2e3f25157144a..6fa68cdbda71a5 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -10,6 +10,7 @@ Copyright (c) Corporation for National Research Initiatives. #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_initconfig.h" // _Py_DumpPathConfig() #include "pycore_interp.h" // PyInterpreterState.codec_search_path #include "pycore_lock.h" // PyMutex #include "pycore_pyerrors.h" // _PyErr_FormatNote() @@ -1504,6 +1505,8 @@ _PyCodec_InitRegistry(PyInterpreterState *interp) // search functions, so this is done after everything else is initialized. PyObject *mod = PyImport_ImportModule("encodings"); if (mod == NULL) { + PyThreadState *tstate = _PyThreadState_GET(); + _Py_DumpPathConfig(tstate); return PyStatus_Error("Failed to import encodings module"); } Py_DECREF(mod);