30 #ifndef _PY2PY3CPPWRAPPER_H_
31 #define _PY2PY3CPPWRAPPER_H_
40 #include <boost/locale/encoding_utf.hpp>
45 void initializePython(
const std::string &main,
const std::string &home=
"") {
46 static const std::string mainStatic=main;
47 #if PY_MAJOR_VERSION < 3
48 Py_SetProgramName(const_cast<char*>(mainStatic.c_str()));
50 Py_SetPythonHome(const_cast<char*>(home.c_str()));
52 Py_SetProgramName(const_cast<wchar_t*>(boost::locale::conv::utf_to_utf<wchar_t>(mainStatic).c_str()));
54 Py_SetPythonHome(const_cast<wchar_t*>(boost::locale::conv::utf_to_utf<wchar_t>(home).c_str()));
62 inline bool PyLong_Check_Py2Py3(PyObject *o) {
63 #if PY_MAJOR_VERSION < 3
64 return PyLong_Check(o) || PyInt_Check(o);
66 return PyLong_Check(o);
70 inline long PyLong_AsLong_Py2Py3(PyObject *o) {
71 #if PY_MAJOR_VERSION < 3
73 return PyInt_AsLong(o);
74 return PyLong_AsLong(o);
76 return PyLong_AsLong(o);
80 inline bool PyUnicode_Check_Py2Py3(PyObject *o) {
81 #if PY_MAJOR_VERSION < 3
82 return PyUnicode_Check(o) || PyString_Check(o);
84 return PyUnicode_Check(o);
89 inline std::string PyUnicode_AsUTF8_Py2Py3(PyObject *o) {
90 #if PY_MAJOR_VERSION < 3
91 if(PyString_Check(o)) {
92 char *retc=PyString_AsString(o);
96 PyObject *str=PyUnicode_AsUTF8String(o);
98 char *retc=PyString_AsString(str);
103 std::string ret=retc;
107 char *retc=PyUnicode_AsUTF8(o);
116 #undef PyUnicode_Check
117 #define PyLong_Check PythonCpp::PyLong_Check_Py2Py3
118 #define PyLong_AsLong PythonCpp::PyLong_AsLong_Py2Py3
119 #define PyUnicode_Check PythonCpp::PyUnicode_Check_Py2Py3
120 #define PyUnicode_AsUTF8 PythonCpp::PyUnicode_AsUTF8_Py2Py3
123 inline PyObject* PyRun_String_func(
const char *str,
int start, PyObject *globals, PyObject *locals) {
return PyRun_String(str, start, globals, locals); }
125 #define PyRun_String PythonCpp::PyRun_String_func
128 inline int PyFloat_Check_func(PyObject *p) {
return PyFloat_Check(p); }
130 #define PyFloat_Check PythonCpp::PyFloat_Check_func
133 inline int PyFloat_AS_DOUBLE_func(PyObject *p) {
return PyFloat_AS_DOUBLE(p); }
134 #undef PyFloat_AS_DOUBLE
135 #define PyFloat_AS_DOUBLE PythonCpp::PyFloat_AS_DOUBLE_func
138 inline int PyBool_Check_func(PyObject *p) {
return PyBool_Check(p); }
140 #define PyBool_Check PythonCpp::PyBool_Check_func
143 inline int PyList_Check_func(PyObject *p) {
return PyList_Check(p); }
145 #define PyList_Check PythonCpp::PyList_Check_func
148 inline int PyObject_TypeCheck_func(PyObject *p, PyTypeObject *type) {
return PyObject_TypeCheck(p, type); }
149 #undef PyObject_TypeCheck
150 #define PyObject_TypeCheck PythonCpp::PyObject_TypeCheck_func
155 constexpr
PyO() : p(
nullptr) {}
156 explicit PyO(PyObject *src,
bool srcIsBorrowedRef=
false) : p(src) {
if(srcIsBorrowedRef) Py_XINCREF(p); }
157 PyO(
const PyO &r) : p(r.p) { Py_XINCREF(p); }
158 PyO(PyO &&r) : p(r.p) { r.p=
nullptr; }
159 ~PyO() { Py_XDECREF(p); }
160 PyO& operator=(
const PyO &r) { Py_XDECREF(p); p=r.p; Py_XINCREF(p);
return *
this; }
161 PyO& operator=(PyO &&r) { Py_XDECREF(p); p=r.p; r.p=
nullptr;
return *
this; }
162 void reset() { Py_XDECREF(p); p=
nullptr; }
163 void reset(PyObject *src,
bool srcIsBorrowedRef=
false) { Py_XDECREF(p); p=src;
if(srcIsBorrowedRef) Py_XINCREF(p); }
164 void swap(PyO &r) { PyObject *temp=p; p=r.p; r.p=temp; }
165 PyObject*
get(
bool incRef=
false)
const {
if(incRef) Py_XINCREF(p);
return p; }
166 long use_count()
const {
return p ? Py_REFCNT(p) : 0; }
167 PyObject* operator->()
const {
return p; }
168 PyO& incRef() { Py_XINCREF(p);
return *
this; }
169 operator bool()
const {
return p!=
nullptr; }
174 inline bool operator==(
const PyO& l,
const PyO& r) {
return l.get()==r.get(); }
175 inline bool operator!=(
const PyO& l,
const PyO& r) {
return l.get()!=r.get(); }
176 inline bool operator< (
const PyO& l,
const PyO& r) {
return l.get()< r.get(); }
177 inline bool operator> (
const PyO& l,
const PyO& r) {
return l.get()> r.get(); }
178 inline bool operator<=(
const PyO& l,
const PyO& r) {
return l.get()<=r.get(); }
179 inline bool operator>=(
const PyO& l,
const PyO& r) {
return l.get()>=r.get(); }
188 std::string getFile() {
return file; }
189 int getLine() {
return line; }
190 PyO getType() {
return type; }
191 PyO getValue() {
return value; }
192 PyO getTraceback() {
return traceback; }
193 const char* what()
const throw();
197 PyO type, value, traceback;
198 mutable std::string msg;
202 void checkPythonError() {
212 inline static type convert(
const T &r) {
219 inline static PyO convert(PyObject *r) {
221 throw std::runtime_error(
"Internal error: Expected python object but got NULL pointer and no python exception is set.");
223 throw std::runtime_error(
"Internal error: Expected python object but a python object with 0 refcount and no python exception is set.");
230 template<
typename Arg>
231 inline Arg convertArg(
const Arg &arg) {
235 inline PyObject* convertArg(
const PyO &o) {
236 if(o && o.use_count()<=0)
237 throw std::runtime_error(
"Internal error: access object with reference count <= 0. Check the source code.");
241 inline const char* convertArg(
const std::string &o) {
247 template<
typename PyRet,
typename... PyArgs,
typename... CallArgs>
248 inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs...), CallArgs&&... args) {
249 PyRet ret=func(convertArg(std::forward<CallArgs>(args))...);
251 throw PythonException(file, line);
252 return MapRetType<PyRet>::convert(ret);
259 #define CALLPY(...) PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__)
265 #define CALLPYB(...) PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__).incRef()
268 PythonException::PythonException(
const char *file_,
int line_) : file(file_), line(line_) {
270 if(!PyErr_Occurred())
271 throw std::runtime_error(
"Internal error: PythonException object created but no python error occured.");
273 PyObject *type_, *value_, *traceback_;
274 PyErr_Fetch(&type_, &value_, &traceback_);
277 traceback=PyO(traceback_);
280 const char* PythonException::what()
const throw() {
285 PyObject *savedstderr=PySys_GetObject(const_cast<char*>(
"stderr"));
287 throw std::runtime_error(
"Internal error: no sys.stderr available.");
288 PyObject *io=PyImport_ImportModule(
"io");
290 throw std::runtime_error(
"Internal error: cannot load io module.");
291 #if PY_MAJOR_VERSION < 3
292 PyObject *fileIO=PyObject_GetAttrString(io,
"BytesIO");
294 PyObject *fileIO=PyObject_GetAttrString(io,
"StringIO");
297 throw std::runtime_error(
"Internal error: cannot get in memory file class.");
299 PyObject *buf=PyObject_CallObject(fileIO, NULL);
302 throw std::runtime_error(
"Internal error: cannot create new in memory file instance");
303 if(PySys_SetObject(const_cast<char*>(
"stderr"), buf)!=0)
304 throw std::runtime_error(
"Internal error: cannot redirect stderr");
306 PyErr_Restore(type.get(), value.get(), traceback.get());
307 Py_XINCREF(type.get());
308 Py_XINCREF(value.get());
309 Py_XINCREF(traceback.get());
313 if(PySys_SetObject(const_cast<char*>(
"stderr"), savedstderr)!=0)
314 throw std::runtime_error(
"Internal error: cannot revert redirect stderr");
316 PyObject *getvalue=PyObject_GetAttrString(buf,
"getvalue");
318 throw std::runtime_error(
"Internal error: cannot get getvalue attribute");
319 PyObject *pybufstr=PyObject_CallObject(getvalue, NULL);
321 throw std::runtime_error(
"Internal error: cannot get string from in memory file output");
324 #if PY_MAJOR_VERSION < 3
325 char *strc=PyBytes_AsString(pybufstr);
327 throw std::runtime_error(
"Internal error: cannot get c string");
328 std::string str(strc);
330 std::string str=PyUnicode_AsUTF8(pybufstr);
332 throw std::runtime_error(
"Internal error: cannot get c string");
335 std::stringstream strstr;
336 strstr<<
"Python exception";
338 strstr<<
" at "<<file<<
":"<<line;
339 strstr<<
":"<<std::endl<<str;
Definition: py2py3cppwrapper.h:153
Definition: py2py3cppwrapper.h:184
Definition: py2py3cppwrapper.h:210