https://github.com/python/cpython/commit/7267c9b8f4973bf5be785ebf3ddb9624ed5d4446
commit: 7267c9b8f4973bf5be785ebf3ddb9624ed5d4446
branch: 3.14
author: Kirill Podoprigora <[email protected]>
committer: Eclips4 <[email protected]>
date: 2026-08-25T00:11:08+03:00
summary:
[3.14] gh-156126: Fix crash in -X importtime with unencodable module … (#156330)
[3.14] gh-156126: Fix crash in -X importtime with unencodable module names
(GH-156137)
(cherry picked from commit 3a5aa685885d8a2103f7d8de17481be64bc84dfb)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-08-20-22-13-20.gh-issue-156126.pXm4Qr.rst
M Lib/test/test_cmd_line.py
M Python/import.c
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index adc665135576d46..e101d54cf04171f 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -1225,6 +1225,24 @@ def test_import_time(self):
assert_python_failure('-X', 'importtime=-1', '-c', code)
assert_python_failure('-X', 'importtime=3', '-c', code)
+ def test_import_time_unencodable_module_name(self):
+ code = textwrap.dedent("""
+ import sys, types
+ name = 'mod\\ud800'
+ sys.modules[name] = types.ModuleType(name)
+ __import__(name)
+ try:
+ __import__('nonexistent\\ud800')
+ except ModuleNotFoundError:
+ pass
+ """)
+ res = assert_python_ok('-X', 'importtime=2', '-c', code)
+ res_err = res.err.decode('utf-8')
+ self.assertRegex(res_err,
+ r'import time: cached\s* \| cached\s* \| mod\\ud800')
+ self.assertRegex(res_err,
+ r'import time: \s*\d+ \| \s*\d+ \|
\s*nonexistent\\ud800')
+
def res2int(self, res):
out = res.out.strip().decode("utf-8")
return tuple(int(i) for i in out.split())
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-08-20-22-13-20.gh-issue-156126.pXm4Qr.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-20-22-13-20.gh-issue-156126.pXm4Qr.rst
new file mode 100644
index 000000000000000..d8cfefb86b06dd2
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-20-22-13-20.gh-issue-156126.pXm4Qr.rst
@@ -0,0 +1,3 @@
+Fix a crash when importing a module whose name contains characters that
+cannot be encoded to UTF-8 (such as lone surrogates) while :option:`-X
+importtime <-X>` is enabled.
diff --git a/Python/import.c b/Python/import.c
index d18ca3d87e09ebd..fded9a3e849f67c 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -241,6 +241,19 @@ import_get_module(PyThreadState *tstate, PyObject *name)
return m;
}
+static PyObject *
+get_importtime_name(PyObject *name)
+{
+ PyObject *exc = PyErr_GetRaisedException();
+ PyObject *encoded = PyUnicode_AsEncodedString(name, "utf-8",
+ "backslashreplace");
+ if (encoded == NULL) {
+ PyErr_Clear();
+ }
+ PyErr_SetRaisedException(exc);
+ return encoded;
+}
+
static int
import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject
*name)
{
@@ -278,8 +291,11 @@ import_ensure_initialized(PyInterpreterState *interp,
PyObject *mod, PyObject *n
if (_PyInterpreterState_GetConfig(interp)->import_time == 2) {
_IMPORT_TIME_HEADER(interp);
#define import_level FIND_AND_LOAD(interp).import_level
+ PyObject *encoded_name = get_importtime_name(name);
fprintf(stderr, "import time: cached | cached | %*s\n",
- import_level*2, PyUnicode_AsUTF8(name));
+ import_level*2,
+ encoded_name != NULL ? PyBytes_AS_STRING(encoded_name) : "?");
+ Py_XDECREF(encoded_name);
#undef import_level
}
@@ -3782,10 +3798,13 @@ import_find_and_load(PyThreadState *tstate, PyObject
*abs_name)
PyTime_t cum = t2 - t1;
import_level--;
+ PyObject *encoded_name = get_importtime_name(abs_name);
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
(long)_PyTime_AsMicroseconds(cum - accumulated,
_PyTime_ROUND_CEILING),
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
- import_level*2, "", PyUnicode_AsUTF8(abs_name));
+ import_level*2, "",
+ encoded_name != NULL ? PyBytes_AS_STRING(encoded_name) : "?");
+ Py_XDECREF(encoded_name);
accumulated = accumulated_copy + cum;
}
_______________________________________________
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]