30 #ifndef _PY2PY3CPPWRAPPER_H_
31 #define _PY2PY3CPPWRAPPER_H_
38 #include <boost/shared_ptr.hpp>
39 #include <boost/locale/encoding_utf.hpp>
44 void initializePython(
const std::string &main,
const std::vector<std::string> &args=std::vector<std::string>()) {
45 #if PY_MAJOR_VERSION < 3
46 Py_SetProgramName(const_cast<char*>(main.c_str()));
48 std::vector<char*> argv(args.size());
49 for(
size_t i=0; i<args.size(); ++i)
50 argv[i]=const_cast<char*>(args[i].c_str());
51 PySys_SetArgvEx(args.size(), &argv[0], 0);
53 Py_SetProgramName(const_cast<wchar_t*>(boost::locale::conv::utf_to_utf<wchar_t>(main).c_str()));
55 std::vector<wchar_t*> argv(args.size());
56 std::vector<std::wstring> argsw;
57 argsw.reserve(args.size());
58 for(
size_t i=0; i<args.size(); ++i) {
59 argsw.push_back(boost::locale::conv::utf_to_utf<wchar_t>(args[i]));
60 argv[i]=
const_cast<wchar_t*
>(argsw[i].c_str());
62 PySys_SetArgvEx(args.size(), &argv[0], 0);
69 inline bool PyLong_Check_Py2Py3(PyObject *o) {
70 #if PY_MAJOR_VERSION < 3
71 return PyLong_Check(o) || PyInt_Check(o);
73 return PyLong_Check(o);
77 inline long PyLong_AsLong_Py2Py3(PyObject *o) {
78 #if PY_MAJOR_VERSION < 3
80 return PyInt_AsLong(o);
81 return PyLong_AsLong(o);
83 return PyLong_AsLong(o);
87 inline bool PyUnicode_Check_Py2Py3(PyObject *o) {
88 #if PY_MAJOR_VERSION < 3
89 return PyUnicode_Check(o) || PyString_Check(o);
91 return PyUnicode_Check(o);
96 inline std::string PyUnicode_AsUTF8_Py2Py3(PyObject *o) {
97 #if PY_MAJOR_VERSION < 3
98 if(PyString_Check(o)) {
99 char *retc=PyString_AsString(o);
103 PyObject *str=PyUnicode_AsUTF8String(o);
105 char *retc=PyString_AsString(str);
110 std::string ret=retc;
114 char *retc=PyUnicode_AsUTF8(o);
123 #undef PyUnicode_Check
124 #define PyLong_Check PythonCpp::PyLong_Check_Py2Py3
125 #define PyLong_AsLong PythonCpp::PyLong_AsLong_Py2Py3
126 #define PyUnicode_Check PythonCpp::PyUnicode_Check_Py2Py3
127 #define PyUnicode_AsUTF8 PythonCpp::PyUnicode_AsUTF8_Py2Py3
130 inline PyObject* PyRun_String_func(
const char *str,
int start, PyObject *globals, PyObject *locals) {
return PyRun_String(str, start, globals, locals); }
132 #define PyRun_String PythonCpp::PyRun_String_func
135 inline int PyFloat_Check_func(PyObject *p) {
return PyFloat_Check(p); }
137 #define PyFloat_Check PythonCpp::PyFloat_Check_func
140 inline int PyFloat_AS_DOUBLE_func(PyObject *p) {
return PyFloat_AS_DOUBLE(p); }
141 #undef PyFloat_AS_DOUBLE
142 #define PyFloat_AS_DOUBLE PythonCpp::PyFloat_AS_DOUBLE_func
145 inline int PyBool_Check_func(PyObject *p) {
return PyBool_Check(p); }
147 #define PyBool_Check PythonCpp::PyBool_Check_func
150 inline int PyList_Check_func(PyObject *p) {
return PyList_Check(p); }
152 #define PyList_Check PythonCpp::PyList_Check_func
155 inline int PyObject_TypeCheck_func(PyObject *p, PyTypeObject *type) {
return PyObject_TypeCheck(p, type); }
156 #undef PyObject_TypeCheck
157 #define PyObject_TypeCheck PythonCpp::PyObject_TypeCheck_func
160 typedef boost::shared_ptr<PyObject> PyO;
169 std::string getFile() {
return file; }
170 int getLine() {
return line; }
171 PyO getType() {
return type; }
172 PyO getValue() {
return value; }
173 PyO getTraceback() {
return traceback; }
174 const char* what()
const throw();
178 PyO type, value, traceback;
179 mutable std::string msg;
183 void checkPythonError() {
193 inline static type convert(
const T &r) {
200 inline static PyO convert(PyObject *r) {
202 throw std::runtime_error(
"Internal error: Expected python object but got NULL pointer and not python exception is set.");
203 return PyO(r, &Py_DecRef);
209 template<
typename Arg>
210 inline Arg convertArg(
const Arg &arg) {
214 inline PyObject* convertArg(
const PyO &o) {
215 if(o && Py_REFCNT(o.get())<=0)
216 throw std::runtime_error(
"Internal error: access object with reference count <= 0. Check the source code.");
220 inline const char* convertArg(
const std::string &o) {
236 template<
typename PyRet>
237 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)()) {
240 throw PythonException(file, line);
241 return MapRetType<PyRet>::convert(ret);
244 template<
typename PyRet,
typename PyArgs1,
typename CallArgs1>
245 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs1), CallArgs1 args1) {
246 PyRet ret=func(convertArg(args1));
248 throw PythonException(file, line);
249 return MapRetType<PyRet>::convert(ret);
252 template<
typename PyRet,
typename PyArgs1,
typename PyArgs2,
typename CallArgs1,
typename CallArgs2>
253 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs1, PyArgs2), CallArgs1 args1, CallArgs2 args2) {
254 PyRet ret=func(convertArg(args1), convertArg(args2));
256 throw PythonException(file, line);
257 return MapRetType<PyRet>::convert(ret);
260 template<
typename PyRet,
typename PyArgs1,
typename PyArgs2,
typename PyArgs3,
typename CallArgs1,
typename CallArgs2,
typename CallArgs3>
261 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs1, PyArgs2, PyArgs3), CallArgs1 args1, CallArgs2 args2, CallArgs3 args3) {
262 PyRet ret=func(convertArg(args1), convertArg(args2), convertArg(args3));
264 throw PythonException(file, line);
265 return MapRetType<PyRet>::convert(ret);
268 template<
typename PyRet,
typename PyArgs1,
typename PyArgs2,
typename PyArgs3,
typename PyArgs4,
typename CallArgs1,
typename CallArgs2,
typename CallArgs3,
typename CallArgs4>
269 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs1, PyArgs2, PyArgs3, PyArgs4), CallArgs1 args1, CallArgs2 args2, CallArgs3 args3, CallArgs4 args4) {
270 PyRet ret=func(convertArg(args1), convertArg(args2), convertArg(args3), convertArg(args4));
272 throw PythonException(file, line);
273 return MapRetType<PyRet>::convert(ret);
276 template<
typename PyRet,
typename PyArgs1,
typename PyArgs2,
typename PyArgs3,
typename PyArgs4,
typename PyArgs5,
typename CallArgs1,
typename CallArgs2,
typename CallArgs3,
typename CallArgs4,
typename CallArgs5>
277 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs1, PyArgs2, PyArgs3, PyArgs4, PyArgs5), CallArgs1 args1, CallArgs2 args2, CallArgs3 args3, CallArgs4 args4, CallArgs5 args5) {
278 PyRet ret=func(convertArg(args1), convertArg(args2), convertArg(args3), convertArg(args4), convertArg(args5));
280 throw PythonException(file, line);
281 return MapRetType<PyRet>::convert(ret);
288 #define CALLPY(...) PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__)
294 #define CALLPYB(...) PythonCpp::PyIncRef(PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__))
298 inline const PyO& PyIncRef(
const PyO &o) {
299 if(Py_REFCNT(o.get())<=0)
300 throw std::runtime_error(
"Internal error: Access object with reference count <= 0. Check the source code.");
306 PythonException::PythonException(
const char *file_,
int line_) : file(file_), line(line_) {
308 if(!PyErr_Occurred())
309 throw std::runtime_error(
"Internal error: PythonException object created but no python error occured.");
311 PyObject *type_, *value_, *traceback_;
312 PyErr_Fetch(&type_, &value_, &traceback_);
313 type=PyO(type_, &Py_DecRef);
314 value=PyO(value_, &Py_DecRef);
315 traceback=PyO(traceback_, &Py_DecRef);
318 const char* PythonException::what()
const throw() {
323 PyObject *savedstderr=PySys_GetObject(const_cast<char*>(
"stderr"));
325 throw std::runtime_error(
"Internal error: no sys.stderr available.");
326 PyObject *io=PyImport_ImportModule(
"io");
328 throw std::runtime_error(
"Internal error: cannot load io module.");
329 #if PY_MAJOR_VERSION < 3
330 PyObject *fileIO=PyObject_GetAttrString(io,
"BytesIO");
332 PyObject *fileIO=PyObject_GetAttrString(io,
"StringIO");
335 throw std::runtime_error(
"Internal error: cannot get in memory file class.");
337 PyObject *buf=PyObject_CallObject(fileIO, NULL);
340 throw std::runtime_error(
"Internal error: cannot create new in memory file instance");
341 if(PySys_SetObject(const_cast<char*>(
"stderr"), buf)!=0)
342 throw std::runtime_error(
"Internal error: cannot redirect stderr");
344 PyErr_Restore(type.get(), value.get(), traceback.get());
345 Py_XINCREF(type.get());
346 Py_XINCREF(value.get());
347 Py_XINCREF(traceback.get());
351 if(PySys_SetObject(const_cast<char*>(
"stderr"), savedstderr)!=0)
352 throw std::runtime_error(
"Internal error: cannot revert redirect stderr");
354 PyObject *getvalue=PyObject_GetAttrString(buf,
"getvalue");
356 throw std::runtime_error(
"Internal error: cannot get getvalue attribute");
357 PyObject *pybufstr=PyObject_CallObject(getvalue, NULL);
359 throw std::runtime_error(
"Internal error: cannot get string from in memory file output");
362 #if PY_MAJOR_VERSION < 3
363 char *strc=PyBytes_AsString(pybufstr);
365 throw std::runtime_error(
"Internal error: cannot get c string");
366 std::string str(strc);
368 std::string str=PyUnicode_AsUTF8(pybufstr);
370 throw std::runtime_error(
"Internal error: cannot get c string");
373 std::stringstream strstr;
374 strstr<<
"Python exception";
376 strstr<<
" at "<<file<<
":"<<line;
377 strstr<<
":"<<std::endl<<str;;
Definition: py2py3cppwrapper.h:165
Definition: py2py3cppwrapper.h:191