[PyQt] Bug in sip-4.9.2-snapshot-20091108 handling virtual methods

Giovanni Bajo rasky at develer.com
Fri Nov 13 19:41:11 GMT 2009


On Fri, 2009-11-13 at 00:29 +0100, Simon Edwards wrote:
> Hello Phil,
> 
> Using sip-4.9.2-snapshot-20091108 here I've got a class with a public:
> 
> class WallpaperScript : Plasma::ScriptEngine {
> // ...
> public:
>      virtual void            initWallpaper (const KConfigGroup& config);
> // ...
> }
> 
> When it is called from C++ I get a TypeError that 4 args were given 
> while only 2 were expected.
> 
> Digging into the cpp I found the method which cpp hits first:
> 
> -----------------------------------------------------------
> 
> void sipPlasma_WallpaperScript::initWallpaper(const KConfigGroup& a0)
> {
>      sip_gilstate_t sipGILState;
>      PyObject *meth;
> 
>      meth = 
> sipIsPyMethod(&sipGILState,&sipPyMethods[0],sipPySelf,NULL,sipName_initWallpaper);
> 
>      if (!meth)
>      {
>          Plasma::WallpaperScript::initWallpaper(a0);
>          return;
>      }
> 
>      typedef void (*sipVH_kdeui_64)(sip_gilstate_t,PyObject *,const 
> KConfigGroup&);
> 
>  
> ((sipVH_kdeui_64)(sipModuleAPI_plasma_kdeui->em_virthandlers[65]))(sipGILState,meth,a0);
> }
> -----------------------------------------------------------
> 
> When jumping through the table in the last line, it hits this code next:
> 
> -----------------------------------------------------------
> bool sipVH_kdeui_64(sip_gilstate_t sipGILState,PyObject 
> *sipMethod,unsigned long a0,unsigned long a1,unsigned long
> {
>      bool sipRes = 0;
>      PyObject *resObj = sipCallMethod(0,sipMethod,"mmm",a0,a1,a2);
> 
>      if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
>          PyErr_Print();
> 
>      Py_XDECREF(resObj);
>      Py_DECREF(sipMethod);
> 
>      SIP_RELEASE_GIL(sipGILState)
> 
>      return sipRes;
> }
> 
> -----------------------------------------------------------
> 
> As you can see it has the wrong parameters.
> 
> Oddly enough, the method below this one has the right parameters and it 
> probably the right one:
> 
> -----------------------------------------------------------
> 
> void sipVH_kdeui_65(sip_gilstate_t sipGILState,PyObject *sipMethod,const 
> KConfigGroup& a0)
> {
>      PyObject *resObj = 
> sipCallMethod(0,sipMethod,"D",const_cast<KConfigGroup 
> *>(&a0),sipType_KConfigGroup,NULL);
> 
>      if (!resObj || sipParseResult(0,sipMethod,resObj,"Z") < 0)
>          PyErr_Print();
> 
>      Py_XDECREF(resObj);
>      Py_DECREF(sipMethod);
> 
>      SIP_RELEASE_GIL(sipGILState)
> }
> -----------------------------------------------------------
> 
> I'm guessing that the jump table lookup is out by 1.
> 
> cheers,

Simon,

this kind of problems happen to me without a full recompilation;
specifically, if module A %Imports module B, you need to recompile A
whenever *any* of B's sip files changes.

sipdistutils.py doesn't handle this automatically yet, but I have a
patch in progress.
-- 
Giovanni Bajo
Develer S.r.l.
http://www.develer.com




More information about the PyQt mailing list