30#ifndef _MBXMLUTILS_PYCPPWRAPPER_H_
31#define _MBXMLUTILS_PYCPPWRAPPER_H_
37#include <boost/filesystem/path.hpp>
38#if PY_MAJOR_VERSION < 3
39 #error "This file can only handle python >= 3"
45inline PyObject* PyRun_String_func(
const char *str,
int start, PyObject *globals, PyObject *locals) {
return PyRun_String(str, start, globals, locals); }
47#define PyRun_String PythonCpp::PyRun_String_func
50inline int PyFloat_Check_func(PyObject *p) {
return PyFloat_Check(p); }
52#define PyFloat_Check PythonCpp::PyFloat_Check_func
55inline int PyFloat_AS_DOUBLE_func(PyObject *p) {
return PyFloat_AS_DOUBLE(p); }
56#undef PyFloat_AS_DOUBLE
57#define PyFloat_AS_DOUBLE PythonCpp::PyFloat_AS_DOUBLE_func
60inline int PyBool_Check_func(PyObject *p) {
return PyBool_Check(p); }
62#define PyBool_Check PythonCpp::PyBool_Check_func
65inline int PyList_Check_func(PyObject *p) {
return PyList_Check(p); }
67#define PyList_Check PythonCpp::PyList_Check_func
70inline int PyObject_TypeCheck_func(PyObject *p, PyTypeObject *type) {
return PyObject_TypeCheck(p, type); }
71#undef PyObject_TypeCheck
72#define PyObject_TypeCheck PythonCpp::PyObject_TypeCheck_func
75inline int PyLong_Check_func(PyObject *p) {
return PyLong_Check(p); }
77#define PyLong_Check PythonCpp::PyLong_Check_func
80inline int PyUnicode_Check_func(PyObject *p) {
return PyUnicode_Check(p); }
82#define PyUnicode_Check PythonCpp::PyUnicode_Check_func
87 GilState() { state=PyGILState_Ensure(); }
88 ~GilState() { PyGILState_Release(state); }
94 PyGILState_STATE state;
100 constexpr PyO() =
default;
101 explicit PyO(PyObject *src,
bool srcIsBorrowedRef=
false) : p(src) {
if(srcIsBorrowedRef) Py_XINCREF(p); }
102 PyO(
const PyO &r) : p(r.p) { Py_XINCREF(p); }
103 PyO(
PyO &&r) noexcept : p(r.p) { r.p=
nullptr; }
110 PyO& operator=(
const PyO &r) { Py_XDECREF(p); p=r.p; Py_XINCREF(p);
return *
this; }
111 PyO& operator=(
PyO &&r)
noexcept { Py_XDECREF(p); p=r.p; r.p=
nullptr;
return *
this; }
112 void reset() { Py_XDECREF(p); p=
nullptr; }
113 void reset(PyObject *src,
bool srcIsBorrowedRef=
false) { Py_XDECREF(p); p=src;
if(srcIsBorrowedRef) Py_XINCREF(p); }
114 void swap(
PyO &r) { PyObject *temp=p; p=r.p; r.p=temp; }
115 PyObject* get(
bool incRef=
false)
const {
if(incRef) Py_XINCREF(p);
return p; }
116 long use_count()
const {
return p ? Py_REFCNT(p) : 0; }
117 PyObject* operator->()
const {
return p; }
118 PyO& incRef() { Py_XINCREF(p);
return *
this; }
119 operator bool()
const {
return p!=
nullptr; }
121 PyObject *p{
nullptr};
124inline bool operator==(
const PyO& l,
const PyO& r) {
return l.get()==r.get(); }
125inline bool operator!=(
const PyO& l,
const PyO& r) {
return l.get()!=r.get(); }
126inline bool operator< (
const PyO& l,
const PyO& r) {
return l.get()< r.get(); }
127inline bool operator> (
const PyO& l,
const PyO& r) {
return l.get()> r.get(); }
128inline bool operator<=(
const PyO& l,
const PyO& r) {
return l.get()<=r.get(); }
129inline bool operator>=(
const PyO& l,
const PyO& r) {
return l.get()>=r.get(); }
138 std::string getFile() {
return file; }
139 int getLine() {
return line; }
140 PyO getType() {
return type; }
141 PyO getValue() {
return value; }
142 PyO getTraceback() {
return traceback; }
143 const char* what()
const noexcept override;
147 PyO type, value, traceback;
148 mutable std::string msg;
152void checkPythonError();
159 inline static type convert(
const T &r) {
166 inline static PyO convert(PyObject *r) {
168 throw std::runtime_error(
"Internal error: Expected python object but got NULL pointer and no python exception is set.");
170 throw std::runtime_error(
"Internal error: Expected python object but a python object with 0 refcount and no python exception is set.");
177template<
typename Arg>
178inline Arg convertArg(
const Arg &arg) {
182inline PyObject* convertArg(
const PyO &o) {
183 if(o && o.use_count()<=0)
184 throw std::runtime_error(
"Internal error: access object with reference count <= 0. Check the source code.");
188inline const char* convertArg(
const std::string &o) {
202template<
typename PyRet,
typename... PyArgs,
typename... CallArgs>
203inline typename MapRetType<PyRet>::type callPy(
const char *file,
int line, PyRet (*func)(PyArgs...), CallArgs&&... args) {
208 ret=func(convertArg(std::forward<CallArgs>(args))...);
211 throw PythonException(file, line);
212 return MapRetType<PyRet>::convert(ret);
219#define CALLPY(...) PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__)
225#define CALLPYB(...) PythonCpp::callPy(__FILE__, __LINE__, __VA_ARGS__).incRef()
234void initializePython(
const boost::filesystem::path &main,
const std::string &pythonVersion,
235 const std::vector<boost::filesystem::path> &sysPathPrepend={},
236 const std::vector<boost::filesystem::path> &sysPathAppend={},
237 const std::vector<boost::filesystem::path> &possiblePrefix={},
238 const std::vector<boost::filesystem::path> &PATHAppend={});
241template<
typename... Args>
242PyO Py_BuildValue_(
const char *format, Args&&... args) {
243 return PyO(Py_BuildValue(format, convertArg(std::forward<Args>(args))...));
Definition: pycppwrapper.h:192
Definition: pycppwrapper.h:85
Definition: pycppwrapper.h:98
Definition: pycppwrapper.h:134
Definition: pycppwrapper.h:157