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