diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-12-02 11:53:18 -0300 |
---|---|---|
committer | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-12-02 19:15:55 -0300 |
commit | 458432be438fb750ae351460536cb7cb3e14263d (patch) | |
tree | 8d8407bf3f08bd2116de62cd63a1ee4b30dab31a /libshiboken | |
parent | 943a413287b522475532583147a78c6517613006 (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.cpp | 2 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 3 | ||||
-rw-r--r-- | libshiboken/bindingmanager.cpp | 35 |
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; } |