[PyQt] SIP bug? (typemaps, %Import)

Jim Crowell jaclists at mailbolt.com
Tue Dec 9 19:08:23 GMT 2008


Hi all,

This is a bit odd as it's an application that appeared after a change in
my .sip code, but it looks like a SIP bug. I get the same behavior with
4.7.3 and 4.7.9. Briefly:

I have two modules, szg and szgexpt. szg is much the larger. szgexpt.sip
begins with a

%Import szg.sip

...and defines a class arGluTessObject that contains the following
method:

void addContour( vector<arVector3> vertexSequence  );

The arVector3 class, along with a class arVector4 (3- and 4-element
vectors), are defined in a file %Included by szg.sip, which also defines
the following typemap:

// vector<TYPE> is implemented as a Python list.
template<TYPE>
%MappedType vector<TYPE>
{
%TypeHeaderCode
#include <vector>
using namespace std;
%End

<%ConvertFromTypeCode omitted>

%ConvertToTypeCode
  // Check the type if that is all that is required.
  if (sipIsErr == NULL) {
    if (!PyList_Check(sipPy))
      return 0;
    for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
      if (!sipCanConvertToInstance(PyList_GET_ITEM(sipPy, i),
      sipClass_TYPE, SIP_NOT_NONE))
        return 0;
    return 1;
  }
  vector<TYPE> *qv = new vector<TYPE>;
  for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) {
    int state;
    TYPE *t = reinterpret_cast<TYPE
    *>(sipConvertToInstance(PyList_GET_ITEM(sipPy, i), sipClass_TYPE,
    sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));
    if (*sipIsErr) {
      sipReleaseInstance(t, sipClass_TYPE, state);
      delete qv;
      return 0;
    }
    qv->push_back(*t);
    sipReleaseInstance(t, sipClass_TYPE, state);
  }
  *sipCppPtr = qv;
  return sipGetState(sipTransferObj);
%End
};

...which worked fine with a version of the bindings compiled about 9
months ago. I recently tried updating the bindings used by that app to
my current version, and now I get a type-conversion error from
addContour(). If I insert:

cerr << "converting from a vector<TYPE>.\n";

...at the beginning of the vector<TYPE> %ConvertToTypeCode block and run
the program, it prints "converting from a vector<arVector4>" (wrong
class). However, the Python program thinks it's passing a list of
szg.arVector3's, and when I look in the generated .cpp file, addContour
is calling the following:

        if
        (sipParseArgs(&sipArgsParsed,sipArgs,"BM1",&sipSelf,sipClass_arGluTessObject,&sipCpp,
              sipMappedType_vector_0200arVector3,&a0,&a0State))

...so it looks like sipParseArgs is doing something funny.

Any suggestions about where to look next? I was able to workaround it by
defining a %MethodCode block for addContour() that explicitly calls
sipConvertToInstance(), which works fine, but I'd like to understand
what's going on.

Thanks,
-Jim C.


More information about the PyQt mailing list