#1184 2.0.4 typedef expansion regression

closed-fixed
5
2011-07-28
2011-07-26
Michel Zou
No

Hi,

There is a regression between swig 2.0.4 and swig 2.0.3.
Swig fails to understand a typedef spread across template classes that should expand to std::string.
Here is the minimal module that fails.
It tries to wrap the object DescriptionImplementation which is basically a collection of strings.
DescriptionImplementation provides the add method to add one single element.
The wrapping of that method fails as swig doesn't understand it should take a string as argument.

============================================================
%module example

%include std_string.i

%inline %{
#include <string> // for std::string

typedef std::string String;

namespace Type
{
template <class T> class TypedInterfaceObject {};

template <class T> class TypedCollectionInterfaceObject : public TypedInterfaceObject<T>
{
public:
typedef T ImplementationType;

typedef typename ImplementationType::ElementType ImplementationElementType;

/** Method add() appends an element to the collection */
void add(const ImplementationElementType & elt);

}; /* class TypedCollectionInterfaceObject */

template <class T>
class PersistentCollection
{
public:
typedef T ElementType;

/** Method add() appends an element to the collection */
inline virtual void add(const T & elt) {}

}; /* class PersistentCollection */

} /* namespace Type */
%}

%template(StringPersistentCollection) Type::PersistentCollection<String>;

%inline %{

namespace Type
{

class DescriptionImplementation
: public PersistentCollection<String>
{
public:

typedef PersistentCollection<String>::ElementType ElementType;

/** Default constructor */
DescriptionImplementation();

}; /* class DescriptionImplementation */

} /* namespace Type */

%}

%template(DescriptionImplementationTypedInterfaceObject) Type::TypedInterfaceObject<Type::DescriptionImplementation>;
%template(DescriptionImplementationTypedCollectionInterfaceObject) Type::TypedCollectionInterfaceObject<Type::DescriptionImplementation>;

==============================================

Swig fails to wrap the Type::DescriptionImplementation::add(String) method.
What I get with swig 2.0.3 is this output :

==============================================
SWIGINTERN PyObject *_wrap_DescriptionImplementationTypedCollectionInterfaceObject_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *arg1 = (Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *) 0 ;
Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 = SWIG_OLDOBJ ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;

if (!PyArg_ParseTuple(args,(char *)"OO:DescriptionImplementationTypedCollectionInterfaceObject_add",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Type__TypedCollectionInterfaceObjectT_Type__DescriptionImplementation_t, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "1"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *""'");
}
arg1 = reinterpret_cast< Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > * >(argp1);
{
std::string *ptr = (std::string *)0;
res2 = SWIG_AsPtr_std_string(obj1, &ptr);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "2"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &""'");
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "2"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &""'");
}
arg2 = ptr;
}
(arg1)->add((Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &)*arg2);
resultobj = SWIG_Py_Void();
if (SWIG_IsNewObj(res2)) delete arg2;
return resultobj;
fail:
if (SWIG_IsNewObj(res2)) delete arg2;
return NULL;
}
==============================================

One can see that swig 2.0.3 tries to get a string from arg #2, which is ok:
std::string *ptr = (std::string *)0;
res2 = SWIG_AsPtr_std_string(obj1, &ptr);

But with swig 2.0.4 the wrapped function is different regarding this very same argument:

===============================================

SWIGINTERN PyObject *_wrap_DescriptionImplementationTypedCollectionInterfaceObject_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *arg1 = (Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *) 0 ;
Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType *arg2 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;

if (!PyArg_ParseTuple(args,(char *)"OO:DescriptionImplementationTypedCollectionInterfaceObject_add",&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Type__TypedCollectionInterfaceObjectT_Type__DescriptionImplementation_t, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "1"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > *""'");
}
arg1 = reinterpret_cast< Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation > * >(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Type__PersistentCollectionT_String_t__ElementType, 0 | 0);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "2"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &""'");
}
if (!argp2) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "2"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &""'");
}
arg2 = reinterpret_cast< Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType * >(argp2);
(arg1)->add((Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &)*arg2);
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
===============================================

Now swig 2.0.4 is lost and tries to convert my string argument to that crap:
arg2 = reinterpret_cast< Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType * >(argp2);

As a result when I try to load my module, (import example; des = example.DescriptionImplementation() ; des.add('Hey!') )
I expectedly got the python exception raised by :
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DescriptionImplementationTypedCollectionInterfaceObject_add" "', argument " "2"" of type '" "Type::TypedCollectionInterfaceObject< Type::DescriptionImplementation >::ImplementationElementType const &""'");

Regards.

Discussion

  • Michel Zou

    Michel Zou - 2011-07-26
     
  • William Fulton

    William Fulton - 2011-07-28
    • assigned_to: nobody --> wsfulton
    • labels: 102864 --> code generation (general)
    • status: open --> closed-fixed
     
  • William Fulton

    William Fulton - 2011-07-28

    The regression was introduced in rev 12640 to fix bug #3286333: infinite recursion with mutual "using namespace" clause. Rev 12764 improves scope lookup and fixes the regression. Hence the next release - swig-2.0.5 will fix this regression.

    As we didn't have any tests like this one, I've added it to the test-suite.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks