1
//-----------------------------------------------------------------------------
3
// Copyright (c) 1998 - 2007, The Regents of the University of California
4
// Produced at the Lawrence Livermore National Laboratory
5
// All rights reserved.
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
//-----------------------------------------------------------------------------
38
#ifndef __CXX_Extensions__h
39
#define __CXX_Extensions__h
43
// disable warning C4786: symbol greater than 255 character,
45
#pragma warning(disable: 4786)
48
#include "CXX/WrapPython.h"
49
#include "CXX/Version.hxx"
50
#include "CXX/Config.hxx"
51
#include "CXX/Objects.hxx"
55
extern PyObject py_object_initializer;
63
class ExtensionModuleBase;
65
// Make an Exception Type for use in raising custom exceptions
66
class ExtensionExceptionType : public Object
69
ExtensionExceptionType();
70
virtual ~ExtensionExceptionType();
72
// call init to create the type
73
void init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent );
74
void init( ExtensionModuleBase &module, const std::string& name );
82
virtual ~MethodTable();
84
void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
88
std::vector<PyMethodDef> t; // accumulator of PyMethodDef's
89
PyMethodDef *mt; // Actual method table produced when full
91
static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
95
// prevent the compiler generating these unwanted functions
97
MethodTable(const MethodTable& m); //unimplemented
98
void operator=(const MethodTable& m); //unimplemented
100
}; // end class MethodTable
104
typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
105
typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
109
class MethodDefExt : public PyMethodDef
112
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
113
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
118
method_varargs_function_t _function,
119
method_varargs_call_handler_t _handler,
123
ext_meth_def.ml_name = const_cast<char *>(_name);
124
ext_meth_def.ml_meth = _handler;
125
ext_meth_def.ml_flags = METH_VARARGS;
126
ext_meth_def.ml_doc = const_cast<char *>(_doc);
128
ext_varargs_function = _function;
129
ext_keyword_function = NULL;
135
method_keyword_function_t _function,
136
method_keyword_call_handler_t _handler,
140
ext_meth_def.ml_name = const_cast<char *>(_name);
141
ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
142
ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
143
ext_meth_def.ml_doc = const_cast<char *>(_doc);
145
ext_varargs_function = NULL;
146
ext_keyword_function = _function;
152
PyMethodDef ext_meth_def;
153
method_varargs_function_t ext_varargs_function;
154
method_keyword_function_t ext_keyword_function;
157
class ExtensionModuleBase
160
ExtensionModuleBase( const char *name );
161
virtual ~ExtensionModuleBase();
163
Module module(void) const; // only valid after initialize() has been called
164
Dict moduleDictionary(void) const; // only valid after initialize() has been called
166
virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
167
virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
169
const std::string &name() const;
170
const std::string &fullName() const;
173
// Initialize the module
174
void initialize( const char *module_doc );
176
const std::string module_name;
177
const std::string full_module_name;
178
MethodTable method_table;
183
// prevent the compiler generating these unwanted functions
185
ExtensionModuleBase( const ExtensionModuleBase & ); //unimplemented
186
void operator=( const ExtensionModuleBase & ); //unimplemented
190
extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
191
extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
192
extern "C" void do_not_dealloc( void * );
195
template<TEMPLATE_TYPENAME T>
196
class ExtensionModule : public ExtensionModuleBase
199
ExtensionModule( const char *name )
200
: ExtensionModuleBase( name )
202
virtual ~ExtensionModule()
206
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
207
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
208
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
210
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
212
method_map_t &mm = methods();
214
MethodDefExt<T> *method_definition = new MethodDefExt<T>
218
method_varargs_call_handler,
222
mm[std::string( name )] = method_definition;
225
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
227
method_map_t &mm = methods();
229
MethodDefExt<T> *method_definition = new MethodDefExt<T>
233
method_keyword_call_handler,
237
mm[std::string( name )] = method_definition;
240
void initialize( const char *module_doc="" )
242
ExtensionModuleBase::initialize( module_doc );
243
Dict dict( moduleDictionary() );
246
// put each of the methods into the modules dictionary
247
// so that we get called back at the function in T.
249
method_map_t &mm = methods();
250
EXPLICIT_TYPENAME method_map_t::iterator i;
252
for( i=mm.begin(); i != mm.end(); ++i )
254
MethodDefExt<T> *method_definition = (*i).second;
256
static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
259
args[0] = Object( self );
260
args[1] = String( (*i).first );
262
PyObject *func = PyCFunction_New
264
&method_definition->ext_meth_def,
265
new_reference_to( args )
268
dict[ (*i).first ] = Object( func );
272
protected: // Tom Malcolmson reports that derived classes need access to these
274
static method_map_t &methods(void)
276
static method_map_t *map_of_methods = NULL;
277
if( map_of_methods == NULL )
278
map_of_methods = new method_map_t;
280
return *map_of_methods;
284
// this invoke function must be called from within a try catch block
285
virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
287
method_map_t &mm = methods();
288
MethodDefExt<T> *meth_def = mm[ name ];
289
if( meth_def == NULL )
291
std::string error_msg( "CXX - cannot invoke keyword method named " );
293
throw RuntimeError( error_msg );
296
// cast up to the derived class
297
T *self = static_cast<T *>(this);
299
return (self->*meth_def->ext_keyword_function)( args, keywords );
302
// this invoke function must be called from within a try catch block
303
virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
305
method_map_t &mm = methods();
306
MethodDefExt<T> *meth_def = mm[ name ];
307
if( meth_def == NULL )
309
std::string error_msg( "CXX - cannot invoke varargs method named " );
311
throw RuntimeError( error_msg );
314
// cast up to the derived class
315
T *self = static_cast<T *>(this);
317
return (self->*meth_def->ext_varargs_function)( args );
322
// prevent the compiler generating these unwanted functions
324
ExtensionModule( const ExtensionModule<T> & ); //unimplemented
325
void operator=( const ExtensionModule<T> & ); //unimplemented
332
// if you define one sequence method you must define
333
// all of them except the assigns
335
PythonType (size_t base_size, int itemsize, const char *default_name );
336
virtual ~PythonType ();
338
const char *getName () const;
339
const char *getDoc () const;
341
PyTypeObject* type_object () const;
342
PythonType & name (const char* nam);
343
PythonType & doc (const char* d);
344
PythonType & dealloc(void (*f)(PyObject*));
346
PythonType & supportPrint(void);
347
PythonType & supportGetattr(void);
348
PythonType & supportSetattr(void);
349
PythonType & supportGetattro(void);
350
PythonType & supportSetattro(void);
351
PythonType & supportCompare(void);
352
PythonType & supportRepr(void);
353
PythonType & supportStr(void);
354
PythonType & supportHash(void);
355
PythonType & supportCall(void);
356
PythonType & supportIter(void);
358
PythonType & supportSequenceType(void);
359
PythonType & supportMappingType(void);
360
PythonType & supportNumberType(void);
361
PythonType & supportBufferType(void);
365
PySequenceMethods *sequence_table;
366
PyMappingMethods *mapping_table;
367
PyNumberMethods *number_table;
368
PyBufferProcs *buffer_table;
370
void init_sequence();
377
// prevent the compiler generating these unwanted functions
379
PythonType (const PythonType& tb); // unimplemented
380
void operator=(const PythonType& t); // unimplemented
382
}; // end of PythonType
386
// Class PythonExtension is what you inherit from to create
387
// a new Python extension type. You give your class itself
388
// as the template paramter.
390
// There are two ways that extension objects can get destroyed.
391
// 1. Their reference count goes to zero
392
// 2. Someone does an explicit delete on a pointer.
393
// In (1) the problem is to get the destructor called
394
// We register a special deallocator in the Python type object
395
// (see behaviors()) to do this.
396
// In (2) there is no problem, the dtor gets called.
398
// PythonExtension does not use the usual Python heap allocator,
399
// instead using new/delete. We do the setting of the type object
400
// and reference count, usually done by PyObject_New, in the
403
// This special deallocator does a delete on the pointer.
406
class PythonExtensionBase : public PyObject
409
PythonExtensionBase();
410
virtual ~PythonExtensionBase();
413
virtual int print( FILE *, int );
414
virtual Object getattr( const char * ) = 0;
415
virtual int setattr( const char *, const Object & );
416
virtual Object getattro( const Object & );
417
virtual int setattro( const Object &, const Object & );
418
virtual int compare( const Object & );
419
virtual Object repr();
420
virtual Object str();
422
virtual Object call( const Object &, const Object & );
423
virtual Object iter();
424
virtual PyObject* iternext();
427
virtual int sequence_length();
428
virtual Object sequence_concat( const Object & );
429
virtual Object sequence_repeat( Py_ssize_t );
430
virtual Object sequence_item( Py_ssize_t );
431
virtual Object sequence_slice( Py_ssize_t, Py_ssize_t );
432
virtual int sequence_ass_item( Py_ssize_t, const Object & );
433
virtual int sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Object & );
436
virtual int mapping_length();
437
virtual Object mapping_subscript( const Object & );
438
virtual int mapping_ass_subscript( const Object &, const Object & );
441
virtual int number_nonzero();
442
virtual Object number_negative();
443
virtual Object number_positive();
444
virtual Object number_absolute();
445
virtual Object number_invert();
446
virtual Object number_int();
447
virtual Object number_float();
448
virtual Object number_long();
449
virtual Object number_oct();
450
virtual Object number_hex();
451
virtual Object number_add( const Object & );
452
virtual Object number_subtract( const Object & );
453
virtual Object number_multiply( const Object & );
454
virtual Object number_divide( const Object & );
455
virtual Object number_remainder( const Object & );
456
virtual Object number_divmod( const Object & );
457
virtual Object number_lshift( const Object & );
458
virtual Object number_rshift( const Object & );
459
virtual Object number_and( const Object & );
460
virtual Object number_xor( const Object & );
461
virtual Object number_or( const Object & );
462
virtual Object number_power( const Object &, const Object & );
465
virtual Py_ssize_t buffer_getreadbuffer( Py_ssize_t, void** );
466
virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
467
virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );
470
void missing_method( void );
471
static PyObject *method_call_handler( PyObject *self, PyObject *args );
474
template<TEMPLATE_TYPENAME T>
475
class PythonExtension: public PythonExtensionBase
478
static PyTypeObject* type_object()
480
return behaviors().type_object();
483
static int check( PyObject *p )
486
return p->ob_type == type_object();
489
static int check( const Object& ob )
491
return check( ob.ptr());
496
// every object needs getattr implemented
497
// to support methods
499
virtual Object getattr( const char *name )
501
return getattr_methods( name );
505
explicit PythonExtension()
506
: PythonExtensionBase()
509
(void)PyObject_INIT( this, type_object() );
512
ob_type = type_object();
515
// every object must support getattr
516
behaviors().supportGetattr();
519
virtual ~PythonExtension()
522
static PythonType &behaviors()
524
static PythonType* p;
527
#if defined( _CPPRTTI ) || defined(__GNUG__)
528
const char *default_name = (typeid ( T )).name();
530
const char *default_name = "unknown";
532
p = new PythonType( sizeof( T ), 0, default_name );
533
p->dealloc( extension_object_deallocator );
540
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
541
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
542
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
544
// support the default attributes, __name__, __doc__ and methods
545
virtual Object getattr_default( const char *_name )
547
std::string name( _name );
549
if( name == "__name__" && type_object()->tp_name != NULL )
551
return Py::String( type_object()->tp_name );
553
if( name == "__doc__" && type_object()->tp_doc != NULL )
555
return Py::String( type_object()->tp_doc );
558
// trying to fake out being a class for help()
559
// else if( name == "__bases__" )
561
// return Py::Tuple(0);
563
// else if( name == "__module__" )
565
// return Py::Nothing();
567
// else if( name == "__dict__" )
569
// return Py::Dict();
572
return getattr_methods( _name );
575
// turn a name into function object
576
virtual Object getattr_methods( const char *_name )
578
std::string name( _name );
580
method_map_t &mm = methods();
582
if( name == "__methods__" )
586
for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
587
methods.append( String( (*i).first ) );
592
// see if name exists
593
if( mm.find( name ) == mm.end() )
594
throw AttributeError( name );
598
self[0] = Object( this );
599
self[1] = String( name );
601
MethodDefExt<T> *method_definition = mm[ name ];
603
PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
605
return Object(func, true);
608
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
610
method_map_t &mm = methods();
612
MethodDefExt<T> *method_definition = new MethodDefExt<T>
616
method_varargs_call_handler,
620
mm[std::string( name )] = method_definition;
623
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
625
method_map_t &mm = methods();
627
MethodDefExt<T> *method_definition = new MethodDefExt<T>
631
method_keyword_call_handler,
635
mm[std::string( name )] = method_definition;
639
static method_map_t &methods(void)
641
static method_map_t *map_of_methods = NULL;
642
if( map_of_methods == NULL )
643
map_of_methods = new method_map_t;
645
return *map_of_methods;
648
static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
652
Tuple self_and_name_tuple( _self_and_name_tuple );
654
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
655
T *self = static_cast<T *>( self_in_cobject );
657
String name( self_and_name_tuple[1] );
659
method_map_t &mm = methods();
660
MethodDefExt<T> *meth_def = mm[ name ];
661
if( meth_def == NULL )
666
// _keywords may be NULL so be careful about the way the dict is created
668
if( _keywords != NULL )
669
keywords = Dict( _keywords );
671
Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
673
return new_reference_to( result.ptr() );
681
static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
685
Tuple self_and_name_tuple( _self_and_name_tuple );
687
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
688
T *self = static_cast<T *>( self_in_cobject );
690
String name( self_and_name_tuple[1] );
692
method_map_t &mm = methods();
693
MethodDefExt<T> *meth_def = mm[ name ];
694
if( meth_def == NULL )
701
// TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
705
result = (self->*meth_def->ext_varargs_function)( args );
707
catch (std::__stl_debug_exception)
709
// throw cxx::RuntimeError( sErrMsg );
710
throw cxx::RuntimeError( "Error message not set yet." );
713
result = (self->*meth_def->ext_varargs_function)( args );
714
#endif // _STLP_DEBUG
716
return new_reference_to( result.ptr() );
724
static void extension_object_deallocator ( PyObject* t )
730
// prevent the compiler generating these unwanted functions
732
explicit PythonExtension( const PythonExtension<T>& other );
733
void operator=( const PythonExtension<T>& rhs );
737
// ExtensionObject<T> is an Object that will accept only T's.
739
template<TEMPLATE_TYPENAME T>
740
class ExtensionObject: public Object
744
explicit ExtensionObject ( PyObject *pyob )
750
ExtensionObject( const ExtensionObject<T>& other )
756
ExtensionObject( const Object& other )
762
ExtensionObject& operator= ( const Object& rhs )
764
return (*this = *rhs );
767
ExtensionObject& operator= ( PyObject* rhsp )
775
virtual bool accepts ( PyObject *pyob ) const
777
return ( pyob && T::check( pyob ));
781
// Obtain a pointer to the PythonExtension object
783
T *extensionObject(void)
785
return static_cast<T *>( ptr() );
790
// End of CXX_Extensions.h