[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/python_utility.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2009 by Ullrich Koethe and Hans Meine */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_PYTHON_UTILITY_HXX 00037 #define VIGRA_PYTHON_UTILITY_HXX 00038 00039 #include <Python.h> 00040 #include <algorithm> 00041 #include <string> 00042 #include "vigra/error.hxx" 00043 #include "vigra/tinyvector.hxx" 00044 00045 namespace vigra { 00046 00047 template <class PYOBJECT_PTR> 00048 void pythonToCppException(PYOBJECT_PTR obj) 00049 { 00050 if(obj != 0) 00051 return; 00052 PyObject * type, * value, * trace; 00053 PyErr_Fetch(&type, &value, &trace); 00054 if(type == 0) 00055 return; 00056 std::string message(((PyTypeObject *)type)->tp_name); 00057 if(PyString_Check(value)) 00058 { 00059 message += std::string(": ") + PyString_AS_STRING(value); 00060 } 00061 00062 Py_XDECREF(type); 00063 Py_XDECREF(value); 00064 Py_XDECREF(trace); 00065 throw std::runtime_error(message.c_str()); 00066 } 00067 00068 /********************************************************/ 00069 /* */ 00070 /* python_ptr */ 00071 /* */ 00072 /********************************************************/ 00073 00074 class python_ptr 00075 { 00076 private: 00077 PyObject * ptr_; 00078 00079 public: 00080 00081 typedef PyObject element_type; 00082 typedef PyObject value_type; 00083 typedef PyObject * pointer; 00084 typedef PyObject & reference; 00085 00086 enum refcount_policy { increment_count, borrowed_reference = increment_count, 00087 keep_count, new_reference = keep_count }; 00088 00089 explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count) 00090 : ptr_( p ) 00091 { 00092 if(rp == increment_count) 00093 { 00094 Py_XINCREF(ptr_); 00095 } 00096 } 00097 00098 python_ptr(python_ptr const & p) 00099 : ptr_(p.ptr_) 00100 { 00101 Py_XINCREF(ptr_); 00102 } 00103 00104 python_ptr & operator=(pointer p) 00105 { 00106 reset(p); 00107 return *this; 00108 } 00109 00110 python_ptr & operator=(python_ptr const & r) 00111 { 00112 reset(r.ptr_); 00113 return *this; 00114 } 00115 00116 ~python_ptr() 00117 { 00118 reset(); 00119 } 00120 00121 void reset(pointer p = 0, refcount_policy rp = increment_count) 00122 { 00123 if(p == ptr_) 00124 return; 00125 if(rp == increment_count) 00126 { 00127 Py_XINCREF(p); 00128 } 00129 Py_XDECREF(ptr_); 00130 ptr_ = p; 00131 } 00132 00133 pointer release(bool return_borrowed_reference = false) 00134 { 00135 pointer p = ptr_; 00136 ptr_ = 0; 00137 if(return_borrowed_reference) 00138 { 00139 Py_XDECREF(p); 00140 } 00141 return p; 00142 } 00143 00144 reference operator* () const 00145 { 00146 vigra_precondition(ptr_ != 0, "python_ptr::operator*(): Cannot dereference NULL pointer."); 00147 return *ptr_; 00148 } 00149 00150 pointer operator-> () const 00151 { 00152 vigra_precondition(ptr_ != 0, "python_ptr::operator->(): Cannot dereference NULL pointer."); 00153 return ptr_; 00154 } 00155 00156 pointer ptr() const 00157 { 00158 return ptr_; 00159 } 00160 00161 pointer get() const 00162 { 00163 return ptr_; 00164 } 00165 00166 operator pointer() const 00167 { 00168 return ptr_; 00169 } 00170 00171 bool operator! () const 00172 { 00173 return ptr_ == 0; 00174 } 00175 00176 bool unique() const 00177 { 00178 return ptr_ && ptr_->ob_refcnt == 1; 00179 } 00180 00181 void swap(python_ptr & other) 00182 { 00183 std::swap(ptr_, other.ptr_); 00184 } 00185 00186 bool operator==(python_ptr const & p) const 00187 { 00188 return ptr_ == p.ptr_; 00189 } 00190 00191 bool operator==(pointer p) const 00192 { 00193 return ptr_ == p; 00194 } 00195 00196 bool operator!=(python_ptr const & p) const 00197 { 00198 return ptr_ != p.ptr_; 00199 } 00200 00201 bool operator!=(pointer p) const 00202 { 00203 return ptr_ != p; 00204 } 00205 }; 00206 00207 inline void swap(python_ptr & a, python_ptr & b) 00208 { 00209 a.swap(b); 00210 } 00211 00212 /****************************************************************/ 00213 00214 inline python_ptr 00215 makePythonDictionary(char const * k1 = 0, PyObject * a1 = 0, 00216 char const * k2 = 0, PyObject * a2 = 0, 00217 char const * k3 = 0, PyObject * a3 = 0) 00218 { 00219 python_ptr dict(PyDict_New(), python_ptr::keep_count); 00220 pythonToCppException(dict); 00221 if(k1 && a1) 00222 PyDict_SetItemString(dict, k1, a1); 00223 if(k2 && a2) 00224 PyDict_SetItemString(dict, k2, a2); 00225 if(k3 && a3) 00226 PyDict_SetItemString(dict, k3, a3); 00227 return dict; 00228 } 00229 00230 /****************************************************************/ 00231 00232 inline python_ptr pythonFromData(bool t) 00233 { 00234 python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count); 00235 pythonToCppException(res); 00236 return res; 00237 } 00238 00239 inline python_ptr pythonFromData(std::string const & s) 00240 { 00241 python_ptr res(PyString_FromString(s.c_str()), python_ptr::keep_count); 00242 pythonToCppException(res); 00243 return res; 00244 } 00245 00246 inline python_ptr pythonFromData(long long t) 00247 { 00248 python_ptr res; 00249 if(t > (long long)NumericTraits<long>::max() || t < (long long)NumericTraits<long>::min()) 00250 res = python_ptr(PyLong_FromLongLong(t), python_ptr::keep_count); 00251 else 00252 res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count); 00253 pythonToCppException(res); 00254 return res; 00255 } 00256 00257 inline python_ptr pythonFromData(unsigned long long t) 00258 { 00259 python_ptr res; 00260 if(t > (unsigned long long)NumericTraits<long>::max()) 00261 res = python_ptr(PyLong_FromUnsignedLongLong(t), python_ptr::keep_count); 00262 else 00263 res = python_ptr(PyInt_FromLong((long)t), python_ptr::keep_count); 00264 pythonToCppException(res); 00265 return res; 00266 } 00267 00268 #define VIGRA_PYTHON_FROM_DATA(type, fct, cast_type) \ 00269 inline python_ptr pythonFromData(type t) \ 00270 { \ 00271 python_ptr res(fct((cast_type)t), python_ptr::keep_count); \ 00272 pythonToCppException(res); \ 00273 return res; \ 00274 } 00275 00276 VIGRA_PYTHON_FROM_DATA(signed char, PyInt_FromLong, long) 00277 VIGRA_PYTHON_FROM_DATA(unsigned char, PyInt_FromLong, long) 00278 VIGRA_PYTHON_FROM_DATA(short, PyInt_FromLong, long) 00279 VIGRA_PYTHON_FROM_DATA(unsigned short, PyInt_FromLong, long) 00280 VIGRA_PYTHON_FROM_DATA(long, PyInt_FromLong, long) 00281 VIGRA_PYTHON_FROM_DATA(unsigned long, PyInt_FromSize_t, size_t) 00282 VIGRA_PYTHON_FROM_DATA(int, PyInt_FromSsize_t, Py_ssize_t) 00283 VIGRA_PYTHON_FROM_DATA(unsigned int, PyInt_FromSize_t, size_t) 00284 VIGRA_PYTHON_FROM_DATA(float, PyFloat_FromDouble, double) 00285 VIGRA_PYTHON_FROM_DATA(double, PyFloat_FromDouble, double) 00286 VIGRA_PYTHON_FROM_DATA(char const *, PyString_FromString, char const *) 00287 00288 #undef VIGRA_PYTHON_FROM_DATA 00289 00290 /****************************************************************/ 00291 00292 #define VIGRA_DATA_FROM_PYTHON(type, check, extract) \ 00293 inline type dataFromPython(PyObject * data, type const & defaultVal) \ 00294 { \ 00295 return data && check(data) \ 00296 ? (type)extract(data) \ 00297 : defaultVal; \ 00298 } 00299 00300 VIGRA_DATA_FROM_PYTHON(signed char, PyInt_Check, PyInt_AsLong) 00301 VIGRA_DATA_FROM_PYTHON(unsigned char, PyInt_Check, PyInt_AsLong) 00302 VIGRA_DATA_FROM_PYTHON(short, PyInt_Check, PyInt_AsLong) 00303 VIGRA_DATA_FROM_PYTHON(unsigned short, PyInt_Check, PyInt_AsLong) 00304 VIGRA_DATA_FROM_PYTHON(long, PyInt_Check, PyInt_AsLong) 00305 VIGRA_DATA_FROM_PYTHON(unsigned long, PyInt_Check, PyInt_AsUnsignedLongMask) 00306 VIGRA_DATA_FROM_PYTHON(int, PyInt_Check, PyInt_AsLong) 00307 VIGRA_DATA_FROM_PYTHON(unsigned int, PyInt_Check, PyInt_AsUnsignedLongMask) 00308 VIGRA_DATA_FROM_PYTHON(long long, PyInt_Check, PyInt_AsSsize_t) 00309 VIGRA_DATA_FROM_PYTHON(unsigned long long, PyInt_Check, PyInt_AsUnsignedLongLongMask) 00310 VIGRA_DATA_FROM_PYTHON(float, PyFloat_Check, PyFloat_AsDouble) 00311 VIGRA_DATA_FROM_PYTHON(double, PyFloat_Check, PyFloat_AsDouble) 00312 00313 inline std::string dataFromPython(PyObject * data, const char * defaultVal) 00314 { 00315 return data && PyString_Check(data) 00316 ? std::string(PyString_AsString(data)) 00317 : std::string(defaultVal); 00318 } 00319 00320 inline std::string dataFromPython(PyObject * data, std::string const & defaultVal) 00321 { 00322 return data && PyString_Check(data) 00323 ? std::string(PyString_AsString(data)) 00324 : defaultVal; 00325 } 00326 00327 inline python_ptr dataFromPython(PyObject * data, python_ptr defaultVal) 00328 { 00329 return data 00330 ? python_ptr(data) 00331 : defaultVal; 00332 } 00333 00334 #undef VIGRA_DATA_FROM_PYTHON 00335 00336 /****************************************************************/ 00337 00338 template <class T> 00339 T pythonGetAttr(PyObject * obj, const char * key, T defaultValue) 00340 { 00341 if(!obj) 00342 return defaultValue; 00343 00344 python_ptr k(PyString_FromString(key), python_ptr::keep_count); 00345 pythonToCppException(k); 00346 python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count); 00347 if(!pres) 00348 PyErr_Clear(); 00349 return dataFromPython(pres, defaultValue); 00350 } 00351 00352 inline std::string 00353 pythonGetAttr(PyObject * obj, const char * key, const char * defaultValue) 00354 { 00355 if(!obj) 00356 return std::string(defaultValue); 00357 00358 python_ptr k(PyString_FromString(key), python_ptr::keep_count); 00359 pythonToCppException(k); 00360 python_ptr pres(PyObject_GetAttr(obj, k), python_ptr::keep_count); 00361 if(!pres) 00362 PyErr_Clear(); 00363 return dataFromPython(pres, defaultValue); 00364 } 00365 00366 /****************************************************************/ 00367 00368 template <class T, int N> 00369 python_ptr shapeToPythonTuple(TinyVector<T, N> const & shape) 00370 { 00371 python_ptr tuple(PyTuple_New(N), python_ptr::keep_count); 00372 pythonToCppException(tuple); 00373 for(unsigned int k=0; k<N; ++k) 00374 { 00375 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release()); 00376 } 00377 return tuple; 00378 } 00379 00380 template <class T> 00381 python_ptr shapeToPythonTuple(ArrayVectorView<T> const & shape) 00382 { 00383 python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count); 00384 pythonToCppException(tuple); 00385 for(unsigned int k=0; k<shape.size(); ++k) 00386 { 00387 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromData(shape[k]).release()); 00388 } 00389 return tuple; 00390 } 00391 00392 /****************************************************************/ 00393 00394 class PyAllowThreads 00395 { 00396 PyThreadState * save_; 00397 00398 // make it non-copyable 00399 PyAllowThreads(PyAllowThreads const &); 00400 PyAllowThreads & operator=(PyAllowThreads const &); 00401 00402 public: 00403 PyAllowThreads() 00404 : save_(PyEval_SaveThread()) 00405 {} 00406 00407 ~PyAllowThreads() 00408 { 00409 PyEval_RestoreThread(save_); 00410 } 00411 }; 00412 00413 } // namespace vigra 00414 00415 #endif // VIGRA_PYTHON_UTILITY_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|