[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

python_utility.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2009 by Ullrich Koethe and Hans Meine */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_PYTHON_UTILITY_HXX
37 #define VIGRA_PYTHON_UTILITY_HXX
38 
39 #include <Python.h>
40 #include <algorithm>
41 #include <string>
42 #include "vigra/error.hxx"
43 #include "vigra/tinyvector.hxx"
44 
45 namespace vigra {
46 
47 template <class PYOBJECT_PTR>
48 void pythonToCppException(PYOBJECT_PTR obj)
49 {
50  if(obj != 0)
51  return;
52  PyObject * type, * value, * trace;
53  PyErr_Fetch(&type, &value, &trace);
54  if(type == 0)
55  return;
56  std::string message(((PyTypeObject *)type)->tp_name);
57  if(PyString_Check(value))
58  {
59  message += std::string(": ") + PyString_AS_STRING(value);
60  }
61 
62  Py_XDECREF(type);
63  Py_XDECREF(value);
64  Py_XDECREF(trace);
65  throw std::runtime_error(message.c_str());
66 }
67 
68 /********************************************************/
69 /* */
70 /* python_ptr */
71 /* */
72 /********************************************************/
73 
74 class python_ptr
75 {
76  private:
77  PyObject * ptr_;
78 
79  public:
80 
81  typedef PyObject element_type;
82  typedef PyObject value_type;
83  typedef PyObject * pointer;
84  typedef PyObject & reference;
85 
86  enum refcount_policy { increment_count, borrowed_reference = increment_count,
87  keep_count, new_reference = keep_count };
88 
89  explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count)
90  : ptr_( p )
91  {
92  if(rp == increment_count)
93  {
94  Py_XINCREF(ptr_);
95  }
96  }
97 
98  python_ptr(python_ptr const & p)
99  : ptr_(p.ptr_)
100  {
101  Py_XINCREF(ptr_);
102  }
103 
104  python_ptr & operator=(pointer p)
105  {
106  reset(p);
107  return *this;
108  }
109 
110  python_ptr & operator=(python_ptr const & r)
111  {
112  reset(r.ptr_);
113  return *this;
114  }
115 
116  ~python_ptr()
117  {
118  reset();
119  }
120 
121  void reset(pointer p = 0, refcount_policy rp = increment_count)
122  {
123  if(p == ptr_)
124  return;
125  if(rp == increment_count)
126  {
127  Py_XINCREF(p);
128  }
129  Py_XDECREF(ptr_);
130  ptr_ = p;
131  }
132 
133  pointer release(bool return_borrowed_reference = false)
134  {
135  pointer p = ptr_;
136  ptr_ = 0;
137  if(return_borrowed_reference)
138  {
139  Py_XDECREF(p);
140  }
141  return p;
142  }
143 
144  reference operator* () const
145  {
146  vigra_precondition(ptr_ != 0, "python_ptr::operator*(): Cannot dereference NULL pointer.");
147  return *ptr_;
148  }
149 
150  pointer operator-> () const
151  {
152  vigra_precondition(ptr_ != 0, "python_ptr::operator->(): Cannot dereference NULL pointer.");
153  return ptr_;
154  }
155 
156  pointer ptr() const
157  {
158  return ptr_;
159  }
160 
161  pointer get() const
162  {
163  return ptr_;
164  }
165 
166  operator pointer() const
167  {
168  return ptr_;
169  }
170 
171  bool operator! () const
172  {
173  return ptr_ == 0;
174  }
175 
176  bool unique() const
177  {
178  return ptr_ && ptr_->ob_refcnt == 1;
179  }
180 
181  void swap(python_ptr & other)
182  {
183  std::swap(ptr_, other.ptr_);
184  }
185 
186  bool operator==(python_ptr const & p) const
187  {
188  return ptr_ == p.ptr_;
189  }
190 
191  bool operator==(pointer p) const
192  {
193  return ptr_ == p;
194  }
195 
196  bool operator!=(python_ptr const & p) const
197  {
198  return ptr_ != p.ptr_;
199  }
200 
201  bool operator!=(pointer p) const
202  {
203  return ptr_ != p;
204  }
205 };
206 
207 inline void swap(python_ptr & a, python_ptr & b)
208 {
209  a.swap(b);
210 }
211 
212 /****************************************************************/
213 
214 inline python_ptr
215 makePythonDictionary(char const * k1 = 0, PyObject * a1 = 0,
216  char const * k2 = 0, PyObject * a2 = 0,
217  char const * k3 = 0, PyObject * a3 = 0)
218 {
219  python_ptr dict(PyDict_New(), python_ptr::keep_count);
220  pythonToCppException(dict);
221  if(k1 && a1)
222  PyDict_SetItemString(dict, k1, a1);
223  if(k2 && a2)
224  PyDict_SetItemString(dict, k2, a2);
225  if(k3 && a3)
226  PyDict_SetItemString(dict, k3, a3);
227  return dict;
228 }
229 
230 /****************************************************************/
231 
232 inline python_ptr pythonFromData(bool t)
233 {
234  python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count);
235  pythonToCppException(res);
236  return res;
237 }
238 
239 inline python_ptr pythonFromData(std::string const & s)
240 {
241  python_ptr res(PyString_FromString(s.c_str()), python_ptr::keep_count);
242  pythonToCppException(res);
243  return res;
244 }
245 
246 inline python_ptr pythonFromData(long long t)
247 {
248  python_ptr res;
249  if(t > (long long)NumericTraits<long>::max() || t < (long long)NumericTraits<long>::min())
250  res = python_ptr(PyLong_FromLongLong(t), python_ptr::keep_count);
251  else
252  res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count);
253  pythonToCppException(res);
254  return res;
255 }
256 
257 inline python_ptr pythonFromData(unsigned long long t)
258 {
259  python_ptr res;
260  if(t > (unsigned long long)NumericTraits<long>::max())
261  res = python_ptr(PyLong_FromUnsignedLongLong(t), python_ptr::keep_count);
262  else
263  res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count);
264  pythonToCppException(res);
265  return res;
266 }
267 
268 #define VIGRA_PYTHON_FROM_DATA(type, fct, cast_type) \
269 inline python_ptr pythonFromData(type t) \
270 { \
271  python_ptr res(fct((cast_type)t), python_ptr::keep_count); \
272  pythonToCppException(res); \
273  return res; \
274 }
275 
276 VIGRA_PYTHON_FROM_DATA(signed char, PyInt_FromLong, long)
277 VIGRA_PYTHON_FROM_DATA(unsigned char, PyInt_FromLong, long)
278 VIGRA_PYTHON_FROM_DATA(short, PyInt_FromLong, long)
279 VIGRA_PYTHON_FROM_DATA(unsigned short, PyInt_FromLong, long)
280 VIGRA_PYTHON_FROM_DATA(long, PyInt_FromLong, long)
281 VIGRA_PYTHON_FROM_DATA(unsigned long, PyInt_FromSize_t, size_t)
282 VIGRA_PYTHON_FROM_DATA(int, PyInt_FromSsize_t, Py_ssize_t)
283 VIGRA_PYTHON_FROM_DATA(unsigned int, PyInt_FromSize_t, size_t)
284 VIGRA_PYTHON_FROM_DATA(float, PyFloat_FromDouble, double)
285 VIGRA_PYTHON_FROM_DATA(double, PyFloat_FromDouble, double)
286 VIGRA_PYTHON_FROM_DATA(char const *, PyString_FromString, char const *)
287 
288 #undef VIGRA_PYTHON_FROM_DATA
289 
290 /****************************************************************/
291 
292 #define VIGRA_DATA_FROM_PYTHON(type, check, extract) \
293 inline type dataFromPython(PyObject * data, type const & defaultVal) \
294 { \
295  return data && check(data) \
296  ? (type)extract(data) \
297  : defaultVal; \
298 }
299 
300 VIGRA_DATA_FROM_PYTHON(signed char, PyInt_Check, PyInt_AsLong)
301 VIGRA_DATA_FROM_PYTHON(unsigned char, PyInt_Check, PyInt_AsLong)
302 VIGRA_DATA_FROM_PYTHON(short, PyInt_Check, PyInt_AsLong)
303 VIGRA_DATA_FROM_PYTHON(unsigned short, PyInt_Check, PyInt_AsLong)
304 VIGRA_DATA_FROM_PYTHON(long, PyInt_Check, PyInt_AsLong)
305 VIGRA_DATA_FROM_PYTHON(unsigned long, PyInt_Check, PyInt_AsUnsignedLongMask)
306 VIGRA_DATA_FROM_PYTHON(int, PyInt_Check, PyInt_AsLong)
307 VIGRA_DATA_FROM_PYTHON(unsigned int, PyInt_Check, PyInt_AsUnsignedLongMask)
308 VIGRA_DATA_FROM_PYTHON(long long, PyInt_Check, PyInt_AsSsize_t)
309 VIGRA_DATA_FROM_PYTHON(unsigned long long, PyInt_Check, PyInt_AsUnsignedLongLongMask)
310 VIGRA_DATA_FROM_PYTHON(float, PyFloat_Check, PyFloat_AsDouble)
311 VIGRA_DATA_FROM_PYTHON(double, PyFloat_Check, PyFloat_AsDouble)
312 
313 inline std::string dataFromPython(PyObject * data, const char * defaultVal)
314 {
315  return data && PyString_Check(data)
316  ? std::string(PyString_AsString(data))
317  : std::string(defaultVal);
318 }
319 
320 inline std::string dataFromPython(PyObject * data, std::string const & defaultVal)
321 {
322  return data && PyString_Check(data)
323  ? std::string(PyString_AsString(data))
324  : defaultVal;
325 }
326 
327 inline python_ptr dataFromPython(PyObject * data, python_ptr defaultVal)
328 {
329  return data
330  ? python_ptr(data)
331  : defaultVal;
332 }
333 
334 #undef VIGRA_DATA_FROM_PYTHON
335 
336 /****************************************************************/
337 
338 template <class T>
339 T pythonGetAttr(PyObject * obj, const char * key, T defaultValue)
340 {
341  if(!obj)
342  return defaultValue;
343 
344  python_ptr k(PyString_FromString(key), python_ptr::keep_count);
345  pythonToCppException(k);
346  python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count);
347  if(!pres)
348  PyErr_Clear();
349  return dataFromPython(pres, defaultValue);
350 }
351 
352 inline std::string
353 pythonGetAttr(PyObject * obj, const char * key, const char * defaultValue)
354 {
355  if(!obj)
356  return std::string(defaultValue);
357 
358  python_ptr k(PyString_FromString(key), python_ptr::keep_count);
359  pythonToCppException(k);
360  python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count);
361  if(!pres)
362  PyErr_Clear();
363  return dataFromPython(pres, defaultValue);
364 }
365 
366 /****************************************************************/
367 
368 template <class T, int N>
369 python_ptr shapeToPythonTuple(TinyVector<T, N> const & shape)
370 {
371  python_ptr tuple(PyTuple_New(N), python_ptr::keep_count);
372  pythonToCppException(tuple);
373  for(unsigned int k=0; k<N; ++k)
374  {
375  PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release());
376  }
377  return tuple;
378 }
379 
380 template <class T>
381 python_ptr shapeToPythonTuple(ArrayVectorView<T> const & shape)
382 {
383  python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count);
384  pythonToCppException(tuple);
385  for(unsigned int k=0; k<shape.size(); ++k)
386  {
387  PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release());
388  }
389  return tuple;
390 }
391 
392 /****************************************************************/
393 
394 class PyAllowThreads
395 {
396  PyThreadState * save_;
397 
398  // make it non-copyable
399  PyAllowThreads(PyAllowThreads const &);
400  PyAllowThreads & operator=(PyAllowThreads const &);
401 
402  public:
403  PyAllowThreads()
404  : save_(PyEval_SaveThread())
405  {}
406 
407  ~PyAllowThreads()
408  {
409  PyEval_RestoreThread(save_);
410  }
411 };
412 
413 } // namespace vigra
414 
415 #endif // VIGRA_PYTHON_UTILITY_HXX
NumericTraits< T >::Promote trace(MultiArrayView< 2, T, C > const &m)
Definition: matrix.hxx:799
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.10.0 (Fri Feb 21 2014)