aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-04-24 12:47:13 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-04-25 11:32:21 +0200
commitce2959ec5135965ef67476274a8b4a57c897f4cf (patch)
treed7dc74f089f85265b07053e287175e1791d11d26
parentcbdc4518cc089971677676449a9478d70d4a2441 (diff)
libshiboken: Refactor type discovery graph handling
Replace BindingManager::.resolveType() by a new function BindingManager::findDerivedType() which does exactly that and returns a pair of type/cptr instead of modifying the in-parameter. As a drive-by, remove a unused variable in BindingManagerPrivate. Task-number: PYSIDE-2404 Task-number: PYSIDE-2675 Pick-to: 6.7 Change-Id: I5b39ea8370b0fc1a196feb6934306f1f1dfeb8b3 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp11
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.cpp60
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.h14
3 files changed, 51 insertions, 34 deletions
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp
index 3cd8a5c2b..f34e053ca 100644
--- a/sources/shiboken6/libshiboken/basewrapper.cpp
+++ b/sources/shiboken6/libshiboken/basewrapper.cpp
@@ -1460,10 +1460,15 @@ PyObject *newObject(PyTypeObject *instanceType,
{
// Try to find the exact type of cptr.
if (!isExactType) {
- if (PyTypeObject *exactType = ObjectType::typeForTypeName(typeName))
+ if (PyTypeObject *exactType = ObjectType::typeForTypeName(typeName)) {
instanceType = exactType;
- else
- instanceType = BindingManager::instance().resolveType(&cptr, instanceType);
+ } else {
+ auto resolved = BindingManager::instance().findDerivedType(cptr, instanceType);
+ if (resolved.first != nullptr) {
+ instanceType = resolved.first;
+ cptr = resolved.second;
+ }
+ }
}
bool shouldCreate = true;
diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp
index 7542e60b8..84424a78a 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken6/libshiboken/bindingmanager.cpp
@@ -43,35 +43,32 @@ public:
m_edges[from].push_back(to);
}
+ BindingManager::TypeCptrPair identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const;
+
bool dumpTypeGraph(const char *fileName) const;
NodeSet nodeSet() const;
- PyTypeObject *identifyType(void **cptr, PyTypeObject *type, PyTypeObject *baseType) const
- {
- auto edgesIt = m_edges.find(type);
- if (edgesIt != m_edges.end()) {
- const NodeList &adjNodes = m_edges.find(type)->second;
- for (PyTypeObject *node : adjNodes) {
- PyTypeObject *newType = identifyType(cptr, node, baseType);
- if (newType)
- return newType;
- }
- }
- void *typeFound = nullptr;
- auto *sotp = PepType_SOTP(type);
- if (sotp->type_discovery)
- typeFound = sotp->type_discovery(*cptr, baseType);
- if (typeFound) {
- // This "typeFound != type" is needed for backwards compatibility with old modules using a newer version of
- // libshiboken because old versions of type_discovery function used to return a PyTypeObject *instead of
- // a possible variation of the C++ instance pointer (*cptr).
- if (typeFound != type)
- *cptr = typeFound;
- return type;
+};
+
+BindingManager::TypeCptrPair Graph::identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const
+{
+ auto edgesIt = m_edges.find(type);
+ if (edgesIt != m_edges.end()) {
+ const NodeList &adjNodes = edgesIt->second;
+ for (PyTypeObject *node : adjNodes) {
+ auto newType = identifyType(cptr, node, baseType);
+ if (newType.first != nullptr)
+ return newType;
}
- return nullptr;
}
-};
+
+ auto *sotp = PepType_SOTP(type);
+ if (sotp->type_discovery != nullptr) {
+ if (void *derivedCPtr = sotp->type_discovery(cptr, baseType))
+ return {type, derivedCPtr};
+ }
+ return {nullptr, nullptr};
+}
static void formatDotNode(const char *nameC, std::ostream &file)
{
@@ -132,9 +129,6 @@ struct BindingManager::BindingManagerPrivate {
std::recursive_mutex wrapperMapLock;
Graph classHierarchy;
DestructorEntries deleteInMainThread;
- bool destroying;
-
- BindingManagerPrivate() : destroying(false) {}
bool releaseWrapper(void *cptr, SbkObject *wrapper, const int *bases = nullptr);
bool releaseWrapperHelper(void *cptr, SbkObject *wrapper);
@@ -386,10 +380,18 @@ void BindingManager::addClassInheritance(PyTypeObject *parent, PyTypeObject *chi
m_d->classHierarchy.addEdge(parent, child);
}
+BindingManager::TypeCptrPair BindingManager::findDerivedType(void *cptr, PyTypeObject *type) const
+{
+ return m_d->classHierarchy.identifyType(cptr, type, type);
+}
+
+// FIXME PYSIDE7: remove, just for compatibility
PyTypeObject *BindingManager::resolveType(void **cptr, PyTypeObject *type)
{
- PyTypeObject *identifiedType = m_d->classHierarchy.identifyType(cptr, type, type);
- return identifiedType ? identifiedType : type;
+ auto result = findDerivedType(*cptr, type);
+ if (result.second != nullptr)
+ *cptr = result.second;
+ return result.first != nullptr ? result.first : type;
}
std::set<PyObject *> BindingManager::getAllPyObjects()
diff --git a/sources/shiboken6/libshiboken/bindingmanager.h b/sources/shiboken6/libshiboken/bindingmanager.h
index 47db14975..281de2c73 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.h
+++ b/sources/shiboken6/libshiboken/bindingmanager.h
@@ -5,9 +5,11 @@
#define BINDINGMANAGER_H
#include "sbkpython.h"
-#include <set>
#include "shibokenmacros.h"
+#include <set>
+#include <utility>
+
struct SbkObject;
namespace Shiboken
@@ -39,6 +41,14 @@ public:
PyObject *getOverride(const void *cptr, PyObject *nameCache[], const char *methodName);
void addClassInheritance(PyTypeObject *parent, PyTypeObject *child);
+ /// Try to find the correct type of cptr via type discovery knowing that it's at least
+ /// of type \p type. If a derived class is found, it returns a cptr cast to the type
+ /// (which may be different in case of multiple inheritance.
+ /// \param cptr a pointer to the instance of type \p type
+ /// \param type type of cptr
+ using TypeCptrPair = std::pair<PyTypeObject *, void *>;
+ TypeCptrPair findDerivedType(void *cptr, PyTypeObject *type) const;
+
/**
* Try to find the correct type of *cptr knowing that it's at least of type \p type.
* In case of multiple inheritance this function may change the contents of cptr.
@@ -46,7 +56,7 @@ public:
* \param type type of *cptr
* \warning This function is slow, use it only as last resort.
*/
- PyTypeObject *resolveType(void **cptr, PyTypeObject *type);
+ [[deprecated]] PyTypeObject *resolveType(void **cptr, PyTypeObject *type);
std::set<PyObject *> getAllPyObjects();