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

vigra/python_utility.hxx VIGRA

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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.8.0 (20 Sep 2011)