diff options
| author | Christian Tismer <tismer@stackless.com> | 2023-08-11 12:56:02 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-03-05 13:37:19 +0100 |
| commit | 546548acc550e716ec82551c30108eabab87f740 (patch) | |
| tree | afa629104b0645a7bf47ca4e6ac213cd077ea35a /sources/pyside6/libpyside/feature_select.cpp | |
| parent | fb0270f39de6ed190a114b8b87afe9ba9b4d93b1 (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.cpp | 15 |
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; } |
