36 #ifndef VIGRA_PYTHON_UTILITY_HXX
37 #define VIGRA_PYTHON_UTILITY_HXX
41 #include "vigra/error.hxx"
42 #include "vigra/tinyvector.hxx"
47 template <
class PYOBJECT_PTR>
48 void pythonToCppException(PYOBJECT_PTR obj)
52 PyObject * type, * value, *
trace;
53 PyErr_Fetch(&type, &value, &trace);
56 std::string message(((PyTypeObject *)type)->tp_name);
57 if(PyString_Check(value))
59 message += std::string(
": ") + PyString_AS_STRING(value);
65 throw std::runtime_error(message.c_str());
75 typedef PyObject element_type;
76 typedef PyObject value_type;
77 typedef PyObject * pointer;
78 typedef PyObject & reference;
80 enum refcount_policy { increment_count, borrowed_reference = increment_count,
81 keep_count, new_reference = keep_count };
83 explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count)
86 if(rp == increment_count)
92 python_ptr(python_ptr
const & p)
98 python_ptr & operator=(pointer p)
104 python_ptr & operator=(python_ptr
const & r)
115 void reset(pointer p = 0, refcount_policy rp = increment_count)
119 if(rp == increment_count)
127 pointer release(
bool return_borrowed_reference =
false)
131 if(return_borrowed_reference)
138 reference operator* ()
const
140 vigra_precondition(ptr_ != 0,
"python_ptr::operator*(): Cannot dereference NULL pointer.");
144 pointer operator-> ()
const
146 vigra_precondition(ptr_ != 0,
"python_ptr::operator->(): Cannot dereference NULL pointer.");
160 operator pointer()
const
165 bool operator! ()
const
172 return ptr_ && ptr_->ob_refcnt == 1;
175 void swap(python_ptr & other)
177 std::swap(ptr_, other.ptr_);
182 return ptr_ == p.ptr_;
192 return ptr_ != p.ptr_;
201 inline void swap(python_ptr & a, python_ptr & b)
207 getPythonDictionary(
char const * k1 = 0, PyObject * a1 = 0,
208 char const * k2 = 0, PyObject * a2 = 0,
209 char const * k3 = 0, PyObject * a3 = 0)
211 python_ptr dict(PyDict_New(), python_ptr::keep_count);
212 pythonToCppException(dict);
214 PyDict_SetItemString(dict, k1, a1);
216 PyDict_SetItemString(dict, k2, a2);
218 PyDict_SetItemString(dict, k3, a3);
222 inline python_ptr pythonFromNumber(
bool t)
224 python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count);
225 pythonToCppException(res);
229 #define VIGRA_PYTHON_NUMBER_CONVERSION(type, condition, fct1, fct2) \
230 inline python_ptr pythonFromNumber(type t) \
234 res = python_ptr(fct1(t), python_ptr::keep_count); \
236 res = python_ptr(fct2(t), python_ptr::keep_count); \
237 pythonToCppException(res); \
241 VIGRA_PYTHON_NUMBER_CONVERSION(
signed char,
true, PyInt_FromLong, PyInt_FromLong)
242 VIGRA_PYTHON_NUMBER_CONVERSION(
unsigned char, true, PyInt_FromLong, PyInt_FromLong)
243 VIGRA_PYTHON_NUMBER_CONVERSION(
short, true, PyInt_FromLong, PyInt_FromLong)
244 VIGRA_PYTHON_NUMBER_CONVERSION(
unsigned short, true, PyInt_FromLong, PyInt_FromLong)
245 VIGRA_PYTHON_NUMBER_CONVERSION(
long, true, PyInt_FromLong, PyInt_FromLong)
246 VIGRA_PYTHON_NUMBER_CONVERSION(
unsigned long, sizeof(
unsigned long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong)
247 VIGRA_PYTHON_NUMBER_CONVERSION(
int, sizeof(
long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyInt_FromLong)
248 VIGRA_PYTHON_NUMBER_CONVERSION(
unsigned int, sizeof(
unsigned int) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong)
249 VIGRA_PYTHON_NUMBER_CONVERSION(
long long, true, PyLong_FromLongLong, PyLong_FromLongLong)
250 VIGRA_PYTHON_NUMBER_CONVERSION(
unsigned long long, true, PyLong_FromUnsignedLongLong, PyLong_FromUnsignedLongLong)
251 VIGRA_PYTHON_NUMBER_CONVERSION(
float, true, PyFloat_FromDouble, PyFloat_FromDouble)
252 VIGRA_PYTHON_NUMBER_CONVERSION(
double, true, PyFloat_FromDouble, PyFloat_FromDouble)
254 #undef VIGRA_PYTHON_NUMBER_CONVERSION
256 template <
class T,
int N>
257 python_ptr shapeToPythonTuple(TinyVector<T, N>
const & shape)
259 python_ptr tuple(PyTuple_New(N), python_ptr::keep_count);
260 pythonToCppException(tuple);
261 for(
unsigned int k=0; k<N; ++k)
263 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release());
269 python_ptr shapeToPythonTuple(ArrayVectorView<T>
const & shape)
271 python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count);
272 pythonToCppException(tuple);
273 for(
unsigned int k=0; k<shape.size(); ++k)
275 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release());
283 #endif // VIGRA_PYTHON_UTILITY_HXX