[ 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) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)