swig/Examples/test-suite/python_pickle.i
William S Fulton 96fae38be2 Fix Python pickling and metaclass for builtin wrappers
The metaclass (SwigPyObjectType) for SWIG objects was not defined in
a way that let importlib successfully import the Python wrappers.
The pickle module failed because it couldn't determine what module the
SWIG wrapped objects are in.

I've changed the definition of SwigPyObjectType using more normal
builtin type definitions. There are still some open questions:
- None of the builtin types, like swig_static_var_getset_descriptor and
  SwigPyObject are added into any module. No call to PyModule_AddObject
  is made, so isinstance cannot be used for any wrapped type, all of
  which are derived from SwigPyObject.

Closes #808
2016-10-14 07:30:44 +01:00

51 lines
1.1 KiB
OpenEdge ABL

%module python_pickle
%include <std_string.i>
%extend PickleMe {
#if 0
// Note: %pythoncode can't be used with -builtin
%pythoncode %{
def __reduce__(self):
print "In Python __reduce__"
return (type(self), (self.msg, ))
%}
#else
// Equivalent to Python code above
PyObject *__reduce__() {
if (debug)
std::cout << "In C++ __reduce__" << std::endl;
PyObject *args = PyTuple_New(1);
PyTuple_SetItem(args, 0, SWIG_From_std_string(self->msg));
swig_type_info *ty = SWIGTYPE_p_PickleMe;
SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
#if defined(SWIGPYTHON_BUILTIN)
PyObject *callable = (PyObject *)data->pytype;
#else
PyObject *callable = data->klass;
#endif
Py_INCREF(callable);
PyObject *ret = PyTuple_New(2);
PyTuple_SetItem(ret, 0, callable);
PyTuple_SetItem(ret, 1, args);
return ret;
}
#endif
}
%inline %{
#include <iostream>
bool debug = false;
struct PickleMe {
std::string msg;
PickleMe(const std::string& msg) : msg(msg) {
if (debug)
std::cout << "In C++ constructor " << " [" << msg << "]" << std::endl;
}
};
%}