aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--libshiboken/basewrapper.cpp59
-rw-r--r--libshiboken/basewrapper_p.h2
2 files changed, 45 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,
diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h
index e9a067a6e..ba5275001 100644
--- a/libshiboken/basewrapper_p.h
+++ b/libshiboken/basewrapper_p.h
@@ -74,6 +74,8 @@ struct SbkObjectPrivate
unsigned int containsCppWrapper : 1;
/// Marked as false when the object is lost to C++ and the binding can not know if it was deleted or not.
unsigned int validCppObject : 1;
+ /// Marked when the object constructor was called
+ unsigned int cppObjectCreated : 1;
/// Information about the object parents and children, can be null.
Shiboken::ParentInfo* parentInfo;
/// Manage reference counting of objects that are referred but not owned.