[PyKDE] SIP and typedefs in signals

Phil Thompson phil at riverbankcomputing.co.uk
Sun Jan 7 17:43:18 GMT 2007


On Sunday 07 January 2007 4:08 pm, Gerard Vermeulen wrote:
> On Wed, 20 Dec 2006 16:41:22 +0000
>
> Phil Thompson <phil at riverbankcomputing.co.uk> wrote:
> > On Monday 18 December 2006 7:34 pm, Gerard Vermeulen wrote:
> > > Hi,
> > >
> > > moc does not expand typedefs in signals but sip does.
> > > Therefore I needed a hack to wrap the following header code:
> > >
> > > --- start C++ header code ---
> > > typedef QPointF QwtDoublePoint;
> > >
> > > class QWT_EXPORT QwtPlotPicker: public QwtPicker
> > > {
> > >     Q_OBJECT
> > >     ...
> > > signals:
> > >     // Here, moc produces code containing QwtDoublePoint and not
> > > QPointF. void selected(const QwtDoublePoint &pos);
> > > };
> > > --- end C++ header code ---
> > >
> > > --- start SIP declaration ---
> > > // The C++ library declares
> > > // typedef QPointF QwtDoublePoint;
> > > // but that does not work in SIP (Python crashes, when using the
> > > typedef).
> >
> > When does it crash? When you call connect()? When the signal is
> > delivered?
> >
> > > // However the following SIP declaration
> > > class QwtDoublePoint: QPointF
> > > {
> > > %TypeHeaderCode
> > > #include <qpoint.h>
> > > %End // %TypeHeaderCode
> > > };
> > > // does work.
> > >
> > > class QwtPlotPicker: QwtPicker
> > > {
> > > %TypeHeaderCode
> > > #include <qwt_plot_picker.h>
> > > %End // %TypeHeaderCode
> > >     ...
> > > signals:
> > >     void selected(const QwtDoublePoint&);
> > >     // void selected(const QRectF&); without typedef may have worked
> > > before, // but not with SIP-4.5.x.
> > > };
> > > --- end SIP declaration ---
> > >
> > > Is it possible (or worthwhile) to make SIP behave like moc for such
> > > cases?
> >
> > I don't think that this is the problem. SIP supports the use of typedefs
> > in signal arguments - see sipFindSigArgType() in siplib.c. As they are
> > not used very much I think the problem is more likely to be a bug in that
> > function.
>
> Yes, it is a bug:
>
> (gdb) run bug.py
> Starting program: /home/packer/usr/bin/python bug.py
> [Thread debugging using libthread_db enabled]
> [New Thread 47234504940432 (LWP 16756)]
>
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 47234504940432 (LWP 16756)]
> 0x00002af5a4f4a53c in findClassArg (emd=0x0, name=0x2aaaab7f87f1 "QPointF",
>     len=7, at=0xc5b870, indir=0) at siplib.c:6964
> 6964        sipWrapperType **wtp = emd->em_types;
> (gdb) bt
> #0  0x00002af5a4f4a53c in findClassArg (emd=0x0,
>     name=0x2aaaab7f87f1 "QPointF", len=7, at=0xc5b870, indir=0)
>     at siplib.c:6964
> #1  0x00002af5a4f4a8e9 in sipFindSigArgType (name=0xba92d0
> "QwtDoublePoint", len=14, at=0xc5b870, indir=0) at siplib.c:7106
> #2  0x00002af5a4f4bb47 in parseSignature (
>     sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)") at qtlib.c:343
> #3  0x00002af5a4f4be1d in createUniversalSlot (txSelf=0x2aaaaf73bea8,
>     sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8,
>     slot=0x0, member=0x7fff0742d830) at qtlib.c:448
> #4  0x00002af5a4f4cf28 in sip_api_convert_rx (txSelf=0x2aaaaf73bea8,
>     sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8,
>     slot=0x0, memberp=0x7fff0742d830) at qtlib.c:915
> #5  0x00002af5a4f4d06d in sip_api_connect_rx (txObj=0x2aaaaf73bea8,
>     sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8,
>     slot=0x0, type=0) at qtlib.c:961
> #6  0x00002af5a3f5f25d in initQtCore ()
>    from /home/packer/usr/lib/python2.5/site-packages/PyQt4/QtCore.so
> #7  0x000000000047f3c4 in PyEval_EvalFrameEx ()
> #8  0x0000000000480314 in PyEval_EvalFrameEx ()
> #9  0x0000000000480314 in PyEval_EvalFrameEx ()
> #10 0x0000000000480e2b in PyEval_EvalCodeEx ()
> #11 0x00000000004810d2 in PyEval_EvalCode ()
> ---Type <return> to continue, or q <return> to quit---q
> Quit
> (gdb) bt full
> #0  0x00002af5a4f4a53c in findClassArg (emd=0x0,
>     name=0x2aaaab7f87f1 "QPointF", len=7, at=0xc5b870, indir=0)
>     at siplib.c:6964
>         i = 0
>         wtp = (sipWrapperType **) 0xba92d0
> #1  0x00002af5a4f4a8e9 in sipFindSigArgType (name=0xba92d0
> "QwtDoublePoint", len=14, at=0xc5b870, indir=0) at siplib.c:7106
>         tem = (sipExportedModuleDef *) 0x0
>         tn = 0x2aaaab7f87f1 "QPointF"
>         tnlen = 7
>         tdd = (sipTypedefDef *) 0x2aaaab958140
>         em = (sipExportedModuleDef *) 0x2aaaab954340
>         po = (sipPyObject *) 0x7fff0742d440
> #2  0x00002af5a4f4bb47 in parseSignature (
>     sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)") at qtlib.c:343
>         btlen = 14
>         unsup = 0
>         isref = 0
>         indir = 0
>         sat = unknown_sat
>         arg = 0xba92d0 "QwtDoublePoint"
>         a = 0
>         dp = 0xba92d0 "QwtDoublePoint"
> ---Type <return> to continue, or q <return> to quit---
>
>
> and the problem is in the else-block of the lines
>
>                     /*
>                      * Find the module that this class,
>                      * mapped type or enum is defined in.
>                      */
>                     if (tdd->tdd_mod_name == NULL)
>                         tem = em;
>                     else
>                         for (tem = clientList; tem != NULL; tem =
> tem->em_next) if (strcmp(tem->em_name, tdd->tdd_mod_name) == 0) break;
> in sipFindSigArgType()
>
> Stepping leads to:
>
> (gdb) s
> 7098                                if (strcmp(tem->em_name,
> tdd->tdd_mod_name) == 0) (gdb) p tem->em_name
> $12 = 0x2b8f56b9301d "PyQt4.QtCore"
> (gdb) p tdd->tdd_mod_name
> $13 = 0x2aaaab7f840f "QtCore"
> (gdb)
>
> which does not match and tem ends up being NULL

Try tonight's snapshot. It's a code generation bug, but PyQt doesn't use the 
bad code.

Phil




More information about the PyQt mailing list