aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/feature_select.cpp
diff options
context:
space:
mode:
authorChristian Tismer <[email protected]>2022-11-21 12:06:18 +0100
committerChristian Tismer <[email protected]>2022-11-29 17:57:32 +0100
commit7377d2b8130ce7290775cd8a343e75c0561fc854 (patch)
treecbf0c9f8e005f0e61d7959950da7fc255ccf7d55 /sources/pyside6/libpyside/feature_select.cpp
parent916bae507f76f4f063af81439f17cf11c914b4bd (diff)
__feature__: heavily rework the context switching
The example of the issue shows the qasync.py module which fails miserably when using snake_case. The reason: ----------- Reason is the way how feature switching is implemented. Modules like qasync get a default switching of "ignore". This ignores that the qasync module itself imports QtCore, and feature switching is of course relevant, suggesting a default setting of "normal" (explicitly no features). The real problem: ----------------- Testing the simple approach showed a serious problem with feature switching: The functions get switched when a certain function (getattr etc.) is called. But the switching is sometimes not done due to a caching problem. This fix removes caching that was wrong. Optimization will be done in a different step with a different approach. This Change was not qasync specific, but happens with PySide imports. Actions done: - adjust the inline structure - implement a feature_imported callback - identify Python functions that use PySide during import [ChangeLog][PySide6] __feature__ switching now works even with recursive imports like in the qasync module. Fixes: PYSIDE-2029 Change-Id: I3340f54f293083a09fb509383688f73bbd9b60ae Pick-to: 6.4 Reviewed-by: Friedemann Kleint <[email protected]>
Diffstat (limited to 'sources/pyside6/libpyside/feature_select.cpp')
-rw-r--r--sources/pyside6/libpyside/feature_select.cpp48
1 files changed, 16 insertions, 32 deletions
diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp
index b3117d40d..17c6169af 100644
--- a/sources/pyside6/libpyside/feature_select.cpp
+++ b/sources/pyside6/libpyside/feature_select.cpp
@@ -163,15 +163,6 @@ static inline void setCurrentSelectId(PyTypeObject *type, int id)
SbkObjectType_SetReserved(type, id);
}
-static inline PyObject *getCurrentSelectId(PyTypeObject *type)
-{
- int id = SbkObjectType_GetReserved(type);
- // This can be too early.
- if (id < 0)
- id = 0;
- return fast_id_array[id];
-}
-
static bool replaceClassDict(PyTypeObject *type)
{
/*
@@ -218,7 +209,7 @@ static bool addNewDict(PyTypeObject *type, PyObject *select_id)
return true;
}
-static bool moveToFeatureSet(PyTypeObject *type, PyObject *select_id)
+static inline bool moveToFeatureSet(PyTypeObject *type, PyObject *select_id)
{
/*
* Rotate the ring to the given `select_id` and return `true`.
@@ -227,7 +218,6 @@ static bool moveToFeatureSet(PyTypeObject *type, PyObject *select_id)
auto initial_dict = type->tp_dict;
auto dict = initial_dict;
do {
- dict = nextInCircle(dict);
AutoDecRef current_id(getSelectId(dict));
// This works because small numbers are singleton objects.
if (current_id == select_id) {
@@ -235,6 +225,7 @@ static bool moveToFeatureSet(PyTypeObject *type, PyObject *select_id)
setCurrentSelectId(type, select_id);
return true;
}
+ dict = nextInCircle(dict);
} while (dict != initial_dict);
type->tp_dict = initial_dict;
setCurrentSelectId(type, getSelectId(initial_dict));
@@ -290,7 +281,7 @@ static bool createNewFeatureSet(PyTypeObject *type, PyObject *select_id)
return true;
}
-static bool SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_id)
+static inline bool SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_id)
{
/*
* This is the selector for one sublass. We need to call this for
@@ -330,28 +321,21 @@ static inline void SelectFeatureSet(PyTypeObject *type)
return;
}
}
+
PyObject *select_id = getFeatureSelectId(); // borrowed
- PyObject *current_id = getCurrentSelectId(type); // borrowed
- static PyObject *undef = fast_id_array[-1];
-
- // PYSIDE-1019: During import PepType_SOTP is still zero.
- if (current_id == undef)
- current_id = select_id = fast_id_array[0];
-
- if (select_id != current_id) {
- PyObject *mro = type->tp_mro;
- Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
- // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2".
- for (idx = 0; idx < n - 2; idx++) {
- auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
- // When any subtype is already resolved (false), we can stop.
- if (!SelectFeatureSetSubtype(sub_type, select_id))
- break;
- }
- // PYSIDE-1436: Clear all caches for the type and subtypes.
- PyType_Modified(type);
+
+ // PYSIDE-2029: We are no longer caching extremely, but switching safe.
+ PyObject *mro = type->tp_mro;
+ Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
+ // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2".
+ for (idx = 0; idx < n - 2; idx++) {
+ auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ // When any subtype is already resolved (false), we can stop.
+ if (!SelectFeatureSetSubtype(sub_type, select_id))
+ break;
}
- return;
+ // PYSIDE-1436: Clear all caches for the type and subtypes.
+ PyType_Modified(type);
}
// For cppgenerator: