aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/feature_select.cpp
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2023-08-11 12:56:02 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-03-05 13:37:19 +0100
commit546548acc550e716ec82551c30108eabab87f740 (patch)
treeafa629104b0645a7bf47ca4e6ac213cd077ea35a /sources/pyside6/libpyside/feature_select.cpp
parentfb0270f39de6ed190a114b8b87afe9ba9b4d93b1 (diff)
Feature: Prepare feature and signature modules to stand lazy init
When lazy initialization is used, unexpected situations are coming up. The feature switching may call into signature init without knowledge that feature dicts are already switched. Fix this by - disabling feature switching during lazy init of a class - allow this disabling from PySide and Shiboken - Create a way to find the unchanged type dict of features UPDATE: Switching speed is now as high as before. This check-in was extracted after the fact, although it claims to exist beforehand which would have been better. This was quite a painful experience. Change-Id: I6639b7a3c22d21d3b9dd0627e2880a7b7a03d134 Task-number: PYSIDE-1019 Task-number: PYSIDE-2404 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'sources/pyside6/libpyside/feature_select.cpp')
-rw-r--r--sources/pyside6/libpyside/feature_select.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp
index 3f8e38870..cfd465267 100644
--- a/sources/pyside6/libpyside/feature_select.cpp
+++ b/sources/pyside6/libpyside/feature_select.cpp
@@ -107,7 +107,7 @@ createDerivedDictType()
PyObject *ChameleonDict = PepRun_GetResult(R"CPP(if True:
class ChameleonDict(dict):
- __slots__ = ("dict_ring", "select_id")
+ __slots__ = ("dict_ring", "select_id", "orig_dict")
result = ChameleonDict
@@ -172,9 +172,9 @@ static bool replaceClassDict(PyTypeObject *type)
// insert the dict into itself as ring
setNextDict(new_dict, new_dict);
// We have now an exact copy of the dict with a new type.
- // Replace `__dict__` which usually has refcount 1 (but see cyclic_test.py)
- Py_DECREF(PepType_GetDict(type));
PepType_SetDict(type, new_dict);
+ // PYSIDE-2404: Retain the original dict for easy late init.
+ PyObject_SetAttr(new_dict, PySideName::orig_dict(), dict);
return true;
}
@@ -185,6 +185,7 @@ static bool addNewDict(PyTypeObject *type, int select_id)
* A 'false' return is fatal.
*/
AutoDecRef dict(PepType_GetDict(type));
+ AutoDecRef orig_dict(PyObject_GetAttr(dict, PySideName::orig_dict()));
auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type);
auto *new_dict = PyObject_CallObject(ob_ndt, nullptr);
if (new_dict == nullptr)
@@ -195,6 +196,8 @@ static bool addNewDict(PyTypeObject *type, int select_id)
setNextDict(dict, new_dict);
setNextDict(new_dict, next_dict);
PepType_SetDict(type, new_dict);
+ // PYSIDE-2404: Retain the original dict for easy late init.
+ PyObject_SetAttr(new_dict, PySideName::orig_dict(), orig_dict);
return true;
}
@@ -393,12 +396,18 @@ static FeatureProc featureProcArray[] = {
static bool patch_property_impl();
static bool is_initialized = false;
+static void featureEnableCallback(bool enable)
+{
+ featurePointer = enable ? featureProcArray : nullptr;
+}
+
void init()
{
// This function can be called multiple times.
if (!is_initialized) {
featurePointer = featureProcArray;
initSelectableFeature(SelectFeatureSet);
+ setSelectableFeatureCallback(featureEnableCallback);
patch_property_impl();
is_initialized = true;
}