diff options
| author | Christian Tismer <tismer@stackless.com> | 2025-03-22 11:58:48 +0100 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2025-03-24 11:46:30 +0000 |
| commit | 99cdacf4e767207e94d803861842dd2147233512 (patch) | |
| tree | 9b7bf74bdc493611c3248c5c8b33682b6d145b07 | |
| parent | f089e00ae9de0d28507d6c10c6e3ecbe9882bbf8 (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.cpp | 18 |
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; } |
