aboutsummaryrefslogtreecommitdiffstats
path: root/libshiboken/basewrapper.cpp
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-03-15 15:32:13 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:15:18 -0300
commit68f5acc285c9c76cfe26c3bcc8cc74f0b91fc97d (patch)
treefe3bd8f2dcd85c6cc7974c7af875538a0cd261c6 /libshiboken/basewrapper.cpp
parent0fbf99be54ab15b5a85b544700604eb38638f37a (diff)
Check for class initialization on function Object.isValid.
Fix bug #696. Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Luciano Wolf <luciano.wolf@openbossa.org>
Diffstat (limited to 'libshiboken/basewrapper.cpp')
-rw-r--r--libshiboken/basewrapper.cpp59
1 files changed, 43 insertions, 16 deletions
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index d296d061e..83cd83ca0 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -264,19 +264,21 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k
PyObject* SbkObjectTpNew(PyTypeObject* subtype, PyObject*, PyObject*)
{
SbkObject* self = reinterpret_cast<SbkObject*>(subtype->tp_alloc(subtype, 0));
- self->d = new SbkObjectPrivate;
+ SbkObjectPrivate* d = new SbkObjectPrivate;
SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(subtype);
int numBases = ((sbkType->d && sbkType->d->is_multicpp) ? Shiboken::getNumberOfCppBaseClasses(subtype) : 1);
- self->d->cptr = new void*[numBases];
- std::memset(self->d->cptr, 0, sizeof(void*)*numBases);
- self->d->hasOwnership = 1;
- self->d->containsCppWrapper = 0;
- self->d->validCppObject = 0;
- self->d->parentInfo = 0;
+ d->cptr = new void*[numBases];
+ std::memset(d->cptr, 0, sizeof(void*)*numBases);
+ d->hasOwnership = 1;
+ d->containsCppWrapper = 0;
+ d->validCppObject = 0;
+ d->parentInfo = 0;
+ d->referredObjects = 0;
+ d->cppObjectCreated = 0;
self->ob_dict = 0;
self->weakreflist = 0;
- self->d->referredObjects = 0;
+ self->d = d;
return reinterpret_cast<PyObject*>(self);
}
@@ -783,26 +785,51 @@ bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr)
else
sbkObj->d->cptr[idx] = cptr;
+ sbkObj->d->cppObjectCreated = true;
return !alreadyInitialized;
}
bool isValid(PyObject* pyObj)
{
if (!pyObj || pyObj == Py_None
- || pyObj->ob_type->ob_type != &SbkObjectType_Type
- || ((SbkObject*)pyObj)->d->validCppObject) {
+ || pyObj->ob_type->ob_type != &SbkObjectType_Type) {
return true;
}
- PyErr_Format(PyExc_RuntimeError, "Internal C++ object (%s) already deleted.", pyObj->ob_type->tp_name);
- return false;
+
+ SbkObjectPrivate* priv = reinterpret_cast<SbkObject*>(pyObj)->d;
+
+ if (!priv->cppObjectCreated && isUserType(pyObj)) {
+ PyErr_Format(PyExc_RuntimeError, "'__init__' method of object's base class (%s) not called.", pyObj->ob_type->tp_name);
+ return false;
+ }
+
+ if (!priv->validCppObject) {
+ PyErr_Format(PyExc_RuntimeError, "Internal C++ object (%s) already deleted.", pyObj->ob_type->tp_name);
+ return false;
+ }
+
+ return true;
}
bool isValid(SbkObject* pyObj, bool throwPyError)
{
- bool result = !pyObj || pyObj->d->validCppObject;
- if (!result && throwPyError)
- PyErr_Format(PyExc_RuntimeError, "Internal C++ object (%s) already deleted.", pyObj->ob_type->tp_name);
- return result;
+ if (!pyObj)
+ return false;
+
+ SbkObjectPrivate* priv = pyObj->d;
+ if (!priv->cppObjectCreated && isUserType(reinterpret_cast<PyObject*>(pyObj))) {
+ if (throwPyError)
+ PyErr_Format(PyExc_RuntimeError, "Base constructor of the object (%s) not called.", pyObj->ob_type->tp_name);
+ return false;
+ }
+
+ if (!priv->validCppObject) {
+ if (throwPyError)
+ PyErr_Format(PyExc_RuntimeError, "Internal C++ object (%s) already deleted.", pyObj->ob_type->tp_name);
+ return false;
+ }
+
+ return true;
}
PyObject* newObject(SbkObjectType* instanceType,