I have a function in C++ that returns a vector<vector<double> > object. I have wrapped it for Python using Swig. When I call it, I am unable to subsequently modify the function’s output using the resize() or push_back() vector methods.
When I try this, I get an error that the ‘tuple’ object has no attribute ‘resize’ or ‘push_back’. Does Swig transform vectors into Tuple objects when I interact with them in Python? If that’s the case, then I assume the output from this function in Python is immutable, which is a problem. I can pass this object into wrapped methods that accept a vector of vectors of doubles. I just can’t mess with it using the vector methods from within Python. Any explanation on why this is or ideas on work-arounds would be appreciated.
Here is my swig file for reference. STL template lines are towards the end:
/* SolutionCombiner.i */
%module SolutionCombiner
%{
/* Put header files here or function declarations like below */
#include "Coord.hpp"
#include "MaterialData.hpp"
#include "FailureCriterion.hpp"
#include "QuadPointData.hpp"
#include "ModelSolution.hpp"
#include "ExclusionZone.hpp"
#include "CriticalLocation.hpp"
#include "FailureMode.hpp"
#include "ExecutiveFunctions.hpp"
#include <fstream>
#include <iostream>
%}
%{
#define SWIG_FILE_WITH_INIT
std::ostream& new_ofstream(const char* FileName){
return *(new std::ofstream(FileName));
}
std::istream& new_ifstream(const char* FileName){
return *(new std::ifstream(FileName));
}
void write(std::ostream* FOUT, char* OutString){
*FOUT << OutString;
}
std::ostream *get_cout(){return &std::cout;}
%}
%include "std_vector.i"
%include "std_string.i"
%include "std_set.i"
%include "../../source/Coord.hpp"
%include "../../source/MaterialData.hpp"
%include "../../source/FailureCriterion.hpp"
%include "../../source/QuadPointData.hpp"
%include "../../source/ModelSolution.hpp"
%include "../../source/ExclusionZone.hpp"
%include "../../source/CriticalLocation.hpp"
%include "../../source/FailureMode.hpp"
%include "../../source/ExecutiveFunctions.hpp"
namespace std {
%template(IntVector) vector<int>;
%template(DoubleVector) vector<double>;
%template(DoubleVVector) vector<vector<double> >;
%template(DoubleVVVector) vector<vector<vector<double> > >;
%template(SolutionVector) vector<ModelSolution>;
%template(CritLocVector) vector<CriticalLocation>;
%template(CritLocVVector) vector<vector<CriticalLocation> >;
%template(ModeVector) vector<FailureMode>;
%template(IntSet) set<int>;
}
std::ofstream& new_ofstream(char* FileName);
std::ifstream& new_ifstream(char* FileName);
std::iostream *get_cout();
Yes, the vector template returns an immutable Python tuple. Maybe you could modify the
std_vector.iimplementation to return lists, but there is probably a good reason for the choice. You could convert them to lists so you can manipulate them in Python:Note: I made a sample function that returned
vector<vector<double>>as a test.