aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2025-03-22 11:58:48 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2025-03-24 11:46:30 +0000
commit99cdacf4e767207e94d803861842dd2147233512 (patch)
tree9b7bf74bdc493611c3248c5c8b33682b6d145b07
parentf089e00ae9de0d28507d6c10c6e3ecbe9882bbf8 (diff)
feature: Fix regression when PySide is imported with trace set
The feature switching redirects imports in order to support the "from __feature__ import" construct. When no feature is involved, the original function and some post processing is called. When settrace is used before the Shiboken import, we see infinite recursion in Python 3.13. An optimization in updatecache now calls import itself, which then runs the feature machinery recursively. Instead of only calling the original import, temporarily switch the whole import redirection back to the original. Change-Id: Ie3c2e24467ca456b0e731db2696a0b2ab80c6174 Fixes: PYSIDE-3054 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit 8ac20831238e9399d51d86847cab400c58ee4d51) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit b4706d78785eee50c803ea9752d6c03a367319b4) (cherry picked from commit d02f57c67fbebea4f2c080b792e09bcbc7785e3a)
-rw-r--r--sources/shiboken6/libshiboken/signature/signature.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/sources/shiboken6/libshiboken/signature/signature.cpp b/sources/shiboken6/libshiboken/signature/signature.cpp
index 81f464cd3..a783d16f2 100644
--- a/sources/shiboken6/libshiboken/signature/signature.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature.cpp
@@ -303,11 +303,18 @@ static PyObject *feature_import(PyObject * /* self */, PyObject *args, PyObject
// feature_import did not handle it, so call the normal import.
Py_DECREF(ret);
static PyObject *builtins = PyEval_GetBuiltins();
- PyObject *import_func = PyDict_GetItemString(builtins, "__orig_import__");
- if (import_func == nullptr) {
+ PyObject *origImportFunc = PyDict_GetItemString(builtins, "__orig_import__");
+ if (origImportFunc == nullptr) {
Py_FatalError("builtins has no \"__orig_import__\" function");
}
- ret = PyObject_Call(import_func, args, kwds);
+ // PYSIDE-3054: Instead of just calling the original import, we temporarily
+ // reset the whole import function to the previous version.
+ // This prevents unforeseen recursions like in settrace.
+ PyObject *featureImportFunc = PyDict_GetItemString(builtins, "__import__");
+ Py_INCREF(origImportFunc);
+ Py_INCREF(featureImportFunc);
+ PyDict_SetItemString(builtins, "__import__", origImportFunc);
+ ret = PyObject_Call(origImportFunc, args, kwds);
if (ret) {
// PYSIDE-2029: Intercept after the import to search for PySide usage.
PyObject *post = PyObject_CallFunctionObjArgs(pyside_globals->feature_imported_func,
@@ -315,9 +322,12 @@ static PyObject *feature_import(PyObject * /* self */, PyObject *args, PyObject
Py_XDECREF(post);
if (post == nullptr) {
Py_DECREF(ret);
- return nullptr;
+ ret = nullptr;
}
}
+ PyDict_SetItemString(builtins, "__import__", featureImportFunc);
+ Py_DECREF(origImportFunc);
+ Py_DECREF(featureImportFunc);
return ret;
}