Skip to content

Commit 7b6e989

Browse files
authored
gh-151253: Dump the Python path configuration on _PyCodec_InitRegistry() failure (#151250)
If "import encodings" fails at Python startup, dump the Python path configuration to help users debugging their configuration. The encodings module is the first module imported during Python startup.
1 parent 9fd1a12 commit 7b6e989

3 files changed

Lines changed: 17 additions & 0 deletions

File tree

Lib/test/test_cmd_line.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,17 @@ def test_presite(self):
13141314
proc = assert_python_ok("-X", f"presite={entrypoint}", "-c", "pass")
13151315
self.assertEqual(proc.out.rstrip(), b"presite func")
13161316

1317+
def test_dump_path_config(self):
1318+
# gh-151253: At the first import (import encodings) during Python
1319+
# startup, if the import fails, dump the Python path configuration.
1320+
nonexistent = '/nonexistent-python-path'
1321+
# Use -X frozen_modules=off to disable frozen encodings module
1322+
# on release build.
1323+
cmd = ["-X", "frozen_modules=off", "-c", "pass"]
1324+
proc = assert_python_failure(*cmd, PYTHONHOME=nonexistent)
1325+
self.assertIn(b'Python path configuration:', proc.err)
1326+
self.assertIn(f"PYTHONHOME = '{nonexistent}'".encode(), proc.err)
1327+
13171328

13181329
@unittest.skipIf(interpreter_requires_environment(),
13191330
'Cannot run -I tests when PYTHON env vars are required.')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
If ``import encodings`` (first import) fails at Python startup, dump the
2+
Python path configuration to help users debugging their configuration. Patch
3+
by Victor Stinner.

Python/codecs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Copyright (c) Corporation for National Research Initiatives.
1111
#include "Python.h"
1212
#include "pycore_call.h" // _PyObject_CallNoArgs()
1313
#include "pycore_codecs.h" // export _PyCodec_LookupTextEncoding()
14+
#include "pycore_initconfig.h" // _Py_DumpPathConfig()
1415
#include "pycore_interp.h" // PyInterpreterState.codec_search_path
1516
#include "pycore_pyerrors.h" // _PyErr_FormatNote()
1617
#include "pycore_pystate.h" // _PyInterpreterState_GET()
@@ -1686,6 +1687,8 @@ _PyCodec_InitRegistry(PyInterpreterState *interp)
16861687
// search functions, so this is done after everything else is initialized.
16871688
PyObject *mod = PyImport_ImportModule("encodings");
16881689
if (mod == NULL) {
1690+
PyThreadState *tstate = _PyThreadState_GET();
1691+
_Py_DumpPathConfig(tstate);
16891692
return PyStatus_Error("Failed to import encodings module");
16901693
}
16911694
Py_DECREF(mod);

0 commit comments

Comments
 (0)