lib

cxx_extensions.cxx

00001 #include "Extensions.hxx"
00002 #include "Exception.hxx"
00003 
00004 #include <assert.h>
00005 
00006 namespace Py 
00007 {
00008 
00009 //================================================================================
00010 //
00011 //  Implementation of MethodTable
00012 //
00013 //================================================================================
00014 
00015 PyMethodDef MethodTable::method( const char* method_name, PyCFunction f, int flags, const char* doc ) 
00016     {
00017     PyMethodDef m;
00018     m.ml_name = const_cast<char*>( method_name );
00019     m.ml_meth = f;
00020     m.ml_flags = flags;
00021     m.ml_doc = const_cast<char*>( doc );
00022     return m;
00023     }
00024 
00025 MethodTable::MethodTable()
00026     {
00027     t.push_back( method( 0, 0, 0, 0 ) );
00028     mt = 0;
00029     }
00030 
00031 MethodTable::~MethodTable()
00032     {
00033     delete [] mt;
00034     }
00035 
00036 void MethodTable::add( const char* method_name, PyCFunction f, const char* doc, int flag )
00037     {
00038     if( !mt )
00039         {
00040         t.insert( t.end()-1, method( method_name, f, flag, doc ) );
00041         }
00042     else
00043         {
00044         throw RuntimeError( "Too late to add a module method!" );
00045         }
00046     }
00047 
00048 PyMethodDef* MethodTable::table()
00049     {    
00050     if( !mt )
00051         {
00052         int t1size = t.size();
00053         mt = new PyMethodDef[t1size];
00054         int j = 0;
00055         for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
00056             {
00057             mt[j++] = *i;
00058             }
00059         }
00060     return mt;
00061     }
00062 
00063 //================================================================================
00064 //
00065 //  Implementation of ExtensionModule
00066 //
00067 //================================================================================
00068 ExtensionModuleBase::ExtensionModuleBase( const char *name )
00069     : module_name( name )
00070     , full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : module_name )
00071     , method_table()
00072     {}
00073 
00074 ExtensionModuleBase::~ExtensionModuleBase()
00075     {}
00076 
00077 const std::string &ExtensionModuleBase::name() const
00078     {
00079     return module_name;
00080     }
00081 
00082 const std::string &ExtensionModuleBase::fullName() const
00083     {
00084     return full_module_name;
00085     }
00086 
00087 class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
00088     {
00089 public:
00090     ExtensionModuleBasePtr( ExtensionModuleBase *_module )
00091         : module( _module )
00092         {}
00093     virtual ~ExtensionModuleBasePtr()
00094         {}
00095 
00096     ExtensionModuleBase *module;
00097     };
00098 
00099 
00100 void ExtensionModuleBase::initialize( const char *module_doc )
00101     {
00102     PyObject *module_ptr = new ExtensionModuleBasePtr( this );
00103 
00104     Py_InitModule4
00105     (
00106     const_cast<char *>( module_name.c_str() ),  // name
00107     method_table.table(),               // methods
00108     const_cast<char *>( module_doc ),       // docs
00109     module_ptr,                 // pass to functions as "self"
00110     PYTHON_API_VERSION              // API version
00111     );
00112     }
00113 
00114 Py::Module ExtensionModuleBase::module(void) const
00115     {
00116     return Module( full_module_name );
00117     }
00118 
00119 Py::Dict ExtensionModuleBase::moduleDictionary(void) const
00120     {
00121     return module().getDict();
00122     }
00123 
00124 //--------------------------------------------------------------------------------
00125 
00126 //================================================================================
00127 //
00128 //  Implementation of PythonType
00129 //
00130 //================================================================================
00131 
00132 extern "C"
00133     {
00134     static void standard_dealloc(PyObject* p);
00135     //
00136     // All the following functions redirect the call from Python
00137     // onto the matching virtual function in PythonExtensionBase
00138     //
00139     static int print_handler (PyObject*, FILE *, int);
00140     static PyObject* getattr_handler (PyObject*, char*);
00141     static int setattr_handler (PyObject*, char*, PyObject*);
00142     static PyObject* getattro_handler (PyObject*, PyObject*);
00143     static int setattro_handler (PyObject*, PyObject*, PyObject*);
00144     static int compare_handler (PyObject*, PyObject*);
00145     static PyObject* repr_handler (PyObject*);
00146     static PyObject* str_handler (PyObject*);
00147     static long hash_handler (PyObject*);
00148     static PyObject* call_handler (PyObject*, PyObject*, PyObject*);
00149 
00150     // Sequence methods
00151     static int sequence_length_handler(PyObject*);
00152     static PyObject* sequence_concat_handler(PyObject*,PyObject*);
00153     static PyObject* sequence_repeat_handler(PyObject*, int);
00154     static PyObject* sequence_item_handler(PyObject*, int);
00155     static PyObject* sequence_slice_handler(PyObject*, int, int);
00156     static int sequence_ass_item_handler(PyObject*, int, PyObject*);
00157     static int sequence_ass_slice_handler(PyObject*, int, int, PyObject*);
00158     // Mapping
00159     static int mapping_length_handler(PyObject*);
00160     static PyObject* mapping_subscript_handler(PyObject*, PyObject*);
00161     static int mapping_ass_subscript_handler(PyObject*, PyObject*, PyObject*);
00162 
00163     // Numeric methods
00164     static int number_nonzero_handler (PyObject*);
00165     static PyObject* number_negative_handler (PyObject*);
00166     static PyObject* number_positive_handler (PyObject*);
00167     static PyObject* number_absolute_handler (PyObject*);
00168     static PyObject* number_invert_handler (PyObject*);
00169     static PyObject* number_int_handler (PyObject*);
00170     static PyObject* number_float_handler (PyObject*);
00171     static PyObject* number_long_handler (PyObject*);
00172     static PyObject* number_oct_handler (PyObject*);
00173     static PyObject* number_hex_handler (PyObject*);
00174     static PyObject* number_add_handler (PyObject*, PyObject*);
00175     static PyObject* number_subtract_handler (PyObject*, PyObject*);
00176     static PyObject* number_multiply_handler (PyObject*, PyObject*);
00177     static PyObject* number_divide_handler (PyObject*, PyObject*);
00178     static PyObject* number_remainder_handler (PyObject*, PyObject*);
00179     static PyObject* number_divmod_handler (PyObject*, PyObject*);
00180     static PyObject* number_lshift_handler (PyObject*, PyObject*);
00181     static PyObject* number_rshift_handler (PyObject*, PyObject*);
00182     static PyObject* number_and_handler (PyObject*, PyObject*);
00183     static PyObject* number_xor_handler (PyObject*, PyObject*);
00184     static PyObject* number_or_handler (PyObject*, PyObject*);
00185     static PyObject* number_power_handler(PyObject*, PyObject*, PyObject*);
00186 
00187     // Buffer
00188     static int buffer_getreadbuffer_handler (PyObject*, int, void**);
00189     static int buffer_getwritebuffer_handler (PyObject*, int, void**);
00190     static int buffer_getsegcount_handler (PyObject*, int*);
00191     }
00192 
00193 
00194 extern "C" void standard_dealloc( PyObject* p )
00195     {
00196     PyMem_DEL( p );
00197     }
00198 
00199 void PythonType::supportSequenceType()
00200     {
00201     if( !sequence_table )
00202         {
00203         sequence_table = new PySequenceMethods;
00204         table->tp_as_sequence = sequence_table;
00205         sequence_table->sq_length = sequence_length_handler;
00206         sequence_table->sq_concat = sequence_concat_handler;
00207         sequence_table->sq_repeat = sequence_repeat_handler;
00208         sequence_table->sq_item = sequence_item_handler;
00209         sequence_table->sq_slice = sequence_slice_handler;
00210 
00211         sequence_table->sq_ass_item = sequence_ass_item_handler;    // BAS setup seperately?
00212         sequence_table->sq_ass_slice = sequence_ass_slice_handler;  // BAS setup seperately?
00213         }
00214     }
00215 
00216 void PythonType::supportMappingType()
00217     {
00218     if( !mapping_table )
00219         {
00220         mapping_table = new PyMappingMethods;
00221         table->tp_as_mapping = mapping_table;
00222         mapping_table->mp_length = mapping_length_handler;
00223         mapping_table->mp_subscript = mapping_subscript_handler;
00224         mapping_table->mp_ass_subscript = mapping_ass_subscript_handler;    // BAS setup seperately?
00225         }
00226     }
00227 
00228 void PythonType::supportNumberType()
00229     {
00230     if( !number_table )
00231         {
00232         number_table = new PyNumberMethods;
00233         table->tp_as_number = number_table;
00234         number_table->nb_add = number_add_handler;
00235         number_table->nb_subtract = number_subtract_handler;
00236         number_table->nb_multiply = number_multiply_handler;
00237         number_table->nb_divide = number_divide_handler;
00238         number_table->nb_remainder = number_remainder_handler;
00239         number_table->nb_divmod = number_divmod_handler;
00240         number_table->nb_power = number_power_handler;
00241         number_table->nb_negative = number_negative_handler;
00242         number_table->nb_positive = number_positive_handler;
00243         number_table->nb_absolute = number_absolute_handler;
00244         number_table->nb_nonzero = number_nonzero_handler;
00245         number_table->nb_invert = number_invert_handler;
00246         number_table->nb_lshift = number_lshift_handler;
00247         number_table->nb_rshift = number_rshift_handler;
00248         number_table->nb_and = number_and_handler;
00249         number_table->nb_xor = number_xor_handler;
00250         number_table->nb_or = number_or_handler;
00251         number_table->nb_coerce = 0;
00252         number_table->nb_int = number_int_handler;
00253         number_table->nb_long = number_long_handler;
00254         number_table->nb_float = number_float_handler;
00255         number_table->nb_oct = number_oct_handler;
00256         number_table->nb_hex = number_hex_handler;
00257         }
00258     }
00259 
00260 void PythonType::supportBufferType()
00261     {
00262     if( !buffer_table )
00263         {
00264         buffer_table = new PyBufferProcs;
00265         table->tp_as_buffer = buffer_table;
00266         buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
00267         buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
00268         buffer_table->bf_getsegcount = buffer_getsegcount_handler;
00269         }
00270     }
00271 
00272 // if you define one sequence method you must define 
00273 // all of them except the assigns
00274 
00275 PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
00276     : table( new PyTypeObject )
00277     , sequence_table( NULL )
00278     , mapping_table( NULL )
00279     , number_table( NULL )
00280     , buffer_table( NULL )
00281     {
00282     *reinterpret_cast<PyObject*>( table ) = py_object_initializer;
00283     table->ob_type = _Type_Type();
00284     table->ob_size = 0;
00285     table->tp_name = const_cast<char *>( default_name );
00286     table->tp_basicsize = basic_size;
00287     table->tp_itemsize = itemsize;
00288     table->tp_dealloc = ( destructor ) standard_dealloc;
00289     table->tp_print = 0;
00290     table->tp_getattr = 0;
00291     table->tp_setattr = 0;
00292     table->tp_compare = 0;
00293     table->tp_repr = 0;
00294     table->tp_as_number = 0;
00295     table->tp_as_sequence = 0;
00296     table->tp_as_mapping =  0;
00297     table->tp_hash = 0;
00298     table->tp_call = 0;
00299     table->tp_str = 0;
00300     table->tp_getattro = 0;
00301     table->tp_setattro = 0;
00302     table->tp_as_buffer = 0;
00303     table->tp_flags = 0L;
00304     table->tp_doc = 0;
00305 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
00306     // first use in 2.0
00307     table->tp_traverse = 0L;
00308     table->tp_clear = 0L;
00309 #else
00310     table->tp_xxx5 = 0L;
00311     table->tp_xxx6 = 0L;
00312 #endif
00313 #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
00314     // first defined in 2.1
00315     table->tp_richcompare = 0L;
00316     table->tp_weaklistoffset = 0L;
00317 #else
00318     table->tp_xxx7 = 0L;
00319     table->tp_xxx8 = 0L;
00320 #endif
00321 
00322 #ifdef COUNT_ALLOCS
00323     table->tp_alloc = 0;
00324     table->tp_free = 0;
00325     table->tp_maxalloc = 0;
00326     table->tp_next = 0;
00327 #endif
00328     }
00329 
00330 PythonType::~PythonType( )
00331     {
00332     delete table;
00333     delete sequence_table;
00334     delete mapping_table;
00335     delete number_table;
00336     delete buffer_table;
00337     }
00338 
00339 PyTypeObject* PythonType::type_object( ) const
00340     {return table;}
00341 
00342 void PythonType::name( const char* nam )
00343     {
00344     table->tp_name = const_cast<char *>( nam );
00345     }
00346 
00347 const char *PythonType::getName() const
00348     {
00349     return table->tp_name;
00350     }
00351 
00352 void PythonType::doc( const char* d )
00353     {
00354     table->tp_doc = const_cast<char *>( d );
00355     }
00356 
00357 const char *PythonType::getDoc() const
00358     {
00359     return table->tp_doc;
00360     }
00361 
00362 void PythonType::dealloc( void( *f )( PyObject* ))
00363     {
00364     table->tp_dealloc = f;
00365     }
00366 
00367 void PythonType::supportPrint()
00368     {
00369     table->tp_print = print_handler;
00370     }
00371 
00372 void PythonType::supportGetattr()
00373     {
00374     table->tp_getattr = getattr_handler;
00375     }
00376 
00377 void PythonType::supportSetattr()
00378     {
00379     table->tp_setattr = setattr_handler;
00380     }
00381 
00382 void PythonType::supportGetattro()
00383     {
00384     table->tp_getattro = getattro_handler;
00385     }
00386 
00387 void PythonType::supportSetattro()
00388     {
00389     table->tp_setattro = setattro_handler;
00390     }
00391 
00392 void PythonType::supportCompare()
00393     {
00394     table->tp_compare = compare_handler;
00395     }
00396 
00397 void PythonType::supportRepr()
00398     {
00399     table->tp_repr = repr_handler;
00400     }
00401 
00402 void PythonType::supportStr()
00403     {
00404     table->tp_str = str_handler;
00405     }
00406 
00407 void PythonType::supportHash()
00408     {
00409     table->tp_hash = hash_handler;
00410     }
00411 
00412 void PythonType::supportCall()
00413     {
00414     table->tp_call = call_handler;
00415     }
00416 
00417 //--------------------------------------------------------------------------------
00418 //
00419 //  Handlers
00420 //
00421 //--------------------------------------------------------------------------------
00422 extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
00423     {
00424     try
00425         {
00426         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00427         return p->print( fp, flags );
00428         }
00429     catch( Py::Exception & )
00430         {
00431         return -1;  // indicate error
00432         }
00433     }
00434 
00435 extern "C" PyObject* getattr_handler( PyObject *self, char *name )
00436     {
00437     try
00438         {
00439         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00440         return new_reference_to( p->getattr( name ) );
00441         }
00442     catch( Py::Exception & )
00443         {
00444         return NULL;    // indicate error
00445         }
00446     }
00447 
00448 extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
00449     {
00450     try
00451         {
00452         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00453         return p->setattr( name, Py::Object( value ) );
00454         }
00455     catch( Py::Exception & )
00456         {
00457         return -1;  // indicate error
00458         }
00459     }
00460 
00461 extern "C" PyObject* getattro_handler( PyObject *self, PyObject *name )
00462     {
00463     try
00464         {
00465         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00466         return new_reference_to( p->getattro( Py::Object( name ) ) );
00467         }
00468     catch( Py::Exception & )
00469         {
00470         return NULL;    // indicate error
00471         }
00472     }
00473 
00474 extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
00475     {
00476     try
00477         {
00478         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00479         return p->setattro( Py::Object( name ), Py::Object( value ) );
00480         }
00481     catch( Py::Exception & )
00482         {
00483         return -1;  // indicate error
00484         }
00485     }
00486 
00487 extern "C" int compare_handler( PyObject *self, PyObject *other )
00488     {
00489     try
00490         {
00491         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00492         return p->compare( Py::Object( other ) );
00493         }
00494     catch( Py::Exception & )
00495         {
00496         return -1;  // indicate error
00497         }
00498     }
00499 
00500 extern "C" PyObject* repr_handler( PyObject *self )
00501     {
00502     try
00503         {
00504         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00505         return new_reference_to( p->repr() );
00506         }
00507     catch( Py::Exception & )
00508         {
00509         return NULL;    // indicate error
00510         }
00511     }
00512 
00513 extern "C" PyObject* str_handler( PyObject *self )
00514     {
00515     try
00516         {
00517         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00518         return new_reference_to( p->str() );
00519         }
00520     catch( Py::Exception & )
00521         {
00522         return NULL;    // indicate error
00523         }
00524     }
00525 
00526 extern "C" long hash_handler( PyObject *self )
00527     {
00528     try
00529         {
00530         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00531         return p->hash();
00532         }
00533     catch( Py::Exception & )
00534         {
00535         return -1;  // indicate error
00536         }
00537     }
00538 
00539 extern "C" PyObject* call_handler( PyObject *self, PyObject *args, PyObject *kw )
00540     {
00541     try
00542         {
00543         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00544         return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
00545         if( kw != NULL )
00546         return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
00547         else
00548         return new_reference_to( p->call( Py::Object( args ), Py::Object() ) );
00549         }
00550     catch( Py::Exception & )
00551         {
00552         return NULL;    // indicate error
00553         }
00554     }
00555 
00556 
00557 // Sequence methods
00558 extern "C" int sequence_length_handler( PyObject *self )
00559     {
00560     try
00561         {
00562         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00563         return p->sequence_length();
00564         }
00565     catch( Py::Exception & )
00566         {
00567         return -1;  // indicate error
00568         }
00569     }
00570 
00571 extern "C" PyObject* sequence_concat_handler( PyObject *self, PyObject *other )
00572     {
00573     try
00574         {
00575         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00576         return new_reference_to( p->sequence_concat( Py::Object( other ) ) );
00577         }
00578     catch( Py::Exception & )
00579         {
00580         return NULL;    // indicate error
00581         }
00582     }
00583 
00584 extern "C" PyObject* sequence_repeat_handler( PyObject *self, int count )
00585     {
00586     try
00587         {
00588         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00589         return new_reference_to( p->sequence_repeat( count ) );
00590         }
00591     catch( Py::Exception & )
00592         {
00593         return NULL;    // indicate error
00594         }
00595     }
00596 
00597 extern "C" PyObject* sequence_item_handler( PyObject *self, int index )
00598     {
00599     try
00600         {
00601         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00602         return new_reference_to( p->sequence_item( index ) );
00603         }
00604     catch( Py::Exception & )
00605         {
00606         return NULL;    // indicate error
00607         }
00608     }
00609 
00610 extern "C" PyObject* sequence_slice_handler( PyObject *self, int first, int last )
00611     {
00612     try
00613         {
00614         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00615         return new_reference_to( p->sequence_slice( first, last ) );
00616         }
00617     catch( Py::Exception & )
00618         {
00619         return NULL;    // indicate error
00620         }
00621     }
00622 
00623 extern "C" int sequence_ass_item_handler( PyObject *self, int index, PyObject *value )
00624     {
00625     try
00626         {
00627         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00628         return p->sequence_ass_item( index, Py::Object( value ) );
00629         }
00630     catch( Py::Exception & )
00631         {
00632         return -1;  // indicate error
00633         }
00634     }
00635 
00636 extern "C" int sequence_ass_slice_handler( PyObject *self, int first, int last, PyObject *value )
00637     {
00638     try
00639         {
00640         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00641         return p->sequence_ass_slice( first, last, Py::Object( value ) );
00642         }
00643     catch( Py::Exception & )
00644         {
00645         return -1;  // indicate error
00646         }
00647     }
00648 
00649 // Mapping
00650 extern "C" int mapping_length_handler( PyObject *self )
00651     {
00652     try
00653         {
00654         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00655         return p->mapping_length();
00656         }
00657     catch( Py::Exception & )
00658         {
00659         return -1;  // indicate error
00660         }
00661     }
00662 
00663 extern "C" PyObject* mapping_subscript_handler( PyObject *self, PyObject *key )
00664     {
00665     try
00666         {
00667         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00668         return new_reference_to( p->mapping_subscript( Py::Object( key ) ) );
00669         }
00670     catch( Py::Exception & )
00671         {
00672         return NULL;    // indicate error
00673         }
00674     }
00675 
00676 extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
00677     {
00678     try
00679         {
00680         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00681         return p->mapping_ass_subscript( Py::Object( key ), Py::Object( value ) );
00682         }
00683     catch( Py::Exception & )
00684         {
00685         return -1;  // indicate error
00686         }
00687     }
00688 
00689 // Number
00690 extern "C" int number_nonzero_handler( PyObject *self )
00691     {
00692     try
00693         {
00694         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00695         return p->number_nonzero();
00696         }
00697     catch( Py::Exception & )
00698         {
00699         return -1;  // indicate error
00700         }
00701     }
00702 
00703 extern "C" PyObject* number_negative_handler( PyObject *self )
00704     {
00705     try
00706         {
00707         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00708         return new_reference_to( p->number_negative() );
00709         }
00710     catch( Py::Exception & )
00711         {
00712         return NULL;    // indicate error
00713         }
00714     }
00715 
00716 extern "C" PyObject* number_positive_handler( PyObject *self )
00717     {
00718     try
00719         {
00720         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00721         return new_reference_to( p->number_positive() );
00722         }
00723     catch( Py::Exception & )
00724         {
00725         return NULL;    // indicate error
00726         }
00727     }
00728 
00729 extern "C" PyObject* number_absolute_handler( PyObject *self )
00730     {
00731     try
00732         {
00733         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00734         return new_reference_to( p->number_absolute() );
00735         }
00736     catch( Py::Exception & )
00737         {
00738         return NULL;    // indicate error
00739         }
00740     }
00741 
00742 extern "C" PyObject* number_invert_handler( PyObject *self )
00743     {
00744     try
00745         {
00746         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00747         return new_reference_to( p->number_invert() );
00748         }
00749     catch( Py::Exception & )
00750         {
00751         return NULL;    // indicate error
00752         }
00753     }
00754 
00755 extern "C" PyObject* number_int_handler( PyObject *self )
00756     {
00757     try
00758         {
00759         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00760         return new_reference_to( p->number_int() );
00761         }
00762     catch( Py::Exception & )
00763         {
00764         return NULL;    // indicate error
00765         }
00766     }
00767 
00768 extern "C" PyObject* number_float_handler( PyObject *self )
00769     {
00770     try
00771         {
00772         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00773         return new_reference_to( p->number_float() );
00774         }
00775     catch( Py::Exception & )
00776         {
00777         return NULL;    // indicate error
00778         }
00779     }
00780 
00781 extern "C" PyObject* number_long_handler( PyObject *self )
00782     {
00783     try
00784         {
00785         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00786         return new_reference_to( p->number_long() );
00787         }
00788     catch( Py::Exception & )
00789         {
00790         return NULL;    // indicate error
00791         }
00792     }
00793 
00794 extern "C" PyObject* number_oct_handler( PyObject *self )
00795     {
00796     try
00797         {
00798         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00799         return new_reference_to( p->number_oct() );
00800         }
00801     catch( Py::Exception & )
00802         {
00803         return NULL;    // indicate error
00804         }
00805     }
00806 
00807 extern "C" PyObject* number_hex_handler( PyObject *self )
00808     {
00809     try
00810         {
00811         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00812         return new_reference_to( p->number_hex() );
00813         }
00814     catch( Py::Exception & )
00815         {
00816         return NULL;    // indicate error
00817         }
00818     }
00819 
00820 extern "C" PyObject* number_add_handler( PyObject *self, PyObject *other )
00821     {
00822     try
00823         {
00824         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00825         return new_reference_to( p->number_add( Py::Object( other ) ) );
00826         }
00827     catch( Py::Exception & )
00828         {
00829         return NULL;    // indicate error
00830         }
00831     }
00832 
00833 extern "C" PyObject* number_subtract_handler( PyObject *self, PyObject *other )
00834     {
00835     try
00836         {
00837         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00838         return new_reference_to( p->number_subtract( Py::Object( other ) ) );
00839         }
00840     catch( Py::Exception & )
00841         {
00842         return NULL;    // indicate error
00843         }
00844     }
00845 
00846 extern "C" PyObject* number_multiply_handler( PyObject *self, PyObject *other )
00847     {
00848     try
00849         {
00850         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00851         return new_reference_to( p->number_multiply( Py::Object( other ) ) );
00852         }
00853     catch( Py::Exception & )
00854         {
00855         return NULL;    // indicate error
00856         }
00857     }
00858 
00859 extern "C" PyObject* number_divide_handler( PyObject *self, PyObject *other )
00860     {
00861     try
00862         {
00863         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00864         return new_reference_to( p->number_divide( Py::Object( other ) ) );
00865         }
00866     catch( Py::Exception & )
00867         {
00868         return NULL;    // indicate error
00869         }
00870     }
00871 
00872 extern "C" PyObject* number_remainder_handler( PyObject *self, PyObject *other )
00873     {
00874     try
00875         {
00876         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00877         return new_reference_to( p->number_remainder( Py::Object( other ) ) );
00878         }
00879     catch( Py::Exception & )
00880         {
00881         return NULL;    // indicate error
00882         }
00883     }
00884 
00885 extern "C" PyObject* number_divmod_handler( PyObject *self, PyObject *other )
00886     {
00887     try
00888         {
00889         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00890         return new_reference_to( p->number_divmod( Py::Object( other ) ) );
00891         }
00892     catch( Py::Exception & )
00893         {
00894         return NULL;    // indicate error
00895         }
00896     }
00897 
00898 extern "C" PyObject* number_lshift_handler( PyObject *self, PyObject *other )
00899     {
00900     try
00901         {
00902         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00903         return new_reference_to( p->number_lshift( Py::Object( other ) ) );
00904         }
00905     catch( Py::Exception & )
00906         {
00907         return NULL;    // indicate error
00908         }
00909     }
00910 
00911 extern "C" PyObject* number_rshift_handler( PyObject *self, PyObject *other )
00912     {
00913     try
00914         {
00915         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00916         return new_reference_to( p->number_rshift( Py::Object( other ) ) );
00917         }
00918     catch( Py::Exception & )
00919         {
00920         return NULL;    // indicate error
00921         }
00922     }
00923 
00924 extern "C" PyObject* number_and_handler( PyObject *self, PyObject *other )
00925     {
00926     try
00927         {
00928         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00929         return new_reference_to( p->number_and( Py::Object( other ) ) );
00930         }
00931     catch( Py::Exception & )
00932         {
00933         return NULL;    // indicate error
00934         }
00935     }
00936 
00937 extern "C" PyObject* number_xor_handler( PyObject *self, PyObject *other )
00938     {
00939     try
00940         {
00941         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00942         return new_reference_to( p->number_xor( Py::Object( other ) ) );
00943         }
00944     catch( Py::Exception & )
00945         {
00946         return NULL;    // indicate error
00947         }
00948     }
00949 
00950 extern "C" PyObject* number_or_handler( PyObject *self, PyObject *other )
00951     {
00952     try
00953         {
00954         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00955         return new_reference_to( p->number_or( Py::Object( other ) ) );
00956         }
00957     catch( Py::Exception & )
00958         {
00959         return NULL;    // indicate error
00960         }
00961     }
00962 
00963 extern "C" PyObject* number_power_handler( PyObject *self, PyObject *x1, PyObject *x2 )
00964     {
00965     try
00966         {
00967         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00968         return new_reference_to( p->number_power( Py::Object( x1 ), Py::Object( x2 ) ) );
00969         }
00970     catch( Py::Exception & )
00971         {
00972         return NULL;    // indicate error
00973         }
00974     }
00975 
00976 // Buffer
00977 extern "C" int buffer_getreadbuffer_handler( PyObject *self, int index, void **pp )
00978     {
00979     try
00980         {
00981         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00982         return p->buffer_getreadbuffer( index, pp );
00983         }
00984     catch( Py::Exception & )
00985         {
00986         return -1;  // indicate error
00987         }
00988     }
00989 
00990 extern "C" int buffer_getwritebuffer_handler( PyObject *self, int index, void **pp )
00991     {
00992     try
00993         {
00994         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
00995         return p->buffer_getwritebuffer( index, pp );
00996         }
00997     catch( Py::Exception & )
00998         {
00999         return -1;  // indicate error
01000         }
01001     }
01002 
01003 extern "C" int buffer_getsegcount_handler( PyObject *self, int *count )
01004     {
01005     try
01006         {
01007         PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
01008         return p->buffer_getsegcount( count );
01009         }
01010     catch( Py::Exception & )
01011         {
01012         return -1;  // indicate error
01013         }
01014     }
01015 
01016 
01017 //================================================================================
01018 //
01019 //  Implementation of PythonExtensionBase
01020 //
01021 //================================================================================
01022 #define missing_method( method ) \
01023 throw RuntimeError( "Extension object does not support method " #method );
01024 
01025 PythonExtensionBase::PythonExtensionBase()
01026     {
01027     }
01028 
01029 PythonExtensionBase::~PythonExtensionBase()
01030     {
01031     assert( ob_refcnt == 0 );
01032     }
01033 
01034 int PythonExtensionBase::print( FILE *, int )
01035     { missing_method( print ); return -1; }
01036 
01037 int PythonExtensionBase::setattr( const char*, const Py::Object & )
01038     { missing_method( setattr ); return -1; }
01039 
01040 Py::Object PythonExtensionBase::getattro( const Py::Object & )
01041     { missing_method( getattro ); return Py::Nothing(); }
01042 
01043 int PythonExtensionBase::setattro( const Py::Object &, const Py::Object & )
01044     { missing_method( setattro ); return -1; }
01045 
01046 int PythonExtensionBase::compare( const Py::Object & )
01047     { missing_method( compare ); return -1; }
01048 
01049 Py::Object PythonExtensionBase::repr()
01050     { missing_method( repr ); return Py::Nothing(); }
01051 
01052 Py::Object PythonExtensionBase::str()
01053     { missing_method( str ); return Py::Nothing(); }
01054 
01055 long PythonExtensionBase::hash()
01056     { missing_method( hash ); return -1; }
01057 
01058 Py::Object PythonExtensionBase::call( const Py::Object &, const Py::Object & )
01059     { missing_method( call ); return Py::Nothing(); }
01060 
01061 
01062 // Sequence methods
01063 int PythonExtensionBase::sequence_length()
01064     { missing_method( sequence_length ); return -1; }
01065 
01066 Py::Object PythonExtensionBase::sequence_concat( const Py::Object & )
01067     { missing_method( sequence_concat ); return Py::Nothing(); }
01068 
01069 Py::Object PythonExtensionBase::sequence_repeat( int )
01070     { missing_method( sequence_repeat ); return Py::Nothing(); }
01071 
01072 Py::Object PythonExtensionBase::sequence_item( int )
01073     { missing_method( sequence_item ); return Py::Nothing(); }
01074 
01075 Py::Object PythonExtensionBase::sequence_slice( int, int )
01076     { missing_method( sequence_slice ); return Py::Nothing(); }
01077 
01078 int PythonExtensionBase::sequence_ass_item( int, const Py::Object & )
01079     { missing_method( sequence_ass_item ); return -1; }
01080 
01081 int PythonExtensionBase::sequence_ass_slice( int, int, const Py::Object & )
01082     { missing_method( sequence_ass_slice ); return -1; }
01083 
01084 
01085 // Mapping
01086 int PythonExtensionBase::mapping_length()
01087     { missing_method( mapping_length ); return -1; }
01088 
01089 Py::Object PythonExtensionBase::mapping_subscript( const Py::Object & )
01090     { missing_method( mapping_subscript ); return Py::Nothing(); }
01091 
01092 int PythonExtensionBase::mapping_ass_subscript( const Py::Object &, const Py::Object & )
01093     { missing_method( mapping_ass_subscript ); return -1; }
01094 
01095 
01096 // Number
01097 int PythonExtensionBase::number_nonzero()
01098     { missing_method( number_nonzero ); return -1; }
01099 
01100 Py::Object PythonExtensionBase::number_negative()
01101     { missing_method( number_negative ); return Py::Nothing(); }
01102 
01103 Py::Object PythonExtensionBase::number_positive()
01104     { missing_method( number_positive ); return Py::Nothing(); }
01105 
01106 Py::Object PythonExtensionBase::number_absolute()
01107     { missing_method( number_absolute ); return Py::Nothing(); }
01108 
01109 Py::Object PythonExtensionBase::number_invert()
01110     { missing_method( number_invert ); return Py::Nothing(); }
01111 
01112 Py::Object PythonExtensionBase::number_int()
01113     { missing_method( number_int ); return Py::Nothing(); }
01114 
01115 Py::Object PythonExtensionBase::number_float()
01116     { missing_method( number_float ); return Py::Nothing(); }
01117 
01118 Py::Object PythonExtensionBase::number_long()
01119     { missing_method( number_long ); return Py::Nothing(); }
01120 
01121 Py::Object PythonExtensionBase::number_oct()
01122     { missing_method( number_oct ); return Py::Nothing(); }
01123 
01124 Py::Object PythonExtensionBase::number_hex()
01125     { missing_method( number_hex ); return Py::Nothing(); }
01126 
01127 Py::Object PythonExtensionBase::number_add( const Py::Object & )
01128     { missing_method( number_add ); return Py::Nothing(); }
01129 
01130 Py::Object PythonExtensionBase::number_subtract( const Py::Object & )
01131     { missing_method( number_subtract ); return Py::Nothing(); }
01132 
01133 Py::Object PythonExtensionBase::number_multiply( const Py::Object & )
01134     { missing_method( number_multiply ); return Py::Nothing(); }
01135 
01136 Py::Object PythonExtensionBase::number_divide( const Py::Object & )
01137     { missing_method( number_divide ); return Py::Nothing(); }
01138 
01139 Py::Object PythonExtensionBase::number_remainder( const Py::Object & )
01140     { missing_method( number_remainder ); return Py::Nothing(); }
01141 
01142 Py::Object PythonExtensionBase::number_divmod( const Py::Object & )
01143     { missing_method( number_divmod ); return Py::Nothing(); }
01144 
01145 Py::Object PythonExtensionBase::number_lshift( const Py::Object & )
01146     { missing_method( number_lshift ); return Py::Nothing(); }
01147 
01148 Py::Object PythonExtensionBase::number_rshift( const Py::Object & )
01149     { missing_method( number_rshift ); return Py::Nothing(); }
01150 
01151 Py::Object PythonExtensionBase::number_and( const Py::Object & )
01152     { missing_method( number_and ); return Py::Nothing(); }
01153 
01154 Py::Object PythonExtensionBase::number_xor( const Py::Object & )
01155     { missing_method( number_xor ); return Py::Nothing(); }
01156 
01157 Py::Object PythonExtensionBase::number_or( const Py::Object & )
01158     { missing_method( number_or ); return Py::Nothing(); }
01159 
01160 Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Object & )
01161     { missing_method( number_power ); return Py::Nothing(); }
01162 
01163 
01164 // Buffer
01165 int PythonExtensionBase::buffer_getreadbuffer( int, void** )
01166     { missing_method( buffer_getreadbuffer ); return -1; }
01167 
01168 int PythonExtensionBase::buffer_getwritebuffer( int, void** )
01169     { missing_method( buffer_getwritebuffer ); return -1; }
01170 
01171 int PythonExtensionBase::buffer_getsegcount( int* )
01172     { missing_method( buffer_getsegcount ); return -1; }
01173 
01174 //--------------------------------------------------------------------------------
01175 //
01176 //  Method call handlers for
01177 //      PythonExtensionBase
01178 //      ExtensionModuleBase
01179 //
01180 //--------------------------------------------------------------------------------
01181 
01182 extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
01183     {
01184     try
01185         {
01186         Tuple self_and_name_tuple( _self_and_name_tuple );
01187 
01188         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01189         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01190         if( self_as_void == NULL )
01191         return NULL;
01192 
01193         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01194 
01195         String py_name( self_and_name_tuple[1] );
01196         std::string name( py_name.as_std_string() );
01197 
01198         Tuple args( _args );
01199         if( _keywords == NULL )
01200             {
01201             Dict keywords;  // pass an empty dict
01202 
01203             Object result( self->invoke_method_keyword( name, args, keywords ) );
01204             return new_reference_to( result.ptr() );
01205             }
01206         else
01207             {
01208             Dict keywords( _keywords );
01209 
01210             Object result( self->invoke_method_keyword( name, args, keywords ) );
01211             return new_reference_to( result.ptr() );
01212             }
01213         }
01214     catch( Exception & )
01215         {
01216         return 0;
01217         }
01218     }
01219 
01220 extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
01221     {
01222     try
01223         {
01224         Tuple self_and_name_tuple( _self_and_name_tuple );
01225 
01226         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
01227         void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
01228         if( self_as_void == NULL )
01229         return NULL;
01230 
01231         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
01232 
01233         String py_name( self_and_name_tuple[1] );
01234         std::string name( py_name.as_std_string() );
01235 
01236         Tuple args( _args );
01237 
01238         Object result( self->invoke_method_varargs( name, args ) );
01239 
01240         return new_reference_to( result.ptr() );
01241         }
01242     catch( Exception & )
01243         {
01244         return 0;
01245         }
01246     }
01247 
01248 extern "C" void do_not_dealloc( void * )
01249     {}
01250 
01251 
01252 //--------------------------------------------------------------------------------
01253 //
01254 //  ExtensionExceptionType
01255 //
01256 //--------------------------------------------------------------------------------
01257 ExtensionExceptionType::ExtensionExceptionType()
01258     : Py::Object()
01259     {
01260     }
01261 
01262 void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
01263     {
01264     std::string module_name( module.fullName() );
01265     module_name += ".";
01266     module_name += name;
01267 
01268     set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
01269     }
01270 
01271 ExtensionExceptionType::~ExtensionExceptionType()
01272     {
01273     }
01274 
01275 Exception::Exception( ExtensionExceptionType &exception, const std::string& reason )
01276     {
01277     PyErr_SetString (exception.ptr(), reason.c_str());
01278     }
01279 
01280 
01281 }   // end of namespace Py
KDE Home | KDE Accessibility Home | Description of Access Keys