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

Phil Thompson phil at riverbankcomputing.com
Tue Dec 9 22:15:59 GMT 2008


On Tue, 09 Dec 2008 13:08:23 -0600, "Jim Crowell" <jaclists at mailbolt.com>
wrote:
> 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.

Impossible to tell from the above. Can you produce a small, complete
example?

Phil


More information about the PyQt mailing list