I am developing Python bindings for a C++ class which extends a std::vector instantiation. To get a Python subscript operator working for this class I added __getitem__ function looking as follows (I cut irrelevant code and error handling):
class Column;
typedef vector<Column*> MetaDataBase;
class MetaData : public MetaDataBase {
public:
#ifdef SWIGPYTHON
Column* __getitem__(int i) { return (*this)[i]; }
#endif
};
The above works all right in Python for accessing single elements, but it does not work for slices.
OK, so I understand I need to change type of the function’s parameter to PyObject * and use PySlice_Check to see if the function is supposed to return a PyList.
This is fine, no problem with that. But because I have to return PyList from the function sometimes, the type of the __getitem__ return value has to be PyObject* as well and I cannot rely on SWIG to convert my C++ type (Column *) to a wrapper class. Also, when creating a slice, I need to ‘manually’ convert Column* to PyObject* before inserting it into the PyList.
How can I do it?
I think there’s a much simpler solution to this for
std::vectorwith SWIG+Python. SWIG’s Python code generation already has support for doing quite a good job wrapping some STL containers.If you add to the beginning of your module interface:
and somewhere, if you haven’t done so:
then this will cause the wrapped
std::vectorto meet the requirements of Python’s MutableSequence. (I think this should be sufficient to achieve what you’re looking for on the Python side, you might need to call SWIG with-extranativeas well).Also worth noting possibly – for your current
__getitem__you can declare and define it in the SWIG interface file using something like:Which allows you to do this without “polluting” your “normal” header files with SWIG+Python specific code.