Hello Phil,
I've made a unittest for the segfault, it is ran by
executing the command :
python -m nose.core test_qt_bindings.py
It seems to be a matter of keeping too much references,
rather than keeping not enough references.
I know the code in itself is pointless and simply
removing a line in it ensures that it doesn't segfaults,
but I would like to understand why it segfaults.
Thank you and best regards,
Erik
On Thu, 2010-09-09 at 15:46 +0100, Phil Thompson wrote:
> On Thu, 09 Sep 2010 16:35:15 +0200, Erik Janssens
> <erik.janss...@conceptive.be> wrote:
> > Hi,
> >
> > I understand that it's possible to segfault writing
> > python code (although in my naive view this should
> > not be the case ;)). I'm rather convinced the code
> > is not doing anything 'illegal', but it would be helpful
> > to have some descriptions on what exactly one can
> > do wrong using pyqt with regard to these kind of
> > segfaults ?
>
> Typically not keeping a reference to an object. Historically (but I'm not
> sure how much it is still the case, particularly with the new-style
> connections) sip/PyQt would keep pointers to Python objects without taking
> a reference. This was to avoid creating circular references in the days
> before the cyclic garbage collector.
>
> > I will try to write a test case for this situation,
> > as well as for the deadlocks I mentioned earlier.
> >
> > Can you maybe comment on the meaning of this line
> > in siplib.c
> >
> > 7288 assert(PyTuple_Check(mro));
> >
> > It might help me finding the cause at the python
> > level.
>
> It's just a sanity check. If Python is working fine then mro will always
> be a tuple, and the following call to PyTuple_GET_SIZE() assumes that it
> is. If it fails then it is likely that mro has been garbage collected and
> the memory reused.
>
> Phil
"""Test the behaviour of the qt bindings in various circumstances.
"""
import unittest
from PyQt4 import QtGui
class ReferenceHoldingBox(QtGui.QGroupBox):
"""A group box holding references to the table
view and the table model"""
def __init__(self, model, table):
QtGui.QGroupBox.__init__(self)
self.model = model
self.table = table
class TableView( QtGui.QWidget ):
"""A widget containg both a table and a groupbox that
holds a reference to both the table and the model of the
table"""
def __init__( self, table_model ):
super(TableView, self).__init__()
widget_layout = QtGui.QVBoxLayout()
table = QtGui.QTableView( self )
table.setModel( table_model )
widget_layout.addWidget( table )
widget_layout.addWidget( ReferenceHoldingBox( table_model, self ) )
self.setLayout( widget_layout )
class TableViewCases(unittest.TestCase):
"""Tests related to table views"""
def setUp(self):
self.application = QtGui.QApplication([])
def test_table_view_garbage_collection(self):
"""Create a table view and force its garbage collection"""
import gc
for i in range(100):
print i
class TableModelSubclass(QtGui.QStringListModel):
pass
widget = TableView( TableModelSubclass() )
gc.collect()
_______________________________________________
PyQt mailing list PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt