I have just found a problem concerning type checking when using a std::vector as input argument.
Here is a small module containing 2 new classes A and B
%module castswig
%{
#include <iostream>
%}
%include "std_vector.i"
%inline {
class A
{
public:
A() { std::cout << "A constructor\n"; }
};
}
%template() std::vector<A*>;
%inline {
class B
{
public:
B(const std::vector<A*> &listA) { std::cout << "B constructor\n"; }
};
}
And my python file showing the bug:
from castswig import *
a1=A()
a2=A()
b1 = B( [a1,a2] ) # <= OK
b2 = B( [1,2] ) # <= should fail
The problem is the last statement does not fail athough the input list contains integers instead of A objects!
I think the bug is located in "Lib/python/pystdcommon.swg" (line 49)
template <class Type>
struct traits_asptr {
static int asptr(PyObject *obj, Type **val) {
Type *p;
int res = (SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0) == SWIG_OK) ? SWIG_OLDOBJ : 0;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
return res;
}
};
The "res" variable is always 0(SWIG_OLDOBJ=0) after the call of SWIG_ConvertPtr. That's why "SWIG_IsOK(res)" is always true and the cast is always done.
I have replaced this line by:
int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
and it seems to work. An exception is thrown as expected and "b2 = B([1,2])" fails as it should.
I found the same problem, commited in svn change set 10958. Fixed for 1.3.37