[PySide] Bug with new hash table feature

Nathan Smith nathanjsmith at gmail.com
Wed May 30 20:31:48 CEST 2012


Hi Hugo,

Thanks for getting back to me.  I thought that was the case, and the
PyErr_format function is called within the isValid(PyObject *pyObj)
function, but no exception is ever raised in Python.  The following is
called from within the body of isValid(PyObject *pyObj):

PyErr_Format(PyExc_RuntimeError, "Internal C++ object (%s) already
deleted.", pyObj->ob_type->tp_name);


My modified hash function *always* returns even when called on invalid
objects.  The updated code is shown below for reference:

Py_hash_t hash(PyObject* pyObj)
{
    assert(Shiboken::Object::checkType(pyObj));
    // begin changes by Nathan
    if (!isValid(pyObj)) {
        return 0L;
    }
    // end changes by Nathan
    return
reinterpret_cast<Py_hash_t>(reinterpret_cast<SbkObject*>(pyObj)->d->cptr[0]);
}

// Unchanged
bool isValid(PyObject* pyObj)
{
    if (!pyObj || pyObj == Py_None
        || Py_TYPE(pyObj->ob_type) != &SbkObjectType_Type) {
        return true;
    }

    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;
}

When passed an invalid object, this function just returns 0 rather than
raising a RuntimeError.  Why isn't a runtime error raised?

Nathan

On Wed, May 30, 2012 at 1:12 PM, Hugo Parente Lima
<hugo.lima at openbossa.org>wrote:

> On Wednesday, May 30, 2012 09:37:15 AM Nathan Smith wrote:
> > Hi all,
> >
> > I uncovered a bug in the new hash feature of Shiboken in the
> repositories.
> >  I'll submit a bug report when the system comes back up, but I'm
> interested
> > in actually submitting a patch.
> >
> > The new hash function doesn't check to see if the provided object is
> valid
> > before calculating the hash value.  This can be seen
> > in shiboken/libshiboken/basewrapper.cpp at line 754 and demonstrated
> using
> >
> > the following code:
> > >>> from PySide import QtCore
> > >>> import shiboken
> > >>> a = QtCore.QObject()
> > >>> b = QtCore.QObject(a)
> > >>> shiboken.isValid(a)
> >
> > True
> >
> > >>> shiboken.isValid(b)
> >
> > True
> >
> > >>> del a
> > >>> shiboken.isValid(b)
> >
> > False
> >
> > >>> hash(b)
> >
> > Segmentation Fault
> >
> >
> > I made the following change in the code, but it didn't do what I
> expected:
> >
> > if (!isValid(pyObj)) {
> >   return 0L;
> > }
> >
> >
> > isValid raises a RuntimeException in addition to returning false, but I
> > never see that exception in Python.  So, I have two questions:
> >
> >    1. Is there some other code that should be checking isValid before the
> >    call ever gets to the C++ hash() function?
> >    2. How do you correctly raise an exception from within Shiboken?
>
> You raise an exception using the Python C API.
>
> Use the PyErr_* functions, e.g. PyErr_SetString
>
> > Nathan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20120530/efd97a2b/attachment.html>


More information about the PySide mailing list