1
//-----------------------------------------------------------------------------
3
// Copyright (c) 1998 - 2007, The Regents of the University of California
4
// Produced at the Lawrence Livermore National Laboratory
7
// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
8
// full copyright notice is contained in the file COPYRIGHT located at the root
9
// of the PyCXX distribution.
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are met:
14
// - Redistributions of source code must retain the above copyright notice,
15
// this list of conditions and the disclaimer below.
16
// - Redistributions in binary form must reproduce the above copyright notice,
17
// this list of conditions and the disclaimer (as noted below) in the
18
// documentation and/or materials provided with the distribution.
19
// - Neither the name of the UC/LLNL nor the names of its contributors may be
20
// used to endorse or promote products derived from this software without
21
// specific prior written permission.
23
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
27
// CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR
28
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
36
//-----------------------------------------------------------------------------
37
#include "CXX/Extensions.hxx"
38
#include "CXX/Exception.hxx"
43
// Functions useful when debugging PyCXX
49
void printRefCount( PyObject *obj )
51
std::cout << "RefCount of 0x" << std::hex << reinterpret_cast< unsigned int >( obj ) << std::dec << " is " << Py_REFCNT( obj ) << std::endl;
57
#ifdef PYCXX_PYTHON_2TO3
58
std::string String::as_std_string( const char *encoding, const char *error ) const
62
Bytes encoded( encode( encoding, error ) );
63
return encoded.as_std_string();
67
return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
71
Bytes String::encode( const char *encoding, const char *error ) const
75
return Bytes( PyUnicode_AsEncodedString( ptr(), encoding, error ) );
79
return Bytes( PyString_AsEncodedObject( ptr(), encoding, error ) );
84
std::string String::as_std_string( const char *encoding, const char *error ) const
88
String encoded( encode( encoding, error ) );
89
return encoded.as_std_string();
93
return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
98
void Object::validate()
100
// release pointer if not the right type
103
#if defined( _CPPRTTI ) || defined( __GNUG__ )
104
std::string s( "PyCXX: Error creating object of type " );
105
s += (typeid( *this )).name();
109
String from_repr = repr();
111
s += from_repr.as_std_string( "utf-8" );
119
if( PyErr_Occurred() )
120
{ // Error message already set
123
// Better error message if RTTI available
124
#if defined( _CPPRTTI ) || defined( __GNUG__ )
125
throw TypeError( s );
127
throw TypeError( "PyCXX: type error." );
132
//================================================================================
134
// Implementation of MethodTable
136
//================================================================================
137
PyMethodDef MethodTable::method( const char *method_name, PyCFunction f, int flags, const char *doc )
140
m.ml_name = const_cast<char*>( method_name );
143
m.ml_doc = const_cast<char*>( doc );
147
MethodTable::MethodTable()
149
t.push_back( method( 0, 0, 0, 0 ) );
153
MethodTable::~MethodTable()
158
void MethodTable::add( const char *method_name, PyCFunction f, const char *doc, int flag )
162
t.insert( t.end()-1, method( method_name, f, flag, doc ) );
166
throw RuntimeError( "Too late to add a module method!" );
170
PyMethodDef *MethodTable::table()
174
Py_ssize_t t1size = t.size();
175
mt = new PyMethodDef[ t1size ];
177
for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
185
//================================================================================
187
// Implementation of ExtensionModule
189
//================================================================================
190
ExtensionModuleBase::ExtensionModuleBase( const char *name )
191
: m_module_name( name )
192
, m_full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : m_module_name )
197
ExtensionModuleBase::~ExtensionModuleBase()
200
const std::string &ExtensionModuleBase::name() const
202
return m_module_name;
205
const std::string &ExtensionModuleBase::fullName() const
207
return m_full_module_name;
210
class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
213
ExtensionModuleBasePtr( ExtensionModuleBase *_module )
217
virtual ~ExtensionModuleBasePtr()
220
ExtensionModuleBase *module;
223
void ExtensionModuleBase::initialize( const char *module_doc )
225
PyObject *module_ptr = new ExtensionModuleBasePtr( this );
226
m_module = Py_InitModule4
228
const_cast<char *>( m_module_name.c_str() ), // name
229
m_method_table.table(), // methods
230
const_cast<char *>( module_doc ), // docs
231
module_ptr, // pass to functions as "self"
232
PYTHON_API_VERSION // API version
236
Py::Module ExtensionModuleBase::module( void ) const
238
return Module( m_full_module_name );
241
Py::Dict ExtensionModuleBase::moduleDictionary( void ) const
243
return module().getDict();
246
Object ExtensionModuleBase::moduleObject( void ) const
248
return Object( m_module );
251
//================================================================================
253
// Implementation of PythonType
255
//================================================================================
258
static void standard_dealloc( PyObject *p );
260
// All the following functions redirect the call from Python
261
// onto the matching virtual function in PythonExtensionBase
263
#if defined( PYCXX_PYTHON_2TO3 )
264
static int print_handler( PyObject *, FILE *, int );
266
static PyObject *getattr_handler( PyObject *, char * );
267
static int setattr_handler( PyObject *, char *, PyObject * );
268
static PyObject *getattro_handler( PyObject *, PyObject * );
269
static int setattro_handler( PyObject *, PyObject *, PyObject * );
270
#if defined( PYCXX_PYTHON_2TO3 )
271
static int compare_handler( PyObject *, PyObject * );
273
static PyObject *rich_compare_handler( PyObject *, PyObject *, int );
274
static PyObject *repr_handler( PyObject * );
275
static PyObject *str_handler( PyObject * );
276
static long hash_handler( PyObject * );
277
static PyObject *call_handler( PyObject *, PyObject *, PyObject * );
278
static PyObject *iter_handler( PyObject * );
279
static PyObject *iternext_handler( PyObject * );
282
static Py_ssize_t sequence_length_handler( PyObject * );
283
static PyObject *sequence_concat_handler( PyObject *,PyObject * );
284
static PyObject *sequence_repeat_handler( PyObject *, Py_ssize_t );
285
static PyObject *sequence_item_handler( PyObject *, Py_ssize_t );
286
static PyObject *sequence_slice_handler( PyObject *, Py_ssize_t, Py_ssize_t );
287
static int sequence_ass_item_handler( PyObject *, Py_ssize_t, PyObject * );
288
static int sequence_ass_slice_handler( PyObject *, Py_ssize_t, Py_ssize_t, PyObject * );
291
static Py_ssize_t mapping_length_handler( PyObject * );
292
static PyObject *mapping_subscript_handler( PyObject *, PyObject * );
293
static int mapping_ass_subscript_handler( PyObject *, PyObject *, PyObject * );
296
static int number_nonzero_handler( PyObject * );
297
static PyObject *number_negative_handler( PyObject * );
298
static PyObject *number_positive_handler( PyObject * );
299
static PyObject *number_absolute_handler( PyObject * );
300
static PyObject *number_invert_handler( PyObject * );
301
static PyObject *number_int_handler( PyObject * );
302
static PyObject *number_float_handler( PyObject * );
303
static PyObject *number_long_handler( PyObject * );
304
static PyObject *number_oct_handler( PyObject * );
305
static PyObject *number_hex_handler( PyObject * );
306
static PyObject *number_add_handler( PyObject *, PyObject * );
307
static PyObject *number_subtract_handler( PyObject *, PyObject * );
308
static PyObject *number_multiply_handler( PyObject *, PyObject * );
309
static PyObject *number_divide_handler( PyObject *, PyObject * );
310
static PyObject *number_remainder_handler( PyObject *, PyObject * );
311
static PyObject *number_divmod_handler( PyObject *, PyObject * );
312
static PyObject *number_lshift_handler( PyObject *, PyObject * );
313
static PyObject *number_rshift_handler( PyObject *, PyObject * );
314
static PyObject *number_and_handler( PyObject *, PyObject * );
315
static PyObject *number_xor_handler( PyObject *, PyObject * );
316
static PyObject *number_or_handler( PyObject *, PyObject * );
317
static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * );
320
static Py_ssize_t buffer_getreadbuffer_handler( PyObject *, Py_ssize_t, void ** );
321
static Py_ssize_t buffer_getwritebuffer_handler( PyObject *, Py_ssize_t, void ** );
322
static Py_ssize_t buffer_getsegcount_handler( PyObject *, Py_ssize_t * );
325
extern "C" void standard_dealloc( PyObject *p )
330
bool PythonType::readyType()
332
return PyType_Ready( table ) >= 0;
335
PythonType &PythonType::supportSequenceType()
337
if( !sequence_table )
339
sequence_table = new PySequenceMethods;
340
memset( sequence_table, 0, sizeof( PySequenceMethods ) ); // ensure new fields are 0
341
table->tp_as_sequence = sequence_table;
342
sequence_table->sq_length = sequence_length_handler;
343
sequence_table->sq_concat = sequence_concat_handler;
344
sequence_table->sq_repeat = sequence_repeat_handler;
345
sequence_table->sq_item = sequence_item_handler;
346
sequence_table->sq_slice = sequence_slice_handler;
347
sequence_table->sq_ass_item = sequence_ass_item_handler; // BAS setup separately?
348
sequence_table->sq_ass_slice = sequence_ass_slice_handler; // BAS setup separately?
353
PythonType &PythonType::supportMappingType()
357
mapping_table = new PyMappingMethods;
358
memset( mapping_table, 0, sizeof( PyMappingMethods ) ); // ensure new fields are 0
359
table->tp_as_mapping = mapping_table;
360
mapping_table->mp_length = mapping_length_handler;
361
mapping_table->mp_subscript = mapping_subscript_handler;
362
mapping_table->mp_ass_subscript = mapping_ass_subscript_handler; // BAS setup separately?
367
PythonType &PythonType::supportNumberType()
371
number_table = new PyNumberMethods;
372
memset( number_table, 0, sizeof( PyNumberMethods ) ); // ensure new fields are 0
373
table->tp_as_number = number_table;
374
number_table->nb_add = number_add_handler;
375
number_table->nb_subtract = number_subtract_handler;
376
number_table->nb_multiply = number_multiply_handler;
377
number_table->nb_divide = number_divide_handler;
378
number_table->nb_remainder = number_remainder_handler;
379
number_table->nb_divmod = number_divmod_handler;
380
number_table->nb_power = number_power_handler;
381
number_table->nb_negative = number_negative_handler;
382
number_table->nb_positive = number_positive_handler;
383
number_table->nb_absolute = number_absolute_handler;
384
number_table->nb_nonzero = number_nonzero_handler;
385
number_table->nb_invert = number_invert_handler;
386
number_table->nb_lshift = number_lshift_handler;
387
number_table->nb_rshift = number_rshift_handler;
388
number_table->nb_and = number_and_handler;
389
number_table->nb_xor = number_xor_handler;
390
number_table->nb_or = number_or_handler;
391
number_table->nb_coerce = 0;
392
number_table->nb_int = number_int_handler;
393
number_table->nb_long = number_long_handler;
394
number_table->nb_float = number_float_handler;
395
number_table->nb_oct = number_oct_handler;
396
number_table->nb_hex = number_hex_handler;
401
PythonType &PythonType::supportBufferType()
405
buffer_table = new PyBufferProcs;
406
memset( buffer_table, 0, sizeof( PyBufferProcs ) ); // ensure new fields are 0
407
table->tp_as_buffer = buffer_table;
408
buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
409
buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
410
buffer_table->bf_getsegcount = buffer_getsegcount_handler;
415
// if you define one sequence method you must define
416
// all of them except the assigns
418
PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
419
: table( new PyTypeObject )
420
, sequence_table( NULL )
421
, mapping_table( NULL )
422
, number_table( NULL )
423
, buffer_table( NULL )
425
// PyTypeObject is defined in <python-sources>/Include/object.h
427
memset( table, 0, sizeof( PyTypeObject ) ); // ensure new fields are 0
428
*reinterpret_cast<PyObject *>( table ) = py_object_initializer;
429
table->ob_type = _Type_Type();
432
table->tp_name = const_cast<char *>( default_name );
433
table->tp_basicsize = basic_size;
434
table->tp_itemsize = itemsize;
436
// Methods to implement standard operations
437
table->tp_dealloc = (destructor)standard_dealloc;
439
table->tp_getattr = 0;
440
table->tp_setattr = 0;
441
table->tp_compare = 0;
444
// Method suites for standard classes
445
table->tp_as_number = 0;
446
table->tp_as_sequence = 0;
447
table->tp_as_mapping = 0;
449
// More standard operations (here for binary compatibility)
453
table->tp_getattro = 0;
454
table->tp_setattro = 0;
456
// Functions to access object as input/output buffer
457
table->tp_as_buffer = 0;
459
// Flags to define presence of optional/expanded features
460
table->tp_flags = Py_TPFLAGS_DEFAULT;
462
// Documentation string
465
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
466
table->tp_traverse = 0L;
468
// delete references to contained objects
469
table->tp_clear = 0L;
474
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
475
// first defined in 2.1
476
table->tp_richcompare = 0L;
477
// weak reference enabler
478
table->tp_weaklistoffset = 0L;
483
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 2)
484
// first defined in 2.3
487
table->tp_iternext = 0L;
492
table->tp_maxalloc = 0;
497
PythonType::~PythonType()
500
delete sequence_table;
501
delete mapping_table;
506
PyTypeObject *PythonType::type_object() const
511
PythonType &PythonType::name( const char *nam )
513
table->tp_name = const_cast<char *>( nam );
517
const char *PythonType::getName() const
519
return table->tp_name;
522
PythonType &PythonType::doc( const char *d )
524
table->tp_doc = const_cast<char *>( d );
528
const char *PythonType::getDoc() const
530
return table->tp_doc;
533
PythonType &PythonType::set_tp_dealloc( void (*tp_dealloc)( PyObject *self ) )
535
table->tp_dealloc = tp_dealloc;
539
PythonType &PythonType::set_tp_init( int (*tp_init)( PyObject *self, PyObject *args, PyObject *kwds ) )
541
table->tp_init = tp_init;
545
PythonType &PythonType::set_tp_new( PyObject *(*tp_new)( PyTypeObject *subtype, PyObject *args, PyObject *kwds ) )
547
table->tp_new = tp_new;
551
PythonType &PythonType::set_methods( PyMethodDef *methods )
553
table->tp_methods = methods;
557
PythonType &PythonType::supportClass()
559
table->tp_flags |= Py_TPFLAGS_BASETYPE;
563
PythonType &PythonType::dealloc( void( *f )( PyObject * ))
565
table->tp_dealloc = f;
569
#if defined( PYCXX_PYTHON_2TO3 )
570
PythonType &PythonType::supportPrint()
572
table->tp_print = print_handler;
577
PythonType &PythonType::supportGetattr()
579
table->tp_getattr = getattr_handler;
583
PythonType &PythonType::supportSetattr()
585
table->tp_setattr = setattr_handler;
589
PythonType &PythonType::supportGetattro()
591
table->tp_getattro = getattro_handler;
595
PythonType &PythonType::supportSetattro()
597
table->tp_setattro = setattro_handler;
601
#if defined( PYCXX_PYTHON_2TO3 )
602
PythonType &PythonType::supportCompare()
604
table->tp_compare = compare_handler;
609
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
610
PythonType &PythonType::supportRichCompare()
612
table->tp_richcompare = rich_compare_handler;
617
PythonType &PythonType::supportRepr()
619
table->tp_repr = repr_handler;
623
PythonType &PythonType::supportStr()
625
table->tp_str = str_handler;
629
PythonType &PythonType::supportHash()
631
table->tp_hash = hash_handler;
635
PythonType &PythonType::supportCall()
637
table->tp_call = call_handler;
641
PythonType &PythonType::supportIter()
643
table->tp_iter = iter_handler;
644
table->tp_iternext = iternext_handler;
648
//--------------------------------------------------------------------------------
652
//--------------------------------------------------------------------------------
653
PYCXX_EXPORT PythonExtensionBase *getPythonExtensionBase( PyObject *self )
655
if( self->ob_type->tp_flags&Py_TPFLAGS_BASETYPE )
657
PythonClassInstance *instance = reinterpret_cast<PythonClassInstance *>( self );
658
return instance->m_pycxx_object;
662
return static_cast<PythonExtensionBase *>( self );
667
#if defined( PYCXX_PYTHON_2TO3 )
668
extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
672
PythonExtensionBase *p = getPythonExtensionBase( self );
673
return p->print( fp, flags );
675
catch( Py::Exception &)
677
return -1; // indicate error
682
extern "C" PyObject *getattr_handler( PyObject *self, char *name )
686
PythonExtensionBase *p = getPythonExtensionBase( self );
687
return new_reference_to( p->getattr( name ) );
689
catch( Py::Exception &)
691
return NULL; // indicate error
695
extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
699
PythonExtensionBase *p = getPythonExtensionBase( self );
700
return p->setattr( name, Py::Object( value ) );
702
catch( Py::Exception &)
704
return -1; // indicate error
708
extern "C" PyObject *getattro_handler( PyObject *self, PyObject *name )
712
PythonExtensionBase *p = getPythonExtensionBase( self );
713
return new_reference_to( p->getattro( Py::String( name ) ) );
715
catch( Py::Exception &)
717
return NULL; // indicate error
721
extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
725
PythonExtensionBase *p = getPythonExtensionBase( self );
726
return p->setattro( Py::String( name ), Py::Object( value ) );
728
catch( Py::Exception &)
730
return -1; // indicate error
734
#if defined( PYCXX_PYTHON_2TO3 )
735
extern "C" int compare_handler( PyObject *self, PyObject *other )
739
PythonExtensionBase *p = getPythonExtensionBase( self );
740
return p->compare( Py::Object( other ) );
742
catch( Py::Exception &)
744
return -1; // indicate error
749
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
750
extern "C" PyObject *rich_compare_handler( PyObject *self, PyObject *other, int op )
754
PythonExtensionBase *p = getPythonExtensionBase( self );
755
return new_reference_to( p->rich_compare( Py::Object( other ), op ) );
757
catch( Py::Exception &)
759
return NULL; // indicate error
764
extern "C" PyObject *repr_handler( PyObject *self )
768
PythonExtensionBase *p = getPythonExtensionBase( self );
769
return new_reference_to( p->repr() );
771
catch( Py::Exception &)
773
return NULL; // indicate error
777
extern "C" PyObject *str_handler( PyObject *self )
781
PythonExtensionBase *p = getPythonExtensionBase( self );
782
return new_reference_to( p->str() );
784
catch( Py::Exception &)
786
return NULL; // indicate error
790
extern "C" long hash_handler( PyObject *self )
794
PythonExtensionBase *p = getPythonExtensionBase( self );
797
catch( Py::Exception &)
799
return -1; // indicate error
803
extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
807
PythonExtensionBase *p = getPythonExtensionBase( self );
809
return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
811
return new_reference_to( p->call( Py::Object( args ), Py::Object() ) );
813
catch( Py::Exception &)
815
return NULL; // indicate error
819
extern "C" PyObject *iter_handler( PyObject *self )
823
PythonExtensionBase *p = getPythonExtensionBase( self );
824
return new_reference_to( p->iter() );
826
catch( Py::Exception &)
828
return NULL; // indicate error
832
extern "C" PyObject *iternext_handler( PyObject *self )
836
PythonExtensionBase *p = getPythonExtensionBase( self );
837
return p->iternext(); // might be a NULL ptr on end of iteration
839
catch( Py::Exception &)
841
return NULL; // indicate error
846
extern "C" Py_ssize_t sequence_length_handler( PyObject *self )
850
PythonExtensionBase *p = getPythonExtensionBase( self );
851
return p->sequence_length();
853
catch( Py::Exception &)
855
return -1; // indicate error
859
extern "C" PyObject *sequence_concat_handler( PyObject *self, PyObject *other )
863
PythonExtensionBase *p = getPythonExtensionBase( self );
864
return new_reference_to( p->sequence_concat( Py::Object( other ) ) );
866
catch( Py::Exception &)
868
return NULL; // indicate error
872
extern "C" PyObject *sequence_repeat_handler( PyObject *self, Py_ssize_t count )
876
PythonExtensionBase *p = getPythonExtensionBase( self );
877
return new_reference_to( p->sequence_repeat( count ) );
879
catch( Py::Exception &)
881
return NULL; // indicate error
885
extern "C" PyObject *sequence_item_handler( PyObject *self, Py_ssize_t index )
889
PythonExtensionBase *p = getPythonExtensionBase( self );
890
return new_reference_to( p->sequence_item( index ) );
892
catch( Py::Exception &)
894
return NULL; // indicate error
898
extern "C" PyObject *sequence_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last )
902
PythonExtensionBase *p = getPythonExtensionBase( self );
903
return new_reference_to( p->sequence_slice( first, last ) );
905
catch( Py::Exception &)
907
return NULL; // indicate error
911
extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value )
915
PythonExtensionBase *p = getPythonExtensionBase( self );
916
return p->sequence_ass_item( index, Py::Object( value ) );
918
catch( Py::Exception &)
920
return -1; // indicate error
924
extern "C" int sequence_ass_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *value )
928
PythonExtensionBase *p = getPythonExtensionBase( self );
929
return p->sequence_ass_slice( first, last, Py::Object( value ) );
931
catch( Py::Exception &)
933
return -1; // indicate error
938
extern "C" Py_ssize_t mapping_length_handler( PyObject *self )
942
PythonExtensionBase *p = getPythonExtensionBase( self );
943
return p->mapping_length();
945
catch( Py::Exception &)
947
return -1; // indicate error
951
extern "C" PyObject *mapping_subscript_handler( PyObject *self, PyObject *key )
955
PythonExtensionBase *p = getPythonExtensionBase( self );
956
return new_reference_to( p->mapping_subscript( Py::Object( key ) ) );
958
catch( Py::Exception &)
960
return NULL; // indicate error
964
extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
968
PythonExtensionBase *p = getPythonExtensionBase( self );
969
return p->mapping_ass_subscript( Py::Object( key ), Py::Object( value ) );
971
catch( Py::Exception &)
973
return -1; // indicate error
978
extern "C" int number_nonzero_handler( PyObject *self )
982
PythonExtensionBase *p = getPythonExtensionBase( self );
983
return p->number_nonzero();
985
catch( Py::Exception &)
987
return -1; // indicate error
991
extern "C" PyObject *number_negative_handler( PyObject *self )
995
PythonExtensionBase *p = getPythonExtensionBase( self );
996
return new_reference_to( p->number_negative() );
998
catch( Py::Exception &)
1000
return NULL; // indicate error
1004
extern "C" PyObject *number_positive_handler( PyObject *self )
1008
PythonExtensionBase *p = getPythonExtensionBase( self );
1009
return new_reference_to( p->number_positive() );
1011
catch( Py::Exception &)
1013
return NULL; // indicate error
1017
extern "C" PyObject *number_absolute_handler( PyObject *self )
1021
PythonExtensionBase *p = getPythonExtensionBase( self );
1022
return new_reference_to( p->number_absolute() );
1024
catch( Py::Exception &)
1026
return NULL; // indicate error
1030
extern "C" PyObject *number_invert_handler( PyObject *self )
1034
PythonExtensionBase *p = getPythonExtensionBase( self );
1035
return new_reference_to( p->number_invert() );
1037
catch( Py::Exception &)
1039
return NULL; // indicate error
1043
extern "C" PyObject *number_int_handler( PyObject *self )
1047
PythonExtensionBase *p = getPythonExtensionBase( self );
1048
return new_reference_to( p->number_int() );
1050
catch( Py::Exception &)
1052
return NULL; // indicate error
1056
extern "C" PyObject *number_float_handler( PyObject *self )
1060
PythonExtensionBase *p = getPythonExtensionBase( self );
1061
return new_reference_to( p->number_float() );
1063
catch( Py::Exception &)
1065
return NULL; // indicate error
1069
extern "C" PyObject *number_long_handler( PyObject *self )
1073
PythonExtensionBase *p = getPythonExtensionBase( self );
1074
return new_reference_to( p->number_long() );
1076
catch( Py::Exception &)
1078
return NULL; // indicate error
1082
extern "C" PyObject *number_oct_handler( PyObject *self )
1086
PythonExtensionBase *p = getPythonExtensionBase( self );
1087
return new_reference_to( p->number_oct() );
1089
catch( Py::Exception &)
1091
return NULL; // indicate error
1095
extern "C" PyObject *number_hex_handler( PyObject *self )
1099
PythonExtensionBase *p = getPythonExtensionBase( self );
1100
return new_reference_to( p->number_hex() );
1102
catch( Py::Exception &)
1104
return NULL; // indicate error
1108
extern "C" PyObject *number_add_handler( PyObject *self, PyObject *other )
1112
PythonExtensionBase *p = getPythonExtensionBase( self );
1113
return new_reference_to( p->number_add( Py::Object( other ) ) );
1115
catch( Py::Exception &)
1117
return NULL; // indicate error
1121
extern "C" PyObject *number_subtract_handler( PyObject *self, PyObject *other )
1125
PythonExtensionBase *p = getPythonExtensionBase( self );
1126
return new_reference_to( p->number_subtract( Py::Object( other ) ) );
1128
catch( Py::Exception &)
1130
return NULL; // indicate error
1134
extern "C" PyObject *number_multiply_handler( PyObject *self, PyObject *other )
1138
PythonExtensionBase *p = getPythonExtensionBase( self );
1139
return new_reference_to( p->number_multiply( Py::Object( other ) ) );
1141
catch( Py::Exception &)
1143
return NULL; // indicate error
1147
extern "C" PyObject *number_divide_handler( PyObject *self, PyObject *other )
1151
PythonExtensionBase *p = getPythonExtensionBase( self );
1152
return new_reference_to( p->number_divide( Py::Object( other ) ) );
1154
catch( Py::Exception &)
1156
return NULL; // indicate error
1160
extern "C" PyObject *number_remainder_handler( PyObject *self, PyObject *other )
1164
PythonExtensionBase *p = getPythonExtensionBase( self );
1165
return new_reference_to( p->number_remainder( Py::Object( other ) ) );
1167
catch( Py::Exception &)
1169
return NULL; // indicate error
1173
extern "C" PyObject *number_divmod_handler( PyObject *self, PyObject *other )
1177
PythonExtensionBase *p = getPythonExtensionBase( self );
1178
return new_reference_to( p->number_divmod( Py::Object( other ) ) );
1180
catch( Py::Exception &)
1182
return NULL; // indicate error
1186
extern "C" PyObject *number_lshift_handler( PyObject *self, PyObject *other )
1190
PythonExtensionBase *p = getPythonExtensionBase( self );
1191
return new_reference_to( p->number_lshift( Py::Object( other ) ) );
1193
catch( Py::Exception &)
1195
return NULL; // indicate error
1199
extern "C" PyObject *number_rshift_handler( PyObject *self, PyObject *other )
1203
PythonExtensionBase *p = getPythonExtensionBase( self );
1204
return new_reference_to( p->number_rshift( Py::Object( other ) ) );
1206
catch( Py::Exception &)
1208
return NULL; // indicate error
1212
extern "C" PyObject *number_and_handler( PyObject *self, PyObject *other )
1216
PythonExtensionBase *p = getPythonExtensionBase( self );
1217
return new_reference_to( p->number_and( Py::Object( other ) ) );
1219
catch( Py::Exception &)
1221
return NULL; // indicate error
1225
extern "C" PyObject *number_xor_handler( PyObject *self, PyObject *other )
1229
PythonExtensionBase *p = getPythonExtensionBase( self );
1230
return new_reference_to( p->number_xor( Py::Object( other ) ) );
1232
catch( Py::Exception &)
1234
return NULL; // indicate error
1238
extern "C" PyObject *number_or_handler( PyObject *self, PyObject *other )
1242
PythonExtensionBase *p = getPythonExtensionBase( self );
1243
return new_reference_to( p->number_or( Py::Object( other ) ) );
1245
catch( Py::Exception &)
1247
return NULL; // indicate error
1251
extern "C" PyObject *number_power_handler( PyObject *self, PyObject *x1, PyObject *x2 )
1255
PythonExtensionBase *p = getPythonExtensionBase( self );
1256
return new_reference_to( p->number_power( Py::Object( x1 ), Py::Object( x2 ) ) );
1258
catch( Py::Exception &)
1260
return NULL; // indicate error
1265
extern "C" Py_ssize_t buffer_getreadbuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
1269
PythonExtensionBase *p = getPythonExtensionBase( self );
1270
return p->buffer_getreadbuffer( index, pp );
1272
catch( Py::Exception &)
1274
return -1; // indicate error
1278
extern "C" Py_ssize_t buffer_getwritebuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
1282
PythonExtensionBase *p = getPythonExtensionBase( self );
1283
return p->buffer_getwritebuffer( index, pp );
1285
catch( Py::Exception &)
1287
return -1; // indicate error
1291
extern "C" Py_ssize_t buffer_getsegcount_handler( PyObject *self, Py_ssize_t *count )
1295
PythonExtensionBase *p = getPythonExtensionBase( self );
1296
return p->buffer_getsegcount( count );
1298
catch( Py::Exception &)
1300
return -1; // indicate error
1304
//================================================================================
1306
// Implementation of PythonExtensionBase
1308
//================================================================================
1309
#define missing_method( method ) \
1310
throw RuntimeError( "Extension object missing implement of " #method );
1312
PythonExtensionBase::PythonExtensionBase()
1317
PythonExtensionBase::~PythonExtensionBase()
1319
assert( ob_refcnt == 0 );
1322
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name )
1325
return self().callMemberFunction( fn_name, args );
1328
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1329
const Py::Object &arg1 )
1331
Py::TupleN args( arg1 );
1332
return self().callMemberFunction( fn_name, args );
1335
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1336
const Py::Object &arg1, const Py::Object &arg2 )
1338
Py::TupleN args( arg1, arg2 );
1339
return self().callMemberFunction( fn_name, args );
1342
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1343
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3 )
1345
Py::TupleN args( arg1, arg2, arg3 );
1346
return self().callMemberFunction( fn_name, args );
1349
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1350
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1351
const Py::Object &arg4 )
1353
Py::TupleN args( arg1, arg2, arg3, arg4 );
1354
return self().callMemberFunction( fn_name, args );
1357
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1358
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1359
const Py::Object &arg4, const Py::Object &arg5 )
1361
Py::TupleN args( arg1, arg2, arg3, arg4, arg5 );
1362
return self().callMemberFunction( fn_name, args );
1365
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1366
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1367
const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6 )
1369
Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 );
1370
return self().callMemberFunction( fn_name, args );
1373
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1374
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1375
const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
1376
const Py::Object &arg7 )
1378
Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
1379
return self().callMemberFunction( fn_name, args );
1382
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1383
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1384
const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
1385
const Py::Object &arg7, const Py::Object &arg8 )
1387
Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 );
1388
return self().callMemberFunction( fn_name, args );
1391
Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1392
const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3,
1393
const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6,
1394
const Py::Object &arg7, const Py::Object &arg8, const Py::Object &arg9 )
1396
Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 );
1397
return self().callMemberFunction( fn_name, args );
1400
void PythonExtensionBase::reinit( Tuple & /*args*/, Dict & /*kwds*/ )
1402
throw RuntimeError( "Must not call __init__ twice on this class" );
1405
Py::Object PythonExtensionBase::genericGetAttro( const Py::String &name )
1407
return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) );
1410
int PythonExtensionBase::genericSetAttro( const Py::String &name, const Py::Object &value )
1412
return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() );
1415
int PythonExtensionBase::print( FILE *, int )
1417
missing_method( print );
1421
Py::Object PythonExtensionBase::getattr( const char * )
1423
missing_method( getattr );
1427
int PythonExtensionBase::setattr( const char *, const Py::Object &)
1429
missing_method( setattr );
1433
Py::Object PythonExtensionBase::getattro( const Py::String &name )
1435
return genericGetAttro( name );
1438
int PythonExtensionBase::setattro( const Py::String &name, const Py::Object &value )
1440
return genericSetAttro( name, value );
1443
int PythonExtensionBase::compare( const Py::Object &)
1445
missing_method( compare );
1449
#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
1450
Py::Object PythonExtensionBase::rich_compare( const Py::Object &, int /*op*/ )
1452
missing_method( rich_compare );
1457
Py::Object PythonExtensionBase::repr()
1459
missing_method( repr );
1463
Py::Object PythonExtensionBase::str()
1465
missing_method( str );
1469
long PythonExtensionBase::hash()
1471
missing_method( hash );
1475
Py::Object PythonExtensionBase::call( const Py::Object &, const Py::Object &)
1477
missing_method( call );
1481
Py::Object PythonExtensionBase::iter()
1483
missing_method( iter );
1487
PyObject *PythonExtensionBase::iternext()
1489
missing_method( iternext );
1494
int PythonExtensionBase::sequence_length()
1496
missing_method( sequence_length );
1500
Py::Object PythonExtensionBase::sequence_concat( const Py::Object &)
1502
missing_method( sequence_concat );
1506
Py::Object PythonExtensionBase::sequence_repeat( Py_ssize_t )
1508
missing_method( sequence_repeat );
1512
Py::Object PythonExtensionBase::sequence_item( Py_ssize_t )
1514
missing_method( sequence_item );
1518
Py::Object PythonExtensionBase::sequence_slice( Py_ssize_t, Py_ssize_t )
1520
missing_method( sequence_slice );
1524
int PythonExtensionBase::sequence_ass_item( Py_ssize_t, const Py::Object &)
1526
missing_method( sequence_ass_item );
1530
int PythonExtensionBase::sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Py::Object &)
1532
missing_method( sequence_ass_slice );
1537
int PythonExtensionBase::mapping_length()
1539
missing_method( mapping_length );
1543
Py::Object PythonExtensionBase::mapping_subscript( const Py::Object &)
1545
missing_method( mapping_subscript );
1549
int PythonExtensionBase::mapping_ass_subscript( const Py::Object &, const Py::Object &)
1551
missing_method( mapping_ass_subscript );
1556
int PythonExtensionBase::number_nonzero()
1558
missing_method( number_nonzero );
1562
Py::Object PythonExtensionBase::number_negative()
1564
missing_method( number_negative );
1568
Py::Object PythonExtensionBase::number_positive()
1570
missing_method( number_positive );
1574
Py::Object PythonExtensionBase::number_absolute()
1576
missing_method( number_absolute );
1580
Py::Object PythonExtensionBase::number_invert()
1582
missing_method( number_invert );
1586
Py::Object PythonExtensionBase::number_int()
1588
missing_method( number_int );
1592
Py::Object PythonExtensionBase::number_float()
1594
missing_method( number_float );
1598
Py::Object PythonExtensionBase::number_long()
1600
missing_method( number_long );
1604
Py::Object PythonExtensionBase::number_oct()
1606
missing_method( number_oct );
1610
Py::Object PythonExtensionBase::number_hex()
1612
missing_method( number_hex );
1616
Py::Object PythonExtensionBase::number_add( const Py::Object &)
1618
missing_method( number_add );
1622
Py::Object PythonExtensionBase::number_subtract( const Py::Object &)
1624
missing_method( number_subtract );
1628
Py::Object PythonExtensionBase::number_multiply( const Py::Object &)
1630
missing_method( number_multiply );
1634
Py::Object PythonExtensionBase::number_divide( const Py::Object &)
1636
missing_method( number_divide );
1640
Py::Object PythonExtensionBase::number_remainder( const Py::Object &)
1642
missing_method( number_remainder );
1646
Py::Object PythonExtensionBase::number_divmod( const Py::Object &)
1648
missing_method( number_divmod );
1652
Py::Object PythonExtensionBase::number_lshift( const Py::Object &)
1654
missing_method( number_lshift );
1658
Py::Object PythonExtensionBase::number_rshift( const Py::Object &)
1660
missing_method( number_rshift );
1664
Py::Object PythonExtensionBase::number_and( const Py::Object &)
1666
missing_method( number_and );
1670
Py::Object PythonExtensionBase::number_xor( const Py::Object &)
1672
missing_method( number_xor );
1676
Py::Object PythonExtensionBase::number_or( const Py::Object &)
1678
missing_method( number_or );
1682
Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Object &)
1684
missing_method( number_power );
1689
Py_ssize_t PythonExtensionBase::buffer_getreadbuffer( Py_ssize_t, void** )
1691
missing_method( buffer_getreadbuffer );
1695
Py_ssize_t PythonExtensionBase::buffer_getwritebuffer( Py_ssize_t, void** )
1697
missing_method( buffer_getwritebuffer );
1701
Py_ssize_t PythonExtensionBase::buffer_getsegcount( Py_ssize_t* )
1703
missing_method( buffer_getsegcount );
1707
//--------------------------------------------------------------------------------
1709
// Method call handlers for
1710
// PythonExtensionBase
1711
// ExtensionModuleBase
1713
//--------------------------------------------------------------------------------
1714
extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
1718
Tuple self_and_name_tuple( _self_and_name_tuple );
1720
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1721
void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1722
if( self_as_void == NULL )
1725
ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1727
Tuple args( _args );
1729
if( _keywords == NULL )
1731
Dict keywords; // pass an empty dict
1735
self->invoke_method_keyword
1737
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
1743
return new_reference_to( result.ptr() );
1747
Dict keywords( _keywords ); // make dict
1751
self->invoke_method_keyword
1753
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
1759
return new_reference_to( result.ptr() );
1762
catch( Exception & )
1768
//NOTE: This method is used in ExtensionModule.hxx but not provided by PyCXX.
1769
//However, it's required because without it we get linker errors.
1770
extern "C" PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * )
1774
Tuple self_and_name_tuple( _self_and_name_tuple );
1776
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1777
void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1778
if( self_as_void == NULL )
1781
ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1785
self->invoke_method_noargs
1787
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() )
1791
return new_reference_to( result.ptr() );
1793
catch( Exception & )
1800
Tuple self_and_name_tuple( _self_and_name_tuple );
1802
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1803
void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1804
if( self_as_void == NULL )
1807
ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1809
String py_name( self_and_name_tuple[1] );
1810
std::string name( py_name.as_std_string( NULL ) );
1812
Object result( self->invoke_method_noargs( name ) );
1814
return new_reference_to( result.ptr() );
1816
catch( Exception & )
1825
extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
1829
Tuple self_and_name_tuple( _self_and_name_tuple );
1831
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1832
void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1833
if( self_as_void == NULL )
1836
ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1837
Tuple args( _args );
1841
self->invoke_method_varargs
1843
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ),
1848
return new_reference_to( result.ptr() );
1850
catch( Exception & )
1856
extern "C" void do_not_dealloc( void * )
1859
//--------------------------------------------------------------------------------
1861
// ExtensionExceptionType
1863
//--------------------------------------------------------------------------------
1864
ExtensionExceptionType::ExtensionExceptionType()
1869
void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
1871
std::string module_name( module.fullName() );
1873
module_name += name;
1874
set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
1877
void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent)
1879
std::string module_name( module.fullName() );
1881
module_name += name;
1882
set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
1885
ExtensionExceptionType::~ExtensionExceptionType()
1889
Exception::Exception( ExtensionExceptionType &exception, const std::string& reason )
1891
PyErr_SetString( exception.ptr(), reason.c_str() );
1894
Exception::Exception( ExtensionExceptionType &exception, Object &reason )
1896
PyErr_SetObject( exception.ptr(), reason.ptr() );
1899
Exception::Exception( PyObject *exception, Object &reason )
1901
PyErr_SetObject( exception, reason.ptr() );
1904
} // end of namespace Py