Python2/cxx_extensions.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 // Copyright (c) 1998 - 2007, The Regents of the University of California
00004 // Produced at the Lawrence Livermore National Laboratory
00005 // All rights reserved.
00006 //
00007 // This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
00008 // full copyright notice is contained in the file COPYRIGHT located at the root
00009 // of the PyCXX distribution.
00010 //
00011 // Redistribution  and  use  in  source  and  binary  forms,  with  or  without
00012 // modification, are permitted provided that the following conditions are met:
00013 //
00014 //  - Redistributions of  source code must  retain the above  copyright notice,
00015 //    this list of conditions and the disclaimer below.
00016 //  - Redistributions in binary form must reproduce the above copyright notice,
00017 //    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
00018 //    documentation and/or materials provided with the distribution.
00019 //  - Neither the name of the UC/LLNL nor  the names of its contributors may be
00020 //    used to  endorse or  promote products derived from  this software without
00021 //    specific prior written permission.
00022 //
00023 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
00024 // AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
00025 // IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
00026 // ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
00027 // CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
00028 // ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
00029 // DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
00030 // SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
00031 // CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
00032 // LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
00033 // OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00034 // DAMAGE.
00035 //
00036 //-----------------------------------------------------------------------------
00037 #include "CXX/Extensions.hxx"
00038 #include "CXX/Exception.hxx"
00039 #include <assert.h>
00040 
00041 #ifdef PYCXX_DEBUG
00042 //
00043 //  Functions useful when debugging PyCXX
00044 //
00045 void bpt( void )
00046 {
00047 }
00048 
00049 void printRefCount( PyObject *obj )
00050 {
00051     std::cout << "RefCount of 0x" << std::hex << reinterpret_cast< unsigned int >( obj ) << std::dec << " is " << Py_REFCNT( obj ) << std::endl;
00052 }
00053 #endif
00054 
00055 namespace Py
00056 {
00057 #ifdef PYCXX_PYTHON_2TO3
00058 std::string String::as_std_string( const char *encoding, const char *error ) const
00059 {
00060     if( isUnicode() )
00061     {
00062         Bytes encoded( encode( encoding, error ) );
00063         return encoded.as_std_string();
00064     }
00065     else
00066     {
00067         return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
00068     }
00069 }
00070 
00071 Bytes String::encode( const char *encoding, const char *error ) const
00072 {
00073     if( isUnicode() )
00074     {
00075         return Bytes( PyUnicode_AsEncodedString( ptr(), encoding, error ) );
00076     }
00077     else
00078     {
00079         return Bytes( PyString_AsEncodedObject( ptr(), encoding, error ) );
00080     }
00081 }
00082 
00083 #else
00084 std::string String::as_std_string( const char *encoding, const char *error ) const
00085 {
00086     if( isUnicode() )
00087     {
00088         String encoded( encode( encoding, error ) );
00089         return encoded.as_std_string();
00090     }
00091     else
00092     {
00093         return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
00094     }
00095 }
00096 #endif
00097 
00098 void Object::validate()
00099 {
00100     // release pointer if not the right type
00101     if( !accepts( p ) )
00102     {
00103 #if defined( _CPPRTTI ) || defined( __GNUG__ )
00104         std::string s( "PyCXX: Error creating object of type " );
00105         s += (typeid( *this )).name();
00106 
00107         if( p != NULL )
00108         {
00109             String from_repr = repr();
00110             s += " from ";
00111             s += from_repr.as_std_string( "utf-8" );
00112         }
00113         else
00114         {
00115             s += " from (nil)";
00116         }
00117 #endif
00118         release();
00119         if( PyErr_Occurred() )
00120         { // Error message already set
00121             throw Exception();
00122         }
00123         // Better error message if RTTI available
00124 #if defined( _CPPRTTI ) || defined( __GNUG__ )
00125         throw TypeError( s );
00126 #else
00127         throw TypeError( "PyCXX: type error." );
00128 #endif
00129     }
00130 }
00131 
00132 //================================================================================
00133 //
00134 //    Implementation of MethodTable
00135 //
00136 //================================================================================
00137 PyMethodDef MethodTable::method( const char *method_name, PyCFunction f, int flags, const char *doc )
00138 {
00139     PyMethodDef m;
00140     m.ml_name = const_cast<char*>( method_name );
00141     m.ml_meth = f;
00142     m.ml_flags = flags;
00143     m.ml_doc = const_cast<char*>( doc );
00144     return m;
00145 }
00146 
00147 MethodTable::MethodTable()
00148 {
00149     t.push_back( method( 0, 0, 0, 0 ) );
00150     mt = NULL;
00151 }
00152 
00153 MethodTable::~MethodTable()
00154 {
00155     delete [] mt;
00156 }
00157 
00158 void MethodTable::add( const char *method_name, PyCFunction f, const char *doc, int flag )
00159 {
00160     if( !mt )
00161     {
00162         t.insert( t.end()-1, method( method_name, f, flag, doc ) );
00163     }
00164     else
00165     {
00166         throw RuntimeError( "Too late to add a module method!" );
00167     }
00168 }
00169 
00170 PyMethodDef *MethodTable::table()
00171 {
00172     if( !mt )
00173     {
00174         Py_ssize_t t1size = t.size();
00175         mt = new PyMethodDef[ t1size ];
00176         int j = 0;
00177         for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
00178         {
00179             mt[ j++ ] = *i;
00180         }
00181     }
00182     return mt;
00183 }
00184 
00185 //================================================================================
00186 //
00187 //    Implementation of ExtensionModule
00188 //
00189 //================================================================================
00190 ExtensionModuleBase::ExtensionModuleBase( const char *name )
00191 : m_module_name( name )
00192 , m_full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : m_module_name )
00193 , m_method_table()
00194 {}
00195 
00196 ExtensionModuleBase::~ExtensionModuleBase()
00197 {}
00198 
00199 const std::string &ExtensionModuleBase::name() const
00200 {
00201     return m_module_name;
00202 }
00203 
00204 const std::string &ExtensionModuleBase::fullName() const
00205 {
00206     return m_full_module_name;
00207 }
00208 
00209 class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
00210 {
00211 public:
00212     ExtensionModuleBasePtr( ExtensionModuleBase *_module )
00213     : module( _module )
00214     {}
00215 
00216     virtual ~ExtensionModuleBasePtr()
00217     {}
00218 
00219     ExtensionModuleBase *module;
00220 };
00221 
00222 void ExtensionModuleBase::initialize( const char *module_doc )
00223 {
00224     PyObject *module_ptr = new ExtensionModuleBasePtr( this );
00225     Py_InitModule4
00226     (
00227     const_cast<char *>( m_module_name.c_str() ),    // name
00228     m_method_table.table(),                         // methods
00229     const_cast<char *>( module_doc ),               // docs
00230     module_ptr,                                     // pass to functions as "self"
00231     PYTHON_API_VERSION                              // API version
00232     );
00233 }
00234 
00235 Py::Module ExtensionModuleBase::module( void ) const
00236 {
00237     return Module( m_full_module_name );
00238 }
00239 
00240 Py::Dict ExtensionModuleBase::moduleDictionary( void ) const
00241 {
00242     return module().getDict();
00243 }
00244 
00245 //================================================================================
00246 //
00247 //    Implementation of PythonType
00248 //
00249 //================================================================================
00250 extern "C"
00251 {
00252     static void standard_dealloc( PyObject *p );
00253     //
00254     // All the following functions redirect the call from Python
00255     // onto the matching virtual function in PythonExtensionBase
00256     //
00257     static int print_handler( PyObject *, FILE *, int );
00258     static PyObject *getattr_handler( PyObject *, char * );
00259     static int setattr_handler( PyObject *, char *, PyObject * );
00260     static PyObject *getattro_handler( PyObject *, PyObject * );
00261     static int setattro_handler( PyObject *, PyObject *, PyObject * );
00262     static int compare_handler( PyObject *, PyObject * );
00263     static PyObject *rich_compare_handler( PyObject *, PyObject *, int );
00264     static PyObject *repr_handler( PyObject * );
00265     static PyObject *str_handler( PyObject * );
00266     static long hash_handler( PyObject * );
00267     static PyObject *call_handler( PyObject *, PyObject *, PyObject * );
00268     static PyObject *iter_handler( PyObject * );
00269     static PyObject *iternext_handler( PyObject * );
00270 
00271     // Sequence methods
00272     static Py_ssize_t sequence_length_handler( PyObject * );
00273     static PyObject *sequence_concat_handler( PyObject *,PyObject * );
00274     static PyObject *sequence_repeat_handler( PyObject *, Py_ssize_t );
00275     static PyObject *sequence_item_handler( PyObject *, Py_ssize_t );
00276     static PyObject *sequence_slice_handler( PyObject *, Py_ssize_t, Py_ssize_t );
00277     static int sequence_ass_item_handler( PyObject *, Py_ssize_t, PyObject * );
00278     static int sequence_ass_slice_handler( PyObject *, Py_ssize_t, Py_ssize_t, PyObject * );
00279 
00280     // Mapping
00281     static Py_ssize_t mapping_length_handler( PyObject * );
00282     static PyObject *mapping_subscript_handler( PyObject *, PyObject * );
00283     static int mapping_ass_subscript_handler( PyObject *, PyObject *, PyObject * );
00284 
00285     // Numeric methods
00286     static int number_nonzero_handler( PyObject * );
00287     static PyObject *number_negative_handler( PyObject * );
00288     static PyObject *number_positive_handler( PyObject * );
00289     static PyObject *number_absolute_handler( PyObject * );
00290     static PyObject *number_invert_handler( PyObject * );
00291     static PyObject *number_int_handler( PyObject * );
00292     static PyObject *number_float_handler( PyObject * );
00293 #if !defined( PY3 )
00294     static PyObject *number_long_handler( PyObject * );
00295 #endif
00296     static PyObject *number_oct_handler( PyObject * );
00297     static PyObject *number_hex_handler( PyObject * );
00298     static PyObject *number_add_handler( PyObject *, PyObject * );
00299     static PyObject *number_subtract_handler( PyObject *, PyObject * );
00300     static PyObject *number_multiply_handler( PyObject *, PyObject * );
00301     static PyObject *number_divide_handler( PyObject *, PyObject * );
00302     static PyObject *number_remainder_handler( PyObject *, PyObject * );
00303     static PyObject *number_divmod_handler( PyObject *, PyObject * );
00304     static PyObject *number_lshift_handler( PyObject *, PyObject * );
00305     static PyObject *number_rshift_handler( PyObject *, PyObject * );
00306     static PyObject *number_and_handler( PyObject *, PyObject * );
00307     static PyObject *number_xor_handler( PyObject *, PyObject * );
00308     static PyObject *number_or_handler( PyObject *, PyObject * );
00309     static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * );
00310 
00311     // Buffer
00312     static Py_ssize_t buffer_getreadbuffer_handler( PyObject *, Py_ssize_t, void ** );
00313     static Py_ssize_t buffer_getwritebuffer_handler( PyObject *, Py_ssize_t, void ** );
00314     static Py_ssize_t buffer_getsegcount_handler( PyObject *, Py_ssize_t * );
00315 }
00316 
00317 extern "C" void standard_dealloc( PyObject *p )
00318 {
00319     PyMem_DEL( p );
00320 }
00321 
00322 bool PythonType::readyType()
00323 {
00324     return PyType_Ready( table ) >= 0;
00325 }
00326 
00327 PythonType &PythonType::supportSequenceType()
00328 {
00329     if( !sequence_table )
00330     {
00331         sequence_table = new PySequenceMethods;
00332         memset( sequence_table, 0, sizeof( PySequenceMethods ) );   // ensure new fields are 0
00333         table->tp_as_sequence = sequence_table;
00334         sequence_table->sq_length = sequence_length_handler;
00335         sequence_table->sq_concat = sequence_concat_handler;
00336         sequence_table->sq_repeat = sequence_repeat_handler;
00337         sequence_table->sq_item = sequence_item_handler;
00338 #if !defined( PY3 )
00339         sequence_table->sq_slice = sequence_slice_handler;
00340 #endif
00341         sequence_table->sq_ass_item = sequence_ass_item_handler;    // BAS setup seperately?
00342 #if !defined( PY3 )
00343         sequence_table->sq_ass_slice = sequence_ass_slice_handler;  // BAS setup seperately?
00344 #endif
00345     }
00346     return *this;
00347 }
00348 
00349 PythonType &PythonType::supportMappingType()
00350 {
00351     if( !mapping_table )
00352     {
00353         mapping_table = new PyMappingMethods;
00354         memset( mapping_table, 0, sizeof( PyMappingMethods ) );   // ensure new fields are 0
00355         table->tp_as_mapping = mapping_table;
00356         mapping_table->mp_length = mapping_length_handler;
00357         mapping_table->mp_subscript = mapping_subscript_handler;
00358         mapping_table->mp_ass_subscript = mapping_ass_subscript_handler;    // BAS setup seperately?
00359     }
00360     return *this;
00361 }
00362 
00363 PythonType &PythonType::supportNumberType()
00364 {
00365     if( !number_table )
00366     {
00367         number_table = new PyNumberMethods;
00368         memset( number_table, 0, sizeof( PyNumberMethods ) );   // ensure new fields are 0
00369         table->tp_as_number = number_table;
00370         number_table->nb_add = number_add_handler;
00371         number_table->nb_subtract = number_subtract_handler;
00372         number_table->nb_multiply = number_multiply_handler;
00373 #if !defined( PY3 )
00374         number_table->nb_divide = number_divide_handler;
00375 #endif
00376         number_table->nb_remainder = number_remainder_handler;
00377         number_table->nb_divmod = number_divmod_handler;
00378         number_table->nb_power = number_power_handler;
00379         number_table->nb_negative = number_negative_handler;
00380         number_table->nb_positive = number_positive_handler;
00381         number_table->nb_absolute = number_absolute_handler;
00382 #if !defined( PY3 )
00383         number_table->nb_nonzero = number_nonzero_handler;
00384 #endif
00385         number_table->nb_invert = number_invert_handler;
00386         number_table->nb_lshift = number_lshift_handler;
00387         number_table->nb_rshift = number_rshift_handler;
00388         number_table->nb_and = number_and_handler;
00389         number_table->nb_xor = number_xor_handler;
00390         number_table->nb_or = number_or_handler;
00391 #if !defined( PY3 )
00392         number_table->nb_coerce = 0;
00393 #endif
00394         number_table->nb_int = number_int_handler;
00395 #if !defined( PY3 )
00396         number_table->nb_long = number_long_handler;
00397 #endif
00398         number_table->nb_float = number_float_handler;
00399 #if !defined( PY3 )
00400         number_table->nb_oct = number_oct_handler;
00401         number_table->nb_hex = number_hex_handler;
00402 #endif
00403     }
00404     return *this;
00405 }
00406 
00407 PythonType &PythonType::supportBufferType()
00408 {
00409     if( !buffer_table )
00410     {
00411         buffer_table = new PyBufferProcs;
00412         memset( buffer_table, 0, sizeof( PyBufferProcs ) );   // ensure new fields are 0
00413         table->tp_as_buffer = buffer_table;
00414 #if !defined( PY3 )
00415         buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
00416         buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
00417         buffer_table->bf_getsegcount = buffer_getsegcount_handler;
00418 #endif
00419     }
00420     return *this;
00421 }
00422 
00423 // if you define one sequence method you must define
00424 // all of them except the assigns
00425 
00426 PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
00427 : table( new PyTypeObject )
00428 , sequence_table( NULL )
00429 , mapping_table( NULL )
00430 , number_table( NULL )
00431 , buffer_table( NULL )
00432 {
00433     // PyTypeObject is defined in <python-sources>/Include/object.h
00434 
00435     memset( table, 0, sizeof( PyTypeObject ) );   // ensure new fields are 0
00436     *reinterpret_cast<PyObject *>( table ) = py_object_initializer;
00437 #if !defined( PY3 )
00438     table->ob_type = _Type_Type();
00439     table->ob_size = 0;
00440 #endif
00441     table->tp_name = const_cast<char *>( default_name );
00442     table->tp_basicsize = basic_size;
00443     table->tp_itemsize = itemsize;
00444 
00445     // Methods to implement standard operations
00446     table->tp_dealloc = (destructor)standard_dealloc;
00447     table->tp_print = 0;
00448     table->tp_getattr = 0;
00449     table->tp_setattr = 0;
00450     table->tp_compare = 0;
00451     table->tp_repr = 0;
00452 
00453     // Method suites for standard classes
00454     table->tp_as_number = 0;
00455     table->tp_as_sequence = 0;
00456     table->tp_as_mapping =  0;
00457 
00458     // More standard operations (here for binary compatibility)
00459     table->tp_hash = 0;
00460     table->tp_call = 0;
00461     table->tp_str = 0;
00462     table->tp_getattro = 0;
00463     table->tp_setattro = 0;
00464 
00465     // Functions to access object as input/output buffer
00466     table->tp_as_buffer = 0;
00467 
00468     // Flags to define presence of optional/expanded features
00469     table->tp_flags = Py_TPFLAGS_DEFAULT;
00470 
00471     // Documentation string
00472     table->tp_doc = 0;
00473 
00474 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
00475     table->tp_traverse = 0L;
00476 
00477     // delete references to contained objects
00478     table->tp_clear = 0L;
00479 #else
00480     table->tp_xxx5 = 0L;
00481     table->tp_xxx6 = 0L;
00482 #endif
00483 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
00484     // first defined in 2.1
00485     table->tp_richcompare = 0L;
00486     // weak reference enabler
00487     table->tp_weaklistoffset = 0L;
00488 #else
00489     table->tp_xxx7 = 0L;
00490     table->tp_xxx8 = 0L;
00491 #endif
00492 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 2)
00493     // first defined in 2.3
00494     // Iterators
00495     table->tp_iter = 0L;
00496     table->tp_iternext = 0L;
00497 #endif
00498 #ifdef COUNT_ALLOCS
00499     table->tp_alloc = 0;
00500     table->tp_free = 0;
00501     table->tp_maxalloc = 0;
00502     table->tp_next = 0;
00503 #endif
00504 }
00505 
00506 PythonType::~PythonType()
00507 {
00508     delete table;
00509     delete sequence_table;
00510     delete mapping_table;
00511     delete number_table;
00512     delete buffer_table;
00513 }
00514 
00515 PyTypeObject *PythonType::type_object() const
00516 {
00517     return table;
00518 }
00519 
00520 PythonType &PythonType::name( const char *nam )
00521 {
00522     table->tp_name = const_cast<char *>( nam );
00523     return *this;
00524 }
00525 
00526 const char *PythonType::getName() const
00527 {
00528     return table->tp_name;
00529 }
00530 
00531 PythonType &PythonType::doc( const char *d )
00532 {
00533     table->tp_doc = const_cast<char *>( d );
00534     return *this;
00535 }
00536 
00537 const char *PythonType::getDoc() const
00538 {
00539     return table->tp_doc;
00540 }
00541 
00542 PythonType &PythonType::set_tp_dealloc( void (*tp_dealloc)( PyObject *self ) )
00543 {
00544     table->tp_dealloc = tp_dealloc;
00545     return *this;
00546 }
00547 
00548 PythonType &PythonType::set_tp_init( int (*tp_init)( PyObject *self, PyObject *args, PyObject *kwds ) )
00549 {
00550     table->tp_init = tp_init;
00551     return *this;
00552 }
00553 
00554 PythonType &PythonType::set_tp_new( PyObject *(*tp_new)( PyTypeObject *subtype, PyObject *args, PyObject *kwds ) )
00555 {
00556     table->tp_new = tp_new;
00557     return *this;
00558 }
00559 
00560 PythonType &PythonType::set_methods( PyMethodDef *methods )
00561 {
00562     table->tp_methods = methods;
00563     return *this;
00564 }
00565 
00566 PythonType &PythonType::supportClass()
00567 {
00568     table->tp_flags |= Py_TPFLAGS_BASETYPE;
00569     return *this;
00570 }
00571 
00572 PythonType &PythonType::dealloc( void( *f )( PyObject * ))
00573 {
00574     table->tp_dealloc = f;
00575     return *this;
00576 }
00577 
00578 PythonType &PythonType::supportPrint()
00579 {
00580     table->tp_print = print_handler;
00581     return *this;
00582 }
00583 
00584 PythonType &PythonType::supportGetattr()
00585 {
00586     table->tp_getattr = getattr_handler;
00587     return *this;
00588 }
00589 
00590 PythonType &PythonType::supportSetattr()
00591 {
00592     table->tp_setattr = setattr_handler;
00593     return *this;
00594 }
00595 
00596 PythonType &PythonType::supportGetattro()
00597 {
00598     table->tp_getattro = getattro_handler;
00599     return *this;
00600 }
00601 
00602 PythonType &PythonType::supportSetattro()
00603 {
00604     table->tp_setattro = setattro_handler;
00605     return *this;
00606 }
00607 
00608 PythonType &PythonType::supportCompare()
00609 {
00610     table->tp_compare = compare_handler;
00611     return *this;
00612 }
00613 
00614 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
00615 PythonType &PythonType::supportRichCompare()
00616 {
00617     table->tp_richcompare = rich_compare_handler;
00618     return *this;
00619 }
00620 #endif
00621 
00622 PythonType &PythonType::supportRepr()
00623 {
00624     table->tp_repr = repr_handler;
00625     return *this;
00626 }
00627 
00628 PythonType &PythonType::supportStr()
00629 {
00630     table->tp_str = str_handler;
00631     return *this;
00632 }
00633 
00634 PythonType &PythonType::supportHash()
00635 {
00636     table->tp_hash = hash_handler;
00637     return *this;
00638 }
00639 
00640 PythonType &PythonType::supportCall()
00641 {
00642     table->tp_call = call_handler;
00643     return *this;
00644 }
00645 
00646 PythonType &PythonType::supportIter()
00647 {
00648     table->tp_iter = iter_handler;
00649     table->tp_iternext = iternext_handler;
00650     return *this;
00651 }
00652 
00653 //--------------------------------------------------------------------------------
00654 //
00655 //    Handlers
00656 //
00657 //--------------------------------------------------------------------------------
00658 PythonExtensionBase *getPythonExtensionBase( PyObject *self )
00659 {
00660     if( self->ob_type->tp_flags&Py_TPFLAGS_BASETYPE )
00661     {
00662         PythonClassInstance *instance = reinterpret_cast<PythonClassInstance *>( self );
00663         return instance->m_pycxx_object;
00664     }
00665     else
00666     {
00667         return static_cast<PythonExtensionBase *>( self );
00668     }
00669 }
00670 
00671 
00672 extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
00673 {
00674     try
00675     {
00676         PythonExtensionBase *p = getPythonExtensionBase( self );
00677         return p->print( fp, flags );
00678     }
00679     catch( Py::Exception &)
00680     {
00681         return -1;    // indicate error
00682     }
00683 }
00684 
00685 extern "C" PyObject *getattr_handler( PyObject *self, char *name )
00686 {
00687     try
00688     {
00689         PythonExtensionBase *p = getPythonExtensionBase( self );
00690         return new_reference_to( p->getattr( name ) );
00691     }
00692     catch( Py::Exception &)
00693     {
00694         return NULL;    // indicate error
00695     }
00696 }
00697 
00698 extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
00699 {
00700     try
00701     {
00702         PythonExtensionBase *p = getPythonExtensionBase( self );
00703         return p->setattr( name, Py::Object( value ) );
00704     }
00705     catch( Py::Exception &)
00706     {
00707         return -1;    // indicate error
00708     }
00709 }
00710 
00711 extern "C" PyObject *getattro_handler( PyObject *self, PyObject *name )
00712 {
00713     try
00714     {
00715         PythonExtensionBase *p = getPythonExtensionBase( self );
00716         return new_reference_to( p->getattro( Py::String( name ) ) );
00717     }
00718     catch( Py::Exception &)
00719     {
00720         return NULL;    // indicate error
00721     }
00722 }
00723 
00724 extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
00725 {
00726     try
00727     {
00728         PythonExtensionBase *p = getPythonExtensionBase( self );
00729         return p->setattro( Py::String( name ), Py::Object( value ) );
00730     }
00731     catch( Py::Exception &)
00732     {
00733         return -1;    // indicate error
00734     }
00735 }
00736 
00737 extern "C" int compare_handler( PyObject *self, PyObject *other )
00738 {
00739     try
00740     {
00741         PythonExtensionBase *p = getPythonExtensionBase( self );
00742         return p->compare( Py::Object( other ) );
00743     }
00744     catch( Py::Exception &)
00745     {
00746         return -1;    // indicate error
00747     }
00748 }
00749 
00750 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
00751 extern "C" PyObject *rich_compare_handler( PyObject *self, PyObject *other, int op )
00752 {
00753     try
00754     {
00755         PythonExtensionBase *p = getPythonExtensionBase( self );
00756         return new_reference_to( p->rich_compare( Py::Object( other ), op ) );
00757     }
00758     catch( Py::Exception &)
00759     {
00760         return NULL;    // indicate error
00761     }
00762 }
00763 #endif
00764 
00765 extern "C" PyObject *repr_handler( PyObject *self )
00766 {
00767     try
00768     {
00769         PythonExtensionBase *p = getPythonExtensionBase( self );
00770         return new_reference_to( p->repr() );
00771     }
00772     catch( Py::Exception &)
00773     {
00774         return NULL;    // indicate error
00775     }
00776 }
00777 
00778 extern "C" PyObject *str_handler( PyObject *self )
00779 {
00780     try
00781     {
00782         PythonExtensionBase *p = getPythonExtensionBase( self );
00783         return new_reference_to( p->str() );
00784     }
00785     catch( Py::Exception &)
00786     {
00787         return NULL;    // indicate error
00788     }
00789 }
00790 
00791 extern "C" long hash_handler( PyObject *self )
00792 {
00793     try
00794     {
00795         PythonExtensionBase *p = getPythonExtensionBase( self );
00796         return p->hash();
00797     }
00798     catch( Py::Exception &)
00799     {
00800         return -1;    // indicate error
00801     }
00802 }
00803 
00804 extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
00805 {
00806     try
00807     {
00808         PythonExtensionBase *p = getPythonExtensionBase( self );
00809         if( kw != NULL )
00810             return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
00811         else
00812             return new_reference_to( p->call( Py::Object( args ), Py::Object() ) );
00813     }
00814     catch( Py::Exception &)
00815     {
00816         return NULL;    // indicate error
00817     }
00818 }
00819 
00820 extern "C" PyObject *iter_handler( PyObject *self )
00821 {
00822     try
00823     {
00824         PythonExtensionBase *p = getPythonExtensionBase( self );
00825         return new_reference_to( p->iter() );
00826     }
00827     catch( Py::Exception &)
00828     {
00829         return NULL;    // indicate error
00830     }
00831 }
00832 
00833 extern "C" PyObject *iternext_handler( PyObject *self )
00834 {
00835     try
00836     {
00837         PythonExtensionBase *p = getPythonExtensionBase( self );
00838         return p->iternext();  // might be a NULL ptr on end of iteration
00839     }
00840     catch( Py::Exception &)
00841     {
00842         return NULL;    // indicate error
00843     }
00844 }
00845 
00846 // Sequence methods
00847 extern "C" Py_ssize_t sequence_length_handler( PyObject *self )
00848 {
00849     try
00850     {
00851         PythonExtensionBase *p = getPythonExtensionBase( self );
00852         return p->sequence_length();
00853     }
00854     catch( Py::Exception &)
00855     {
00856         return -1;    // indicate error
00857     }
00858 }
00859 
00860 extern "C" PyObject *sequence_concat_handler( PyObject *self, PyObject *other )
00861 {
00862     try
00863     {
00864         PythonExtensionBase *p = getPythonExtensionBase( self );
00865         return new_reference_to( p->sequence_concat( Py::Object( other ) ) );
00866     }
00867     catch( Py::Exception &)
00868     {
00869         return NULL;    // indicate error
00870     }
00871 }
00872 
00873 extern "C" PyObject *sequence_repeat_handler( PyObject *self, Py_ssize_t count )
00874 {
00875     try
00876     {
00877         PythonExtensionBase *p = getPythonExtensionBase( self );
00878         return new_reference_to( p->sequence_repeat( count ) );
00879     }
00880     catch( Py::Exception &)
00881     {
00882         return NULL;    // indicate error
00883     }
00884 }
00885 
00886 extern "C" PyObject *sequence_item_handler( PyObject *self, Py_ssize_t index )
00887 {
00888     try
00889     {
00890         PythonExtensionBase *p = getPythonExtensionBase( self );
00891         return new_reference_to( p->sequence_item( index ) );
00892     }
00893     catch( Py::Exception &)
00894     {
00895         return NULL;    // indicate error
00896     }
00897 }
00898 
00899 extern "C" PyObject *sequence_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last )
00900 {
00901     try
00902     {
00903         PythonExtensionBase *p = getPythonExtensionBase( self );
00904         return new_reference_to( p->sequence_slice( first, last ) );
00905     }
00906     catch( Py::Exception &)
00907     {
00908         return NULL;    // indicate error
00909     }
00910 }
00911 
00912 extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value )
00913 {
00914     try
00915     {
00916         PythonExtensionBase *p = getPythonExtensionBase( self );
00917         return p->sequence_ass_item( index, Py::Object( value ) );
00918     }
00919     catch( Py::Exception &)
00920     {
00921         return -1;    // indicate error
00922     }
00923 }
00924 
00925 extern "C" int sequence_ass_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *value )
00926 {
00927     try
00928     {
00929         PythonExtensionBase *p = getPythonExtensionBase( self );
00930         return p->sequence_ass_slice( first, last, Py::Object( value ) );
00931     }
00932     catch( Py::Exception &)
00933     {
00934         return -1;    // indicate error
00935     }
00936 }
00937 
00938 // Mapping
00939 extern "C" Py_ssize_t mapping_length_handler( PyObject *self )
00940 {
00941     try
00942     {
00943         PythonExtensionBase *p = getPythonExtensionBase( self );
00944         return p->mapping_length();
00945     }
00946     catch( Py::Exception &)
00947     {
00948         return -1;    // indicate error
00949     }
00950 }
00951 
00952 extern "C" PyObject *mapping_subscript_handler( PyObject *self, PyObject *key )
00953 {
00954     try
00955     {
00956         PythonExtensionBase *p = getPythonExtensionBase( self );
00957         return new_reference_to( p->mapping_subscript( Py::Object( key ) ) );
00958     }
00959     catch( Py::Exception &)
00960     {
00961         return NULL;    // indicate error
00962     }
00963 }
00964 
00965 extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
00966 {
00967     try
00968     {
00969         PythonExtensionBase *p = getPythonExtensionBase( self );
00970         return p->mapping_ass_subscript( Py::Object( key ), Py::Object( value ) );
00971     }
00972     catch( Py::Exception &)
00973     {
00974         return -1;    // indicate error
00975     }
00976 }
00977 
00978 // Number
00979 extern "C" int number_nonzero_handler( PyObject *self )
00980 {
00981     try
00982     {
00983         PythonExtensionBase *p = getPythonExtensionBase( self );
00984         return p->number_nonzero();
00985     }
00986     catch( Py::Exception &)
00987     {
00988         return -1;    // indicate error
00989     }
00990 }
00991 
00992 extern "C" PyObject *number_negative_handler( PyObject *self )
00993 {
00994     try
00995     {
00996         PythonExtensionBase *p = getPythonExtensionBase( self );
00997         return new_reference_to( p->number_negative() );
00998     }
00999     catch( Py::Exception &)
01000     {
01001         return NULL;    // indicate error
01002     }
01003 }
01004 
01005 extern "C" PyObject *number_positive_handler( PyObject *self )
01006 {
01007     try
01008     {
01009         PythonExtensionBase *p = getPythonExtensionBase( self );
01010         return new_reference_to( p->number_positive() );
01011     }
01012     catch( Py::Exception &)
01013     {
01014         return NULL;    // indicate error
01015     }
01016 }
01017 
01018 extern "C" PyObject *number_absolute_handler( PyObject *self )
01019 {
01020     try
01021     {
01022         PythonExtensionBase *p = getPythonExtensionBase( self );
01023         return new_reference_to( p->number_absolute() );
01024     }
01025     catch( Py::Exception &)
01026     {
01027         return NULL;    // indicate error
01028     }
01029 }
01030 
01031 extern "C" PyObject *number_invert_handler( PyObject *self )
01032 {
01033     try
01034     {
01035         PythonExtensionBase *p = getPythonExtensionBase( self );
01036         return new_reference_to( p->number_invert() );
01037     }
01038     catch( Py::Exception &)
01039     {
01040         return NULL;    // indicate error
01041     }
01042 }
01043 
01044 extern "C" PyObject *number_int_handler( PyObject *self )
01045 {
01046     try
01047     {
01048         PythonExtensionBase *p = getPythonExtensionBase( self );
01049         return new_reference_to( p->number_int() );
01050     }
01051     catch( Py::Exception &)
01052     {
01053         return NULL;    // indicate error
01054     }
01055 }
01056 
01057 extern "C" PyObject *number_float_handler( PyObject *self )
01058 {
01059     try
01060     {
01061         PythonExtensionBase *p = getPythonExtensionBase( self );
01062         return new_reference_to( p->number_float() );
01063     }
01064     catch( Py::Exception &)
01065     {
01066         return NULL;    // indicate error
01067     }
01068 }
01069 
01070 extern "C" PyObject *number_long_handler( PyObject *self )
01071 {
01072     try
01073     {
01074         PythonExtensionBase *p = getPythonExtensionBase( self );
01075         return new_reference_to( p->number_long() );
01076     }
01077     catch( Py::Exception &)
01078     {
01079         return NULL;    // indicate error
01080     }
01081 }
01082 
01083 extern "C" PyObject *number_oct_handler( PyObject *self )
01084 {
01085     try
01086     {
01087         PythonExtensionBase *p = getPythonExtensionBase( self );
01088         return new_reference_to( p->number_oct() );
01089     }
01090     catch( Py::Exception &)
01091     {
01092         return NULL;    // indicate error
01093     }
01094 }
01095 
01096 extern "C" PyObject *number_hex_handler( PyObject *self )
01097 {
01098     try
01099     {
01100         PythonExtensionBase *p = getPythonExtensionBase( self );
01101         return new_reference_to( p->number_hex() );
01102     }
01103     catch( Py::Exception &)
01104     {
01105         return NULL;    // indicate error
01106     }
01107 }
01108 
01109 extern "C" PyObject *number_add_handler( PyObject *self, PyObject *other )
01110 {
01111     try
01112     {
01113         PythonExtensionBase *p = getPythonExtensionBase( self );
01114         return new_reference_to( p->number_add( Py::Object( other ) ) );
01115     }
01116     catch( Py::Exception &)
01117     {
01118         return NULL;    // indicate error
01119     }
01120 }
01121 
01122 extern "C" PyObject *number_subtract_handler( PyObject *self, PyObject *other )
01123 {
01124     try
01125     {
01126         PythonExtensionBase *p = getPythonExtensionBase( self );
01127         return new_reference_to( p->number_subtract( Py::Object( other ) ) );
01128     }
01129     catch( Py::Exception &)
01130     {
01131         return NULL;    // indicate error
01132     }
01133 }
01134 
01135 extern "C" PyObject *number_multiply_handler( PyObject *self, PyObject *other )
01136 {
01137     try
01138     {
01139         PythonExtensionBase *p = getPythonExtensionBase( self );
01140         return new_reference_to( p->number_multiply( Py::Object( other ) ) );
01141     }
01142     catch( Py::Exception &)
01143     {
01144         return NULL;    // indicate error
01145     }
01146 }
01147 
01148 extern "C" PyObject *number_divide_handler( PyObject *self, PyObject *other )
01149 {
01150     try
01151     {
01152         PythonExtensionBase *p = getPythonExtensionBase( self );
01153         return new_reference_to( p->number_divide( Py::Object( other ) ) );
01154     }
01155     catch( Py::Exception &)
01156     {
01157         return NULL;    // indicate error
01158     }
01159 }
01160 
01161 extern "C" PyObject *number_remainder_handler( PyObject *self, PyObject *other )
01162 {
01163     try
01164     {
01165         PythonExtensionBase *p = getPythonExtensionBase( self );
01166         return new_reference_to( p->number_remainder( Py::Object( other ) ) );
01167     }
01168     catch( Py::Exception &)
01169     {
01170         return NULL;    // indicate error
01171     }
01172 }
01173 
01174 extern "C" PyObject *number_divmod_handler( PyObject *self, PyObject *other )
01175 {
01176     try
01177     {
01178         PythonExtensionBase *p = getPythonExtensionBase( self );
01179         return new_reference_to( p->number_divmod( Py::Object( other ) ) );
01180     }
01181     catch( Py::Exception &)
01182     {
01183         return NULL;    // indicate error
01184     }
01185 }
01186 
01187 extern "C" PyObject *number_lshift_handler( PyObject *self, PyObject *other )
01188 {
01189     try
01190     {
01191         PythonExtensionBase *p = getPythonExtensionBase( self );
01192         return new_reference_to( p->number_lshift( Py::Object( other ) ) );
01193     }
01194     catch( Py::Exception &)
01195     {
01196         return NULL;    // indicate error
01197     }
01198 }
01199 
01200 extern "C" PyObject *number_rshift_handler( PyObject *self, PyObject *other )
01201 {
01202     try
01203     {
01204         PythonExtensionBase *p = getPythonExtensionBase( self );
01205         return new_reference_to( p->number_rshift( Py::Object( other ) ) );
01206     }
01207     catch( Py::Exception &)
01208     {
01209         return NULL;    // indicate error
01210     }
01211 }
01212 
01213 extern "C" PyObject *number_and_handler( PyObject *self, PyObject *other )
01214 {
01215     try
01216     {
01217         PythonExtensionBase *p = getPythonExtensionBase( self );
01218         return new_reference_to( p->number_and( Py::Object( other ) ) );
01219     }
01220     catch( Py::Exception &)
01221     {
01222         return NULL;    // indicate error
01223     }
01224 }
01225 
01226 extern "C" PyObject *number_xor_handler( PyObject *self, PyObject *other )
01227 {
01228     try
01229     {
01230         PythonExtensionBase *p = getPythonExtensionBase( self );
01231         return new_reference_to( p->number_xor( Py::Object( other ) ) );
01232     }
01233     catch( Py::Exception &)
01234     {
01235         return NULL;    // indicate error
01236     }
01237 }
01238 
01239 extern "C" PyObject *number_or_handler( PyObject *self, PyObject *other )
01240 {
01241     try
01242     {
01243         PythonExtensionBase *p = getPythonExtensionBase( self );
01244         return new_reference_to( p->number_or( Py::Object( other ) ) );
01245     }
01246     catch( Py::Exception &)
01247     {
01248         return NULL;    // indicate error
01249     }
01250 }
01251 
01252 extern "C" PyObject *number_power_handler( PyObject *self, PyObject *x1, PyObject *x2 )
01253 {
01254     try
01255     {
01256         PythonExtensionBase *p = getPythonExtensionBase( self );
01257         return new_reference_to( p->number_power( Py::Object( x1 ), Py::Object( x2 ) ) );
01258     }
01259     catch( Py::Exception &)
01260     {
01261         return NULL;    // indicate error
01262     }
01263 }
01264 
01265 // Buffer
01266 extern "C" Py_ssize_t buffer_getreadbuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
01267 {
01268     try
01269     {
01270         PythonExtensionBase *p = getPythonExtensionBase( self );
01271         return p->buffer_getreadbuffer( index, pp );
01272     }
01273     catch( Py::Exception &)
01274     {
01275         return -1;    // indicate error
01276     }
01277 }
01278 
01279 extern "C" Py_ssize_t buffer_getwritebuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
01280 {
01281     try
01282     {
01283         PythonExtensionBase *p = getPythonExtensionBase( self );
01284         return p->buffer_getwritebuffer( index, pp );
01285     }
01286     catch( Py::Exception &)
01287     {
01288         return -1;    // indicate error
01289     }
01290 }
01291 
01292 extern "C" Py_ssize_t buffer_getsegcount_handler( PyObject *self, Py_ssize_t *count )
01293 {
01294     try
01295     {
01296         PythonExtensionBase *p = getPythonExtensionBase( self );
01297         return p->buffer_getsegcount( count );
01298     }
01299     catch( Py::Exception &)
01300     {
01301         return -1;    // indicate error
01302     }
01303 }
01304 
01305 //================================================================================
01306 //
01307 //    Implementation of PythonExtensionBase
01308 //
01309 //================================================================================
01310 #define missing_method( method ) \
01311     throw RuntimeError( "Extension object missing implement of " #method );
01312 
01313 PythonExtensionBase::PythonExtensionBase()
01314 {
01315     ob_refcnt = 0;
01316 }
01317 
01318 PythonExtensionBase::~PythonExtensionBase()
01319 {
01320     assert( ob_refcnt == 0 );
01321 }
01322 
01323 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name )
01324 {
01325     Py::TupleN args;
01326     return  self().callMemberFunction( fn_name, args );
01327 }
01328 
01329 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01330                                             const Py::Object &arg1 )
01331 {
01332     Py::TupleN args( arg1 );
01333     return  self().callMemberFunction( fn_name, args );
01334 }
01335 
01336 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01337                                             const Py::Object &arg1, const Py::Object &arg2 )
01338 {
01339     Py::TupleN args( arg1, arg2 );
01340     return self().callMemberFunction( fn_name, args );
01341 }
01342 
01343 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01344                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3 )
01345 {
01346     Py::TupleN args( arg1, arg2, arg3 );
01347     return self().callMemberFunction( fn_name, args );
01348 }
01349 
01350 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01351                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01352                                             const Py::Object &arg4 )
01353 {
01354     Py::TupleN args( arg1, arg2, arg3, arg4 );
01355     return self().callMemberFunction( fn_name, args );
01356 }
01357 
01358 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01359                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01360                                             const Py::Object &arg4, const Py::Object &arg5 )
01361 {
01362     Py::TupleN args( arg1, arg2, arg3, arg4, arg5 );
01363     return self().callMemberFunction( fn_name, args );
01364 }
01365 
01366 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01367                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01368                                             const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6 )
01369 {
01370     Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 );
01371     return self().callMemberFunction( fn_name, args );
01372 }
01373 
01374 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01375                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01376                                             const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
01377                                             const Py::Object &arg7 )
01378 {
01379     Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
01380     return self().callMemberFunction( fn_name, args );
01381 }
01382 
01383 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01384                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01385                                             const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
01386                                             const Py::Object &arg7, const Py::Object &arg8 )
01387 {
01388     Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 );
01389     return self().callMemberFunction( fn_name, args );
01390 }
01391 
01392 Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
01393                                             const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
01394                                             const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
01395                                             const Py::Object &arg7, const Py::Object &arg8, const Py::Object &arg9 )
01396 {
01397     Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 );
01398     return self().callMemberFunction( fn_name, args );
01399 }
01400 
01401 void PythonExtensionBase::reinit( Tuple &args, Dict &kwds )
01402 {
01403     throw RuntimeError( "Must not call __init__ twice on this class" );
01404 }
01405 
01406 Py::Object PythonExtensionBase::genericGetAttro( const Py::String &name )
01407 {
01408     return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) );
01409 }
01410 
01411 int PythonExtensionBase::genericSetAttro( const Py::String &name, const Py::Object &value )
01412 {
01413     return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() );
01414 }
01415 
01416 int PythonExtensionBase::print( FILE *, int )
01417 {
01418     missing_method( print );
01419     return -1;
01420 }
01421 
01422 Py::Object PythonExtensionBase::getattr( const char * )
01423 {
01424     missing_method( getattr );
01425     return Py::None();
01426 }
01427 
01428 int PythonExtensionBase::setattr( const char *, const Py::Object &)
01429 {
01430     missing_method( setattr );
01431     return -1;
01432 }
01433 
01434 Py::Object PythonExtensionBase::getattro( const Py::String &name )
01435 {
01436     return genericGetAttro( name );
01437 }
01438 
01439 int PythonExtensionBase::setattro( const Py::String &name, const Py::Object &value )
01440 {
01441     return genericSetAttro( name, value );
01442 }
01443 
01444 int PythonExtensionBase::compare( const Py::Object &)
01445 {
01446     missing_method( compare );
01447     return -1;
01448 }
01449 
01450 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
01451 Py::Object PythonExtensionBase::rich_compare( const Py::Object &, int op )
01452 {
01453     missing_method( rich_compare );
01454     return Py::None();
01455 }
01456 
01457 #endif
01458 Py::Object PythonExtensionBase::repr()
01459 {
01460     missing_method( repr );
01461     return Py::None();
01462 }
01463 
01464 Py::Object PythonExtensionBase::str()
01465 {
01466     missing_method( str );
01467     return Py::None();
01468 }
01469 
01470 long PythonExtensionBase::hash()
01471 {
01472     missing_method( hash );
01473     return -1;
01474 }
01475 
01476 Py::Object PythonExtensionBase::call( const Py::Object &, const Py::Object &)
01477 {
01478     missing_method( call );
01479     return Py::None();
01480 }
01481 
01482 Py::Object PythonExtensionBase::iter()
01483 {
01484     missing_method( iter );
01485     return Py::None();
01486 }
01487 
01488 PyObject *PythonExtensionBase::iternext()
01489 {
01490     missing_method( iternext );
01491     return NULL;
01492 }
01493 
01494 // Sequence methods
01495 int PythonExtensionBase::sequence_length()
01496 {
01497     missing_method( sequence_length );
01498     return -1;
01499 }
01500 
01501 Py::Object PythonExtensionBase::sequence_concat( const Py::Object &)
01502 {
01503     missing_method( sequence_concat );
01504     return Py::None();
01505 }
01506 
01507 Py::Object PythonExtensionBase::sequence_repeat( Py_ssize_t )
01508 {
01509     missing_method( sequence_repeat );
01510     return Py::None();
01511 }
01512 
01513 Py::Object PythonExtensionBase::sequence_item( Py_ssize_t )
01514 {
01515     missing_method( sequence_item );
01516     return Py::None();
01517 }
01518 
01519 Py::Object PythonExtensionBase::sequence_slice( Py_ssize_t, Py_ssize_t )
01520 {
01521     missing_method( sequence_slice );
01522     return Py::None();
01523 }
01524 
01525 int PythonExtensionBase::sequence_ass_item( Py_ssize_t, const Py::Object &)
01526 {
01527     missing_method( sequence_ass_item );
01528     return -1;
01529 }
01530 
01531 int PythonExtensionBase::sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Py::Object &)
01532 {
01533     missing_method( sequence_ass_slice );
01534     return -1;
01535 }
01536 
01537 // Mapping
01538 int PythonExtensionBase::mapping_length()
01539 {
01540     missing_method( mapping_length );
01541     return -1;
01542 }
01543 
01544 Py::Object PythonExtensionBase::mapping_subscript( const Py::Object &)
01545 {
01546     missing_method( mapping_subscript );
01547     return Py::None();
01548 }
01549 
01550 int PythonExtensionBase::mapping_ass_subscript( const Py::Object &, const Py::Object &)
01551 {
01552     missing_method( mapping_ass_subscript );
01553     return -1;
01554 }
01555 
01556 // Number
01557 int PythonExtensionBase::number_nonzero()
01558 {
01559     missing_method( number_nonzero );
01560     return -1;
01561 }
01562 
01563 Py::Object PythonExtensionBase::number_negative()
01564 {
01565     missing_method( number_negative );
01566     return Py::None();
01567 }
01568 
01569 Py::Object PythonExtensionBase::number_positive()
01570 {
01571     missing_method( number_positive );
01572     return Py::None();
01573 }
01574 
01575 Py::Object PythonExtensionBase::number_absolute()
01576 {
01577     missing_method( number_absolute );
01578     return Py::None();
01579 }
01580 
01581 Py::Object PythonExtensionBase::number_invert()
01582 {
01583     missing_method( number_invert );
01584     return Py::None();
01585 }
01586 
01587 Py::Object PythonExtensionBase::number_int()
01588 {
01589     missing_method( number_int );
01590     return Py::None();
01591 }
01592 
01593 Py::Object PythonExtensionBase::number_float()
01594 {
01595     missing_method( number_float );
01596     return Py::None();
01597 }
01598 
01599 Py::Object PythonExtensionBase::number_long()
01600 {
01601     missing_method( number_long );
01602     return Py::None();
01603 }
01604 
01605 Py::Object PythonExtensionBase::number_oct()
01606 {
01607     missing_method( number_oct );
01608     return Py::None();
01609 }
01610 
01611 Py::Object PythonExtensionBase::number_hex()
01612 {
01613     missing_method( number_hex );
01614     return Py::None();
01615 }
01616 
01617 Py::Object PythonExtensionBase::number_add( const Py::Object &)
01618 {
01619     missing_method( number_add );
01620     return Py::None();
01621 }
01622 
01623 Py::Object PythonExtensionBase::number_subtract( const Py::Object &)
01624 {
01625     missing_method( number_subtract );
01626     return Py::None();
01627 }
01628 
01629 Py::Object PythonExtensionBase::number_multiply( const Py::Object &)
01630 {
01631     missing_method( number_multiply );
01632     return Py::None();
01633 }
01634 
01635 Py::Object PythonExtensionBase::number_divide( const Py::Object &)
01636 {
01637     missing_method( number_divide );
01638     return Py::None();
01639 }
01640 
01641 Py::Object PythonExtensionBase::number_remainder( const Py::Object &)
01642 {
01643     missing_method( number_remainder );
01644     return Py::None();
01645 }
01646 
01647 Py::Object PythonExtensionBase::number_divmod( const Py::Object &)
01648 {
01649     missing_method( number_divmod );
01650     return Py::None();
01651 }
01652 
01653 Py::Object PythonExtensionBase::number_lshift( const Py::Object &)
01654 {
01655     missing_method( number_lshift );
01656     return Py::None();
01657 }
01658 
01659 Py::Object PythonExtensionBase::number_rshift( const Py::Object &)
01660 {
01661     missing_method( number_rshift );
01662     return Py::None();
01663 }
01664 
01665 Py::Object PythonExtensionBase::number_and( const Py::Object &)
01666 {
01667     missing_method( number_and );
01668     return Py::None();
01669 }
01670 
01671 Py::Object PythonExtensionBase::number_xor( const Py::Object &)
01672 {
01673     missing_method( number_xor );
01674     return Py::None();
01675 }
01676 
01677 Py::Object PythonExtensionBase::number_or( const Py::Object &)
01678 {
01679     missing_method( number_or );
01680     return Py::None();
01681 }
01682 
01683 Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Object &)
01684 {
01685     missing_method( number_power );
01686     return Py::None();
01687 }
01688 
01689 // Buffer
01690 Py_ssize_t PythonExtensionBase::buffer_getreadbuffer( Py_ssize_t, void** )
01691 {
01692     missing_method( buffer_getreadbuffer );
01693     return -1;
01694 }
01695 
01696 Py_ssize_t PythonExtensionBase::buffer_getwritebuffer( Py_ssize_t, void** )
01697 {
01698     missing_method( buffer_getwritebuffer );
01699     return -1;
01700 }
01701 
01702 Py_ssize_t PythonExtensionBase::buffer_getsegcount( Py_ssize_t* )
01703 {
01704     missing_method( buffer_getsegcount );
01705     return -1;
01706 }
01707 
01708 //--------------------------------------------------------------------------------
01709 //
01710 //    Method call handlers for
01711 //        PythonExtensionBase
01712 //        ExtensionModuleBase
01713 //
01714 //--------------------------------------------------------------------------------
01715 extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
01716 {
01717     try
01718     {
01719         Tuple self_and_name_tuple( _self_and_name_tuple );
01720 
01721         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01722         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01723         if( self_as_void == NULL )
01724             return NULL;
01725 
01726         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01727 
01728         Tuple args( _args );
01729 
01730         if( _keywords == NULL )
01731         {
01732             Dict keywords;    // pass an empty dict
01733 
01734             Object result
01735                     (
01736                     self->invoke_method_keyword
01737                         (
01738                         PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
01739                         args,
01740                         keywords
01741                         )
01742                     );
01743 
01744             return new_reference_to( result.ptr() );
01745         }
01746         else
01747         {
01748             Dict keywords( _keywords ); // make dict
01749 
01750             Object result
01751                     (
01752                     self->invoke_method_keyword
01753                         (
01754                         PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
01755                         args,
01756                         keywords
01757                         )
01758                     );
01759 
01760             return new_reference_to( result.ptr() );
01761         }
01762     }
01763     catch( Exception & )
01764     {
01765         return 0;
01766     }
01767 }
01768 
01769 extern "C" PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * )
01770 {
01771     try
01772     {
01773         Tuple self_and_name_tuple( _self_and_name_tuple );
01774 
01775         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01776         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01777         if( self_as_void == NULL )
01778             return NULL;
01779 
01780         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01781 
01782         Object result
01783                 (
01784                 self->invoke_method_noargs
01785                     (
01786                     PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() )
01787                     )
01788                 );
01789 
01790         return new_reference_to( result.ptr() );
01791     }
01792     catch( Exception & )
01793     {
01794         return 0;
01795     }
01796 #if 0
01797     try
01798     {
01799         Tuple self_and_name_tuple( _self_and_name_tuple );
01800 
01801         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01802         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01803         if( self_as_void == NULL )
01804             return NULL;
01805 
01806         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01807 
01808         String py_name( self_and_name_tuple[1] );
01809         std::string name( py_name.as_std_string( NULL ) );
01810 
01811         Object result( self->invoke_method_noargs( name ) );
01812 
01813         return new_reference_to( result.ptr() );
01814     }
01815     catch( Exception & )
01816     {
01817         return 0;
01818     }
01819 #else
01820     return 0;
01821 #endif
01822 }
01823 
01824 extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
01825 {
01826     try
01827     {
01828         Tuple self_and_name_tuple( _self_and_name_tuple );
01829 
01830         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01831         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01832         if( self_as_void == NULL )
01833             return NULL;
01834 
01835         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01836         Tuple args( _args );
01837 
01838         Object result
01839                 (
01840                 self->invoke_method_varargs
01841                     (
01842                     PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
01843                     args
01844                     )
01845                 );
01846 
01847         return new_reference_to( result.ptr() );
01848     }
01849     catch( Exception & )
01850     {
01851         return 0;
01852     }
01853 }
01854 
01855 extern "C" void do_not_dealloc( void * )
01856 {}
01857 
01858 //--------------------------------------------------------------------------------
01859 //
01860 //    ExtensionExceptionType
01861 //
01862 //--------------------------------------------------------------------------------
01863 ExtensionExceptionType::ExtensionExceptionType()
01864 : Py::Object()
01865 {
01866 }
01867 
01868 void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
01869 {
01870     std::string module_name( module.fullName() );
01871     module_name += ".";
01872     module_name += name;
01873     set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
01874 }
01875 
01876 void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent)
01877 {
01878      std::string module_name( module.fullName() );
01879      module_name += ".";
01880      module_name += name;
01881      set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
01882 }
01883 
01884 ExtensionExceptionType::~ExtensionExceptionType()
01885 {
01886 }
01887 
01888 Exception::Exception( ExtensionExceptionType &exception, const std::string& reason )
01889 {
01890     PyErr_SetString( exception.ptr(), reason.c_str() );
01891 }
01892 
01893 Exception::Exception( ExtensionExceptionType &exception, Object &reason )
01894 {
01895     PyErr_SetObject( exception.ptr(), reason.ptr() );
01896 }
01897 
01898 Exception::Exception( PyObject *exception, Object &reason )
01899 {
01900     PyErr_SetObject( exception, reason.ptr() );
01901 }
01902 
01903 }    // end of namespace Py

Generated on Wed Nov 23 19:00:05 2011 for FreeCAD by  doxygen 1.6.1