aboutsummaryrefslogtreecommitdiffstats
path: root/libshiboken
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-12-02 11:53:18 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-12-02 19:15:55 -0300
commit458432be438fb750ae351460536cb7cb3e14263d (patch)
tree8d8407bf3f08bd2116de62cd63a1ee4b30dab31a /libshiboken
parent943a413287b522475532583147a78c6517613006 (diff)
Modified the BindingManager::getOverride method to use Python __mro__.
Using the CLASS->tp_mro, which contains the list of method resolution for a Python class, to find an override for a wrapped C++ virtual method is more correct than relying in the ShiboTypeObject's baseWrapperType value. Also baseWrapperType was removed from ShiboTypeObject structure. Reviewed by Hugo Lima <hugo.lima@openbossa.org>
Diffstat (limited to 'libshiboken')
-rw-r--r--libshiboken/basewrapper.cpp2
-rw-r--r--libshiboken/basewrapper.h3
-rw-r--r--libshiboken/bindingmanager.cpp35
3 files changed, 21 insertions, 19 deletions
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index 75af9b5fd..3a2bc9964 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -105,7 +105,6 @@ void destroyParentInfo(PyBaseWrapper* obj, bool removeFromParent)
}
PyObject* PyBaseWrapper_New(PyTypeObject* instanceType,
- ShiboTypeObject* baseWrapperType,
const void* cptr,
unsigned int hasOwnership,
unsigned int containsCppWrapper)
@@ -116,7 +115,6 @@ PyObject* PyBaseWrapper_New(PyTypeObject* instanceType,
ShiboTypeObject* const& instanceType_ = reinterpret_cast<ShiboTypeObject*>(instanceType);
PyBaseWrapper* self = (PyBaseWrapper*)instanceType_->pytype.tp_alloc((PyTypeObject*) instanceType, 0);
- self->baseWrapperType = baseWrapperType;
self->cptr = const_cast<void*>(cptr);
self->hasOwnership = hasOwnership;
self->containsCppWrapper = containsCppWrapper;
diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h
index 90c38c735..56038c4ca 100644
--- a/libshiboken/basewrapper.h
+++ b/libshiboken/basewrapper.h
@@ -75,8 +75,6 @@ struct LIBSHIBOKEN_API ShiboTypeObject
struct LIBSHIBOKEN_API PyBaseWrapper
{
PyObject_HEAD
- /// First binding provided parent type of a Python class that inherits from a wrapped class.
- ShiboTypeObject* baseWrapperType;
/// Pointer to the C++ class.
void* cptr;
/// True when Python is responsible for freeing the used memory.
@@ -174,7 +172,6 @@ typedef struct {
LIBSHIBOKEN_API PyAPI_FUNC(PyObject*)
PyBaseWrapper_New(PyTypeObject* instanceType,
- ShiboTypeObject* baseWrapperType,
const void *cptr,
unsigned int hasOwnership = 1,
unsigned int containsCppWrapper = 0);
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp
index 8c8be3e46..5788b1108 100644
--- a/libshiboken/bindingmanager.cpp
+++ b/libshiboken/bindingmanager.cpp
@@ -109,25 +109,32 @@ PyObject* BindingManager::retrieveWrapper(const void* cptr)
PyObject* BindingManager::getOverride(const void* cptr, const char* methodName)
{
PyObject* wrapper = retrieveWrapper(cptr);
+ if (!wrapper)
+ return 0;
- if (wrapper) {
- PyTypeObject* baseWrapperType = (PyTypeObject*) ((Shiboken::PyBaseWrapper*)wrapper)->baseWrapperType;
- PyObject* method = PyObject_GetAttrString(wrapper, const_cast<char*>(methodName));
- if (method) {
- PyObject* defaultMethod = 0;
- if (PyMethod_Check(method) &&
- ((PyMethodObject*) method)->im_self == wrapper &&
- baseWrapperType->tp_dict != 0) {
- defaultMethod = PyDict_GetItemString(baseWrapperType->tp_dict, const_cast<char*>(methodName));
+ PyObject* pyMethodName = PyString_FromString(methodName);
+ PyObject* method = PyObject_GetAttr(wrapper, pyMethodName);
+
+ if (method && PyMethod_Check(method) && reinterpret_cast<PyMethodObject*>(method)->im_self == wrapper) {
+ PyObject* defaultMethod;
+ PyObject* mro = wrapper->ob_type->tp_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++) {
+ PyTypeObject* parent = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(mro, i));
+ if (parent->tp_dict) {
+ defaultMethod = PyDict_GetItem(parent->tp_dict, pyMethodName);
+ if (defaultMethod && reinterpret_cast<PyMethodObject*>(method)->im_func != defaultMethod) {
+ Py_DECREF(pyMethodName);
+ return method;
+ }
}
-
- if (defaultMethod && ((PyMethodObject*)method)->im_func != defaultMethod)
- return method;
-
- Py_DECREF(method);
}
}
+ Py_XDECREF(method);
+ Py_DECREF(pyMethodName);
return 0;
}