4 #ifndef CT_CYTHON_FUNC_WRAPPER
5 #define CT_CYTHON_FUNC_WRAPPER
12 typedef double(*callback_wrapper)(double,
void*,
void**);
20 , m_exception_type(
nullptr)
21 , m_exception_value(
nullptr)
26 : m_func(other.m_func)
27 , m_exception_type(other.m_exception_type)
28 , m_exception_value(other.m_exception_value)
30 Py_XINCREF(m_exception_type);
31 Py_XINCREF(m_exception_value);
35 Py_XDECREF(m_exception_type);
36 Py_XDECREF(m_exception_value);
42 void setFunc(PyObject* f) {
46 PyObject* exceptionType() {
47 return m_exception_type;
49 void setExceptionType(PyObject* obj) {
50 Py_XDECREF(m_exception_type);
52 m_exception_type = obj;
55 PyObject* exceptionValue() {
56 return m_exception_value;
58 void setExceptionValue(PyObject* obj) {
59 Py_XDECREF(m_exception_value);
61 m_exception_value = obj;
66 PyObject* m_exception_type;
67 PyObject* m_exception_value;
77 CallbackError(
void* type,
void* value) :
78 CanteraError(
"Python callback function"),
79 m_type((PyObject*) type),
80 m_value((PyObject*) value)
89 m_type(info.exceptionType()),
90 m_value(info.exceptionValue())
94 info.setExceptionType(0);
95 info.setExceptionValue(0);
106 PyObject* name = PyObject_GetAttrString(m_type,
"__name__");
107 PyObject* value_str = PyObject_Str(m_value);
109 PyObject* name_bytes = PyUnicode_AsASCIIString(name);
110 PyObject* value_bytes = PyUnicode_AsASCIIString(value_str);
113 msg += PyBytes_AsString(name_bytes);
114 Py_DECREF(name_bytes);
116 msg +=
"<error determining exception type>";
122 msg += PyBytes_AsString(value_bytes);
123 Py_DECREF(value_bytes);
125 msg +=
"<error determining exception message>";
129 Py_XDECREF(value_str);
133 std::string
getClass()
const override {
146 Func1Py(callback_wrapper callback,
void* pyobj) :
147 m_callback(callback),
151 double eval(
double t)
const override {
152 void* err[2] = {0, 0};
153 double y = m_callback(t, m_pyobj, err);
155 throw CallbackError(err[0], err[1]);
161 callback_wrapper m_callback;
166 #if defined(CYTHON_HEX_VERSION) && CYTHON_HEX_VERSION >= 0x001DFFFF
167 extern PyObject* pyCanteraError;
170 extern PyObject* pyCanteraError;
186 template <
class ... Args>
187 std::function<void(Args ...)> pyOverride(PyObject* pyFunc,
void func(
PyFuncInfo&, Args ... args)) {
189 func_info.setFunc(pyFunc);
190 return [func_info, func](Args ... args)
mutable {
191 func(func_info, args ...);
192 if (func_info.exceptionType()) {
193 throw CallbackError(func_info);
199 template <
class ... Args>
200 std::function<int(Args ...)> pyOverride(PyObject* pyFunc,
int func(
PyFuncInfo&, Args ... args)) {
202 func_info.setFunc(pyFunc);
203 return [func_info, func](Args ... args)
mutable {
204 int ret = func(func_info, args ...);
205 if (func_info.exceptionType()) {
206 throw CallbackError(func_info);
215 inline int translate_exception()
218 if (!PyErr_Occurred()) {
223 }
catch (
const CallbackError& exn) {
225 PyErr_SetObject(exn.m_type, exn.m_value);
226 }
catch (
const std::out_of_range& exn) {
227 PyErr_SetString(PyExc_IndexError, exn.what());
229 PyErr_SetString(PyExc_NotImplementedError, exn.
what());
231 PyErr_SetString(pyCanteraError, exn.
what());
232 }
catch (
const std::exception& exn) {
233 PyErr_SetString(PyExc_RuntimeError, exn.what());
235 PyErr_SetString(PyExc_Exception,
"Unknown exception");
Base class for exceptions thrown by Cantera classes.
const char * what() const override
Get a description of the error.
virtual string getMessage() const
Method overridden by derived classes to format the error message.
CanteraError(const string &procedure, const string &msg, const Args &... args)
Normal Constructor for the CanteraError base class.
virtual string getClass() const
Method overridden by derived classes to indicate their type.
Base class for 'functor' classes that evaluate a function of one variable.
virtual double eval(double t) const
Evaluate the function.
An error indicating that an unimplemented function has been called.
A class to hold information needed to call Python functions from delegated methods (see class Delegat...
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...