aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/bindingmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/bindingmanager.cpp')
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.cpp53
1 files changed, 36 insertions, 17 deletions
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index 725150e87..78c03556c 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken2/libshiboken/bindingmanager.cpp
@@ -37,12 +37,14 @@
**
****************************************************************************/
+#include "autodecref.h"
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "sbkdbg.h"
#include "gilstate.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include "debugfreehook.h"
#include <cstddef>
@@ -272,7 +274,17 @@ SbkObject *BindingManager::retrieveWrapper(const void *cptr)
return iter->second;
}
-PyObject *BindingManager::getOverride(const void *cptr, const char *methodName)
+static inline int currentSelectId(PyTypeObject *type)
+{
+ int sel = SbkObjectType_GetReserved(type);
+ // This could theoretically be -1 if used too early.
+ assert(sel >= 0);
+ return sel;
+}
+
+PyObject *BindingManager::getOverride(const void *cptr,
+ PyObject *nameCache[],
+ const char *methodName)
{
SbkObject *wrapper = retrieveWrapper(cptr);
// The refcount can be 0 if the object is dieing and someone called
@@ -280,15 +292,29 @@ PyObject *BindingManager::getOverride(const void *cptr, const char *methodName)
if (!wrapper || reinterpret_cast<const PyObject *>(wrapper)->ob_refcnt == 0)
return nullptr;
+ int flag = currentSelectId(Py_TYPE(wrapper));
+ int propFlag = isdigit(methodName[0]) ? methodName[0] - '0' : 0;
+ if ((flag & 0x02) != 0 && (propFlag & 3) != 0) {
+ // PYSIDE-1019: Handle overriding with properties.
+ // They cannot be overridden (make that sure by the metaclass).
+ return nullptr;
+ }
+ PyObject *pyMethodName = nameCache[(flag & 1) != 0]; // borrowed
+ if (pyMethodName == nullptr) {
+ if (propFlag)
+ methodName += 2; // skip the propFlag and ':'
+ pyMethodName = Shiboken::String::getSnakeCaseName(methodName, flag);
+ nameCache[(flag & 1) != 0] = pyMethodName;
+ }
+
if (wrapper->ob_dict) {
- PyObject *method = PyDict_GetItemString(wrapper->ob_dict, methodName);
+ PyObject *method = PyDict_GetItem(wrapper->ob_dict, pyMethodName);
if (method) {
- Py_INCREF(reinterpret_cast<PyObject *>(method));
+ Py_INCREF(method);
return method;
}
}
- PyObject *pyMethodName = Shiboken::String::fromCString(methodName);
PyObject *method = PyObject_GetAttr(reinterpret_cast<PyObject *>(wrapper), pyMethodName);
if (method && PyMethod_Check(method)
@@ -296,22 +322,20 @@ PyObject *BindingManager::getOverride(const void *cptr, const char *methodName)
PyObject *defaultMethod;
PyObject *mro = Py_TYPE(wrapper)->tp_mro;
+ int size = PyTuple_GET_SIZE(mro);
// The first class in the mro (index 0) is the class being checked and it should not be tested.
// The last class in the mro (size - 1) is the base Python object class which should not be tested also.
- for (int i = 1; i < PyTuple_GET_SIZE(mro) - 1; i++) {
- auto *parent = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
+ for (int idx = 1; idx < size - 1; ++idx) {
+ auto *parent = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
if (parent->tp_dict) {
defaultMethod = PyDict_GetItem(parent->tp_dict, pyMethodName);
- if (defaultMethod && PyMethod_GET_FUNCTION(method) != defaultMethod) {
- Py_DECREF(pyMethodName);
+ if (defaultMethod && PyMethod_GET_FUNCTION(method) != defaultMethod)
return method;
- }
}
}
+ } else {
+ Py_XDECREF(method);
}
-
- Py_XDECREF(method);
- Py_DECREF(pyMethodName);
return nullptr;
}
@@ -320,11 +344,6 @@ void BindingManager::addClassInheritance(SbkObjectType *parent, SbkObjectType *c
m_d->classHierarchy.addEdge(parent, child);
}
-SbkObjectType *BindingManager::resolveType(void *cptr, SbkObjectType *type)
-{
- return resolveType(&cptr, type);
-}
-
SbkObjectType *BindingManager::resolveType(void **cptr, SbkObjectType *type)
{
SbkObjectType *identifiedType = m_d->classHierarchy.identifyType(cptr, type, type);