lib

cxx_extensions.cpp
1#include "Extensions.h"
2#include "Exception.h"
3
4#include <assert.h>
5
6namespace Py
7{
8
9//================================================================================
10//
11// Implementation of MethodTable
12//
13//================================================================================
14
15PyMethodDef MethodTable::method( const char* method_name, PyCFunction f, int flags, const char* doc )
16 {
17 PyMethodDef m;
18 m.ml_name = const_cast<char*>( method_name );
19 m.ml_meth = f;
20 m.ml_flags = flags;
21 m.ml_doc = const_cast<char*>( doc );
22 return m;
23 }
24
25MethodTable::MethodTable()
26 {
27 t.push_back( method( 0, 0, 0, 0 ) );
28 mt = 0;
29 }
30
31MethodTable::~MethodTable()
32 {
33 delete [] mt;
34 }
35
36void MethodTable::add( const char* method_name, PyCFunction f, const char* doc, int flag )
37 {
38 if( !mt )
39 {
40 t.insert( t.end()-1, method( method_name, f, flag, doc ) );
41 }
42 else
43 {
44 throw RuntimeError( "Too late to add a module method!" );
45 }
46 }
47
48PyMethodDef* MethodTable::table()
49 {
50 if( !mt )
51 {
52 int t1size = t.size();
53 mt = new PyMethodDef[t1size];
54 int j = 0;
55 for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
56 {
57 mt[j++] = *i;
58 }
59 }
60 return mt;
61 }
62
63//================================================================================
64//
65// Implementation of ExtensionModule
66//
67//================================================================================
68ExtensionModuleBase::ExtensionModuleBase( const char *name )
69 : module_name( name )
70 , full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : module_name )
71 , method_table()
72 {}
73
74ExtensionModuleBase::~ExtensionModuleBase()
75 {}
76
77const std::string &ExtensionModuleBase::name() const
78 {
79 return module_name;
80 }
81
82const std::string &ExtensionModuleBase::fullName() const
83 {
84 return full_module_name;
85 }
86
87class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
88 {
89public:
90 ExtensionModuleBasePtr( ExtensionModuleBase *_module )
91 : module( _module )
92 {}
93 virtual ~ExtensionModuleBasePtr()
94 {}
95
96 ExtensionModuleBase *module;
97 };
98
99
100void ExtensionModuleBase::initialize( const char *module_doc )
101 {
102 PyObject *module_ptr = new ExtensionModuleBasePtr( this );
103
104 Py_InitModule4
105 (
106 const_cast<char *>( module_name.c_str() ), // name
107 method_table.table(), // methods
108 const_cast<char *>( module_doc ), // docs
109 module_ptr, // pass to functions as "self"
110 PYTHON_API_VERSION // API version
111 );
112 }
113
114Py::Module ExtensionModuleBase::module(void) const
115 {
116 return Module( full_module_name );
117 }
118
119Py::Dict ExtensionModuleBase::moduleDictionary(void) const
120 {
121 return module().getDict();
122 }
123
124//--------------------------------------------------------------------------------
125
126//================================================================================
127//
128// Implementation of PythonType
129//
130//================================================================================
131
132extern "C"
133 {
134 static void standard_dealloc(PyObject* p);
135 //
136 // All the following functions redirect the call from Python
137 // onto the matching virtual function in PythonExtensionBase
138 //
139 static int print_handler (PyObject*, FILE *, int);
140 static PyObject* getattr_handler (PyObject*, char*);
141 static int setattr_handler (PyObject*, char*, PyObject*);
142 static PyObject* getattro_handler (PyObject*, PyObject*);
143 static int setattro_handler (PyObject*, PyObject*, PyObject*);
144 static int compare_handler (PyObject*, PyObject*);
145 static PyObject* repr_handler (PyObject*);
146 static PyObject* str_handler (PyObject*);
147 static long hash_handler (PyObject*);
148 static PyObject* call_handler (PyObject*, PyObject*, PyObject*);
149
150#if PY_VERSION_HEX < 0x02050000
151 typedef int Py_ssize_t;
152#endif
153 // Sequence methods
154 static Py_ssize_t sequence_length_handler(PyObject*);
155 static PyObject* sequence_concat_handler(PyObject*,PyObject*);
156 static PyObject* sequence_repeat_handler(PyObject*, Py_ssize_t);
157 static PyObject* sequence_item_handler(PyObject*, Py_ssize_t);
158 static PyObject* sequence_slice_handler(PyObject*, Py_ssize_t, Py_ssize_t);
159 static int sequence_ass_item_handler(PyObject*, Py_ssize_t, PyObject*);
160 static int sequence_ass_slice_handler(PyObject*, Py_ssize_t, Py_ssize_t, PyObject*);
161 // Mapping
162 static Py_ssize_t mapping_length_handler(PyObject*);
163 static PyObject* mapping_subscript_handler(PyObject*, PyObject*);
164 static int mapping_ass_subscript_handler(PyObject*, PyObject*, PyObject*);
165
166 // Numeric methods
167 static int number_nonzero_handler (PyObject*);
168 static PyObject* number_negative_handler (PyObject*);
169 static PyObject* number_positive_handler (PyObject*);
170 static PyObject* number_absolute_handler (PyObject*);
171 static PyObject* number_invert_handler (PyObject*);
172 static PyObject* number_int_handler (PyObject*);
173 static PyObject* number_float_handler (PyObject*);
174 static PyObject* number_long_handler (PyObject*);
175 static PyObject* number_oct_handler (PyObject*);
176 static PyObject* number_hex_handler (PyObject*);
177 static PyObject* number_add_handler (PyObject*, PyObject*);
178 static PyObject* number_subtract_handler (PyObject*, PyObject*);
179 static PyObject* number_multiply_handler (PyObject*, PyObject*);
180 static PyObject* number_divide_handler (PyObject*, PyObject*);
181 static PyObject* number_remainder_handler (PyObject*, PyObject*);
182 static PyObject* number_divmod_handler (PyObject*, PyObject*);
183 static PyObject* number_lshift_handler (PyObject*, PyObject*);
184 static PyObject* number_rshift_handler (PyObject*, PyObject*);
185 static PyObject* number_and_handler (PyObject*, PyObject*);
186 static PyObject* number_xor_handler (PyObject*, PyObject*);
187 static PyObject* number_or_handler (PyObject*, PyObject*);
188 static PyObject* number_power_handler(PyObject*, PyObject*, PyObject*);
189
190 // Buffer
191 static Py_ssize_t buffer_getreadbuffer_handler (PyObject*, Py_ssize_t, void**);
192 static Py_ssize_t buffer_getwritebuffer_handler (PyObject*, Py_ssize_t, void**);
193 static Py_ssize_t buffer_getsegcount_handler (PyObject*, Py_ssize_t*);
194 }
195
196
197extern "C" void standard_dealloc( PyObject* p )
198 {
199 PyMem_DEL( p );
200 }
201
202void PythonType::supportSequenceType()
203 {
204 if( !sequence_table )
205 {
206 sequence_table = new PySequenceMethods;
207 table->tp_as_sequence = sequence_table;
208 sequence_table->sq_length = sequence_length_handler;
209 sequence_table->sq_concat = sequence_concat_handler;
210 sequence_table->sq_repeat = sequence_repeat_handler;
211 sequence_table->sq_item = sequence_item_handler;
212 sequence_table->sq_slice = sequence_slice_handler;
213
214 sequence_table->sq_ass_item = sequence_ass_item_handler; // BAS setup seperately?
215 sequence_table->sq_ass_slice = sequence_ass_slice_handler; // BAS setup seperately?
216 }
217 }
218
219void PythonType::supportMappingType()
220 {
221 if( !mapping_table )
222 {
223 mapping_table = new PyMappingMethods;
224 table->tp_as_mapping = mapping_table;
225 mapping_table->mp_length = mapping_length_handler;
226 mapping_table->mp_subscript = mapping_subscript_handler;
227 mapping_table->mp_ass_subscript = mapping_ass_subscript_handler; // BAS setup seperately?
228 }
229 }
230
231void PythonType::supportNumberType()
232 {
233 if( !number_table )
234 {
235 number_table = new PyNumberMethods;
236 table->tp_as_number = number_table;
237 number_table->nb_add = number_add_handler;
238 number_table->nb_subtract = number_subtract_handler;
239 number_table->nb_multiply = number_multiply_handler;
240 number_table->nb_divide = number_divide_handler;
241 number_table->nb_remainder = number_remainder_handler;
242 number_table->nb_divmod = number_divmod_handler;
243 number_table->nb_power = number_power_handler;
244 number_table->nb_negative = number_negative_handler;
245 number_table->nb_positive = number_positive_handler;
246 number_table->nb_absolute = number_absolute_handler;
247 number_table->nb_nonzero = number_nonzero_handler;
248 number_table->nb_invert = number_invert_handler;
249 number_table->nb_lshift = number_lshift_handler;
250 number_table->nb_rshift = number_rshift_handler;
251 number_table->nb_and = number_and_handler;
252 number_table->nb_xor = number_xor_handler;
253 number_table->nb_or = number_or_handler;
254 number_table->nb_coerce = 0;
255 number_table->nb_int = number_int_handler;
256 number_table->nb_long = number_long_handler;
257 number_table->nb_float = number_float_handler;
258 number_table->nb_oct = number_oct_handler;
259 number_table->nb_hex = number_hex_handler;
260 }
261 }
262
263void PythonType::supportBufferType()
264 {
265 if( !buffer_table )
266 {
267 buffer_table = new PyBufferProcs;
268 table->tp_as_buffer = buffer_table;
269 buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
270 buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
271 buffer_table->bf_getsegcount = buffer_getsegcount_handler;
272 }
273 }
274
275// if you define one sequence method you must define
276// all of them except the assigns
277
278PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
279 : table( new PyTypeObject )
280 , sequence_table( NULL )
281 , mapping_table( NULL )
282 , number_table( NULL )
283 , buffer_table( NULL )
284 {
285 *reinterpret_cast<PyObject*>( table ) = py_object_initializer;
286 table->ob_type = _Type_Type();
287 table->ob_size = 0;
288 table->tp_name = const_cast<char *>( default_name );
289 table->tp_basicsize = basic_size;
290 table->tp_itemsize = itemsize;
291 table->tp_dealloc = ( destructor ) standard_dealloc;
292 table->tp_print = 0;
293 table->tp_getattr = 0;
294 table->tp_setattr = 0;
295 table->tp_compare = 0;
296 table->tp_repr = 0;
297 table->tp_as_number = 0;
298 table->tp_as_sequence = 0;
299 table->tp_as_mapping = 0;
300 table->tp_hash = 0;
301 table->tp_call = 0;
302 table->tp_str = 0;
303 table->tp_getattro = 0;
304 table->tp_setattro = 0;
305 table->tp_as_buffer = 0;
306 table->tp_flags = 0L;
307 table->tp_doc = 0;
308#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
309 // first use in 2.0
310 table->tp_traverse = 0L;
311 table->tp_clear = 0L;
312#else
313 table->tp_xxx5 = 0L;
314 table->tp_xxx6 = 0L;
315#endif
316#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
317 // first defined in 2.1
318 table->tp_richcompare = 0L;
319 table->tp_weaklistoffset = 0L;
320#else
321 table->tp_xxx7 = 0L;
322 table->tp_xxx8 = 0L;
323#endif
324
325#ifdef COUNT_ALLOCS
326 table->tp_alloc = 0;
327 table->tp_free = 0;
328 table->tp_maxalloc = 0;
329 table->tp_next = 0;
330#endif
331 }
332
333PythonType::~PythonType( )
334 {
335 delete table;
336 delete sequence_table;
337 delete mapping_table;
338 delete number_table;
339 delete buffer_table;
340 }
341
342PyTypeObject* PythonType::type_object( ) const
343 {return table;}
344
345void PythonType::name( const char* nam )
346 {
347 table->tp_name = const_cast<char *>( nam );
348 }
349
350const char *PythonType::getName() const
351 {
352 return table->tp_name;
353 }
354
355void PythonType::doc( const char* d )
356 {
357 table->tp_doc = const_cast<char *>( d );
358 }
359
360const char *PythonType::getDoc() const
361 {
362 return table->tp_doc;
363 }
364
365void PythonType::dealloc( void( *f )( PyObject* ))
366 {
367 table->tp_dealloc = f;
368 }
369
370void PythonType::supportPrint()
371 {
372 table->tp_print = print_handler;
373 }
374
375void PythonType::supportGetattr()
376 {
377 table->tp_getattr = getattr_handler;
378 }
379
380void PythonType::supportSetattr()
381 {
382 table->tp_setattr = setattr_handler;
383 }
384
385void PythonType::supportGetattro()
386 {
387 table->tp_getattro = getattro_handler;
388 }
389
390void PythonType::supportSetattro()
391 {
392 table->tp_setattro = setattro_handler;
393 }
394
395void PythonType::supportCompare()
396 {
397 table->tp_compare = compare_handler;
398 }
399
400void PythonType::supportRepr()
401 {
402 table->tp_repr = repr_handler;
403 }
404
405void PythonType::supportStr()
406 {
407 table->tp_str = str_handler;
408 }
409
410void PythonType::supportHash()
411 {
412 table->tp_hash = hash_handler;
413 }
414
415void PythonType::supportCall()
416 {
417 table->tp_call = call_handler;
418 }
419
420//--------------------------------------------------------------------------------
421//
422// Handlers
423//
424//--------------------------------------------------------------------------------
425extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
426 {
427 try
428 {
429 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
430 return p->print( fp, flags );
431 }
432 catch( Py::Exception & )
433 {
434 return -1; // indicate error
435 }
436 }
437
438extern "C" PyObject* getattr_handler( PyObject *self, char *name )
439 {
440 try
441 {
442 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
443 return new_reference_to( p->getattr( name ) );
444 }
445 catch( Py::Exception & )
446 {
447 return NULL; // indicate error
448 }
449 }
450
451extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
452 {
453 try
454 {
455 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
456 return p->setattr( name, Py::Object( value ) );
457 }
458 catch( Py::Exception & )
459 {
460 return -1; // indicate error
461 }
462 }
463
464extern "C" PyObject* getattro_handler( PyObject *self, PyObject *name )
465 {
466 try
467 {
468 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
469 return new_reference_to( p->getattro( Py::Object( name ) ) );
470 }
471 catch( Py::Exception & )
472 {
473 return NULL; // indicate error
474 }
475 }
476
477extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
478 {
479 try
480 {
481 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
482 return p->setattro( Py::Object( name ), Py::Object( value ) );
483 }
484 catch( Py::Exception & )
485 {
486 return -1; // indicate error
487 }
488 }
489
490extern "C" int compare_handler( PyObject *self, PyObject *other )
491 {
492 try
493 {
494 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
495 return p->compare( Py::Object( other ) );
496 }
497 catch( Py::Exception & )
498 {
499 return -1; // indicate error
500 }
501 }
502
503extern "C" PyObject* repr_handler( PyObject *self )
504 {
505 try
506 {
507 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
508 return new_reference_to( p->repr() );
509 }
510 catch( Py::Exception & )
511 {
512 return NULL; // indicate error
513 }
514 }
515
516extern "C" PyObject* str_handler( PyObject *self )
517 {
518 try
519 {
520 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
521 return new_reference_to( p->str() );
522 }
523 catch( Py::Exception & )
524 {
525 return NULL; // indicate error
526 }
527 }
528
529extern "C" long hash_handler( PyObject *self )
530 {
531 try
532 {
533 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
534 return p->hash();
535 }
536 catch( Py::Exception & )
537 {
538 return -1; // indicate error
539 }
540 }
541
542extern "C" PyObject* call_handler( PyObject *self, PyObject *args, PyObject *kw )
543 {
544 try
545 {
546 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
547 return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
548 if( kw != NULL )
549 return new_reference_to( p->call( Py::Object( args ), Py::Object( kw ) ) );
550 else
551 return new_reference_to( p->call( Py::Object( args ), Py::Object() ) );
552 }
553 catch( Py::Exception & )
554 {
555 return NULL; // indicate error
556 }
557 }
558
559
560// Sequence methods
561extern "C" Py_ssize_t sequence_length_handler( PyObject *self )
562 {
563 try
564 {
565 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
566 return p->sequence_length();
567 }
568 catch( Py::Exception & )
569 {
570 return -1; // indicate error
571 }
572 }
573
574extern "C" PyObject* sequence_concat_handler( PyObject *self, PyObject *other )
575 {
576 try
577 {
578 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
579 return new_reference_to( p->sequence_concat( Py::Object( other ) ) );
580 }
581 catch( Py::Exception & )
582 {
583 return NULL; // indicate error
584 }
585 }
586
587extern "C" PyObject* sequence_repeat_handler( PyObject *self, Py_ssize_t count )
588 {
589 try
590 {
591 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
592 return new_reference_to( p->sequence_repeat( count ) );
593 }
594 catch( Py::Exception & )
595 {
596 return NULL; // indicate error
597 }
598 }
599
600extern "C" PyObject* sequence_item_handler( PyObject *self, Py_ssize_t index )
601 {
602 try
603 {
604 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
605 return new_reference_to( p->sequence_item( index ) );
606 }
607 catch( Py::Exception & )
608 {
609 return NULL; // indicate error
610 }
611 }
612
613extern "C" PyObject* sequence_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last )
614 {
615 try
616 {
617 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
618 return new_reference_to( p->sequence_slice( first, last ) );
619 }
620 catch( Py::Exception & )
621 {
622 return NULL; // indicate error
623 }
624 }
625
626extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value )
627 {
628 try
629 {
630 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
631 return p->sequence_ass_item( index, Py::Object( value ) );
632 }
633 catch( Py::Exception & )
634 {
635 return -1; // indicate error
636 }
637 }
638
639extern "C" int sequence_ass_slice_handler( PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *value )
640 {
641 try
642 {
643 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
644 return p->sequence_ass_slice( first, last, Py::Object( value ) );
645 }
646 catch( Py::Exception & )
647 {
648 return -1; // indicate error
649 }
650 }
651
652// Mapping
653extern "C" Py_ssize_t mapping_length_handler( PyObject *self )
654 {
655 try
656 {
657 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
658 return p->mapping_length();
659 }
660 catch( Py::Exception & )
661 {
662 return -1; // indicate error
663 }
664 }
665
666extern "C" PyObject* mapping_subscript_handler( PyObject *self, PyObject *key )
667 {
668 try
669 {
670 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
671 return new_reference_to( p->mapping_subscript( Py::Object( key ) ) );
672 }
673 catch( Py::Exception & )
674 {
675 return NULL; // indicate error
676 }
677 }
678
679extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
680 {
681 try
682 {
683 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
684 return p->mapping_ass_subscript( Py::Object( key ), Py::Object( value ) );
685 }
686 catch( Py::Exception & )
687 {
688 return -1; // indicate error
689 }
690 }
691
692// Number
693extern "C" int number_nonzero_handler( PyObject *self )
694 {
695 try
696 {
697 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
698 return p->number_nonzero();
699 }
700 catch( Py::Exception & )
701 {
702 return -1; // indicate error
703 }
704 }
705
706extern "C" PyObject* number_negative_handler( PyObject *self )
707 {
708 try
709 {
710 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
711 return new_reference_to( p->number_negative() );
712 }
713 catch( Py::Exception & )
714 {
715 return NULL; // indicate error
716 }
717 }
718
719extern "C" PyObject* number_positive_handler( PyObject *self )
720 {
721 try
722 {
723 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
724 return new_reference_to( p->number_positive() );
725 }
726 catch( Py::Exception & )
727 {
728 return NULL; // indicate error
729 }
730 }
731
732extern "C" PyObject* number_absolute_handler( PyObject *self )
733 {
734 try
735 {
736 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
737 return new_reference_to( p->number_absolute() );
738 }
739 catch( Py::Exception & )
740 {
741 return NULL; // indicate error
742 }
743 }
744
745extern "C" PyObject* number_invert_handler( PyObject *self )
746 {
747 try
748 {
749 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
750 return new_reference_to( p->number_invert() );
751 }
752 catch( Py::Exception & )
753 {
754 return NULL; // indicate error
755 }
756 }
757
758extern "C" PyObject* number_int_handler( PyObject *self )
759 {
760 try
761 {
762 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
763 return new_reference_to( p->number_int() );
764 }
765 catch( Py::Exception & )
766 {
767 return NULL; // indicate error
768 }
769 }
770
771extern "C" PyObject* number_float_handler( PyObject *self )
772 {
773 try
774 {
775 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
776 return new_reference_to( p->number_float() );
777 }
778 catch( Py::Exception & )
779 {
780 return NULL; // indicate error
781 }
782 }
783
784extern "C" PyObject* number_long_handler( PyObject *self )
785 {
786 try
787 {
788 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
789 return new_reference_to( p->number_long() );
790 }
791 catch( Py::Exception & )
792 {
793 return NULL; // indicate error
794 }
795 }
796
797extern "C" PyObject* number_oct_handler( PyObject *self )
798 {
799 try
800 {
801 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
802 return new_reference_to( p->number_oct() );
803 }
804 catch( Py::Exception & )
805 {
806 return NULL; // indicate error
807 }
808 }
809
810extern "C" PyObject* number_hex_handler( PyObject *self )
811 {
812 try
813 {
814 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
815 return new_reference_to( p->number_hex() );
816 }
817 catch( Py::Exception & )
818 {
819 return NULL; // indicate error
820 }
821 }
822
823extern "C" PyObject* number_add_handler( PyObject *self, PyObject *other )
824 {
825 try
826 {
827 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
828 return new_reference_to( p->number_add( Py::Object( other ) ) );
829 }
830 catch( Py::Exception & )
831 {
832 return NULL; // indicate error
833 }
834 }
835
836extern "C" PyObject* number_subtract_handler( PyObject *self, PyObject *other )
837 {
838 try
839 {
840 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
841 return new_reference_to( p->number_subtract( Py::Object( other ) ) );
842 }
843 catch( Py::Exception & )
844 {
845 return NULL; // indicate error
846 }
847 }
848
849extern "C" PyObject* number_multiply_handler( PyObject *self, PyObject *other )
850 {
851 try
852 {
853 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
854 return new_reference_to( p->number_multiply( Py::Object( other ) ) );
855 }
856 catch( Py::Exception & )
857 {
858 return NULL; // indicate error
859 }
860 }
861
862extern "C" PyObject* number_divide_handler( PyObject *self, PyObject *other )
863 {
864 try
865 {
866 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
867 return new_reference_to( p->number_divide( Py::Object( other ) ) );
868 }
869 catch( Py::Exception & )
870 {
871 return NULL; // indicate error
872 }
873 }
874
875extern "C" PyObject* number_remainder_handler( PyObject *self, PyObject *other )
876 {
877 try
878 {
879 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
880 return new_reference_to( p->number_remainder( Py::Object( other ) ) );
881 }
882 catch( Py::Exception & )
883 {
884 return NULL; // indicate error
885 }
886 }
887
888extern "C" PyObject* number_divmod_handler( PyObject *self, PyObject *other )
889 {
890 try
891 {
892 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
893 return new_reference_to( p->number_divmod( Py::Object( other ) ) );
894 }
895 catch( Py::Exception & )
896 {
897 return NULL; // indicate error
898 }
899 }
900
901extern "C" PyObject* number_lshift_handler( PyObject *self, PyObject *other )
902 {
903 try
904 {
905 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
906 return new_reference_to( p->number_lshift( Py::Object( other ) ) );
907 }
908 catch( Py::Exception & )
909 {
910 return NULL; // indicate error
911 }
912 }
913
914extern "C" PyObject* number_rshift_handler( PyObject *self, PyObject *other )
915 {
916 try
917 {
918 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
919 return new_reference_to( p->number_rshift( Py::Object( other ) ) );
920 }
921 catch( Py::Exception & )
922 {
923 return NULL; // indicate error
924 }
925 }
926
927extern "C" PyObject* number_and_handler( PyObject *self, PyObject *other )
928 {
929 try
930 {
931 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
932 return new_reference_to( p->number_and( Py::Object( other ) ) );
933 }
934 catch( Py::Exception & )
935 {
936 return NULL; // indicate error
937 }
938 }
939
940extern "C" PyObject* number_xor_handler( PyObject *self, PyObject *other )
941 {
942 try
943 {
944 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
945 return new_reference_to( p->number_xor( Py::Object( other ) ) );
946 }
947 catch( Py::Exception & )
948 {
949 return NULL; // indicate error
950 }
951 }
952
953extern "C" PyObject* number_or_handler( PyObject *self, PyObject *other )
954 {
955 try
956 {
957 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
958 return new_reference_to( p->number_or( Py::Object( other ) ) );
959 }
960 catch( Py::Exception & )
961 {
962 return NULL; // indicate error
963 }
964 }
965
966extern "C" PyObject* number_power_handler( PyObject *self, PyObject *x1, PyObject *x2 )
967 {
968 try
969 {
970 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
971 return new_reference_to( p->number_power( Py::Object( x1 ), Py::Object( x2 ) ) );
972 }
973 catch( Py::Exception & )
974 {
975 return NULL; // indicate error
976 }
977 }
978
979// Buffer
980extern "C" Py_ssize_t buffer_getreadbuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
981 {
982 try
983 {
984 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
985 return p->buffer_getreadbuffer( index, pp );
986 }
987 catch( Py::Exception & )
988 {
989 return -1; // indicate error
990 }
991 }
992
993extern "C" Py_ssize_t buffer_getwritebuffer_handler( PyObject *self, Py_ssize_t index, void **pp )
994 {
995 try
996 {
997 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
998 return p->buffer_getwritebuffer( index, pp );
999 }
1000 catch( Py::Exception & )
1001 {
1002 return -1; // indicate error
1003 }
1004 }
1005
1006extern "C" Py_ssize_t buffer_getsegcount_handler( PyObject *self, Py_ssize_t *count )
1007 {
1008 try
1009 {
1010 PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
1011 int i_count = *count;
1012 Py_ssize_t r = p->buffer_getsegcount( &i_count );
1013 *count = i_count;
1014 return r;
1015 }
1016 catch( Py::Exception & )
1017 {
1018 return -1; // indicate error
1019 }
1020 }
1021
1022
1023//================================================================================
1024//
1025// Implementation of PythonExtensionBase
1026//
1027//================================================================================
1028#define missing_method( method ) \
1029throw RuntimeError( "Extension object does not support method " #method );
1030
1031PythonExtensionBase::PythonExtensionBase()
1032 {
1033 }
1034
1035PythonExtensionBase::~PythonExtensionBase()
1036 {
1037 assert( ob_refcnt == 0 );
1038 }
1039
1040int PythonExtensionBase::print( FILE *, int )
1041 { missing_method( print ); return -1; }
1042
1043int PythonExtensionBase::setattr( const char*, const Py::Object & )
1044 { missing_method( setattr ); return -1; }
1045
1046Py::Object PythonExtensionBase::getattro( const Py::Object & )
1047 { missing_method( getattro ); return Py::Nothing(); }
1048
1049int PythonExtensionBase::setattro( const Py::Object &, const Py::Object & )
1050 { missing_method( setattro ); return -1; }
1051
1052int PythonExtensionBase::compare( const Py::Object & )
1053 { missing_method( compare ); return -1; }
1054
1055Py::Object PythonExtensionBase::repr()
1056 { missing_method( repr ); return Py::Nothing(); }
1057
1058Py::Object PythonExtensionBase::str()
1059 { missing_method( str ); return Py::Nothing(); }
1060
1061long PythonExtensionBase::hash()
1062 { missing_method( hash ); return -1; }
1063
1064Py::Object PythonExtensionBase::call( const Py::Object &, const Py::Object & )
1065 { missing_method( call ); return Py::Nothing(); }
1066
1067
1068// Sequence methods
1069int PythonExtensionBase::sequence_length()
1070 { missing_method( sequence_length ); return -1; }
1071
1072Py::Object PythonExtensionBase::sequence_concat( const Py::Object & )
1073 { missing_method( sequence_concat ); return Py::Nothing(); }
1074
1075Py::Object PythonExtensionBase::sequence_repeat( int )
1076 { missing_method( sequence_repeat ); return Py::Nothing(); }
1077
1078Py::Object PythonExtensionBase::sequence_item( int )
1079 { missing_method( sequence_item ); return Py::Nothing(); }
1080
1081Py::Object PythonExtensionBase::sequence_slice( int, int )
1082 { missing_method( sequence_slice ); return Py::Nothing(); }
1083
1084int PythonExtensionBase::sequence_ass_item( int, const Py::Object & )
1085 { missing_method( sequence_ass_item ); return -1; }
1086
1087int PythonExtensionBase::sequence_ass_slice( int, int, const Py::Object & )
1088 { missing_method( sequence_ass_slice ); return -1; }
1089
1090
1091// Mapping
1092int PythonExtensionBase::mapping_length()
1093 { missing_method( mapping_length ); return -1; }
1094
1095Py::Object PythonExtensionBase::mapping_subscript( const Py::Object & )
1096 { missing_method( mapping_subscript ); return Py::Nothing(); }
1097
1098int PythonExtensionBase::mapping_ass_subscript( const Py::Object &, const Py::Object & )
1099 { missing_method( mapping_ass_subscript ); return -1; }
1100
1101
1102// Number
1103int PythonExtensionBase::number_nonzero()
1104 { missing_method( number_nonzero ); return -1; }
1105
1106Py::Object PythonExtensionBase::number_negative()
1107 { missing_method( number_negative ); return Py::Nothing(); }
1108
1109Py::Object PythonExtensionBase::number_positive()
1110 { missing_method( number_positive ); return Py::Nothing(); }
1111
1112Py::Object PythonExtensionBase::number_absolute()
1113 { missing_method( number_absolute ); return Py::Nothing(); }
1114
1115Py::Object PythonExtensionBase::number_invert()
1116 { missing_method( number_invert ); return Py::Nothing(); }
1117
1118Py::Object PythonExtensionBase::number_int()
1119 { missing_method( number_int ); return Py::Nothing(); }
1120
1121Py::Object PythonExtensionBase::number_float()
1122 { missing_method( number_float ); return Py::Nothing(); }
1123
1124Py::Object PythonExtensionBase::number_long()
1125 { missing_method( number_long ); return Py::Nothing(); }
1126
1127Py::Object PythonExtensionBase::number_oct()
1128 { missing_method( number_oct ); return Py::Nothing(); }
1129
1130Py::Object PythonExtensionBase::number_hex()
1131 { missing_method( number_hex ); return Py::Nothing(); }
1132
1133Py::Object PythonExtensionBase::number_add( const Py::Object & )
1134 { missing_method( number_add ); return Py::Nothing(); }
1135
1136Py::Object PythonExtensionBase::number_subtract( const Py::Object & )
1137 { missing_method( number_subtract ); return Py::Nothing(); }
1138
1139Py::Object PythonExtensionBase::number_multiply( const Py::Object & )
1140 { missing_method( number_multiply ); return Py::Nothing(); }
1141
1142Py::Object PythonExtensionBase::number_divide( const Py::Object & )
1143 { missing_method( number_divide ); return Py::Nothing(); }
1144
1145Py::Object PythonExtensionBase::number_remainder( const Py::Object & )
1146 { missing_method( number_remainder ); return Py::Nothing(); }
1147
1148Py::Object PythonExtensionBase::number_divmod( const Py::Object & )
1149 { missing_method( number_divmod ); return Py::Nothing(); }
1150
1151Py::Object PythonExtensionBase::number_lshift( const Py::Object & )
1152 { missing_method( number_lshift ); return Py::Nothing(); }
1153
1154Py::Object PythonExtensionBase::number_rshift( const Py::Object & )
1155 { missing_method( number_rshift ); return Py::Nothing(); }
1156
1157Py::Object PythonExtensionBase::number_and( const Py::Object & )
1158 { missing_method( number_and ); return Py::Nothing(); }
1159
1160Py::Object PythonExtensionBase::number_xor( const Py::Object & )
1161 { missing_method( number_xor ); return Py::Nothing(); }
1162
1163Py::Object PythonExtensionBase::number_or( const Py::Object & )
1164 { missing_method( number_or ); return Py::Nothing(); }
1165
1166Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Object & )
1167 { missing_method( number_power ); return Py::Nothing(); }
1168
1169
1170// Buffer
1171int PythonExtensionBase::buffer_getreadbuffer( int, void** )
1172 { missing_method( buffer_getreadbuffer ); return -1; }
1173
1174int PythonExtensionBase::buffer_getwritebuffer( int, void** )
1175 { missing_method( buffer_getwritebuffer ); return -1; }
1176
1177int PythonExtensionBase::buffer_getsegcount( int* )
1178 { missing_method( buffer_getsegcount ); return -1; }
1179
1180//--------------------------------------------------------------------------------
1181//
1182// Method call handlers for
1183// PythonExtensionBase
1184// ExtensionModuleBase
1185//
1186//--------------------------------------------------------------------------------
1187
1188extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
1189 {
1190 try
1191 {
1192 Tuple self_and_name_tuple( _self_and_name_tuple );
1193
1194 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1195 void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1196 if( self_as_void == NULL )
1197 return NULL;
1198
1199 ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1200
1201 String py_name( self_and_name_tuple[1] );
1202 std::string name( py_name.as_std_string() );
1203
1204 Tuple args( _args );
1205 if( _keywords == NULL )
1206 {
1207 Dict keywords; // pass an empty dict
1208
1209 Object result( self->invoke_method_keyword( name, args, keywords ) );
1210 return new_reference_to( result.ptr() );
1211 }
1212 else
1213 {
1214 Dict keywords( _keywords );
1215
1216 Object result( self->invoke_method_keyword( name, args, keywords ) );
1217 return new_reference_to( result.ptr() );
1218 }
1219 }
1220 catch( Exception & )
1221 {
1222 return 0;
1223 }
1224 }
1225
1226extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
1227 {
1228 try
1229 {
1230 Tuple self_and_name_tuple( _self_and_name_tuple );
1231
1232 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1233 void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject );
1234 if( self_as_void == NULL )
1235 return NULL;
1236
1237 ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1238
1239 String py_name( self_and_name_tuple[1] );
1240 std::string name( py_name.as_std_string() );
1241
1242 Tuple args( _args );
1243
1244 Object result( self->invoke_method_varargs( name, args ) );
1245
1246 return new_reference_to( result.ptr() );
1247 }
1248 catch( Exception & )
1249 {
1250 return 0;
1251 }
1252 }
1253
1254extern "C" void do_not_dealloc( void * )
1255 {}
1256
1257
1258//--------------------------------------------------------------------------------
1259//
1260// ExtensionExceptionType
1261//
1262//--------------------------------------------------------------------------------
1263ExtensionExceptionType::ExtensionExceptionType()
1264 : Py::Object()
1265 {
1266 }
1267
1268void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
1269 {
1270 std::string module_name( module.fullName() );
1271 module_name += ".";
1272 module_name += name;
1273
1274 set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
1275 }
1276
1277ExtensionExceptionType::~ExtensionExceptionType()
1278 {
1279 }
1280
1281Exception::Exception( ExtensionExceptionType &exception, const std::string& reason )
1282 {
1283 PyErr_SetString (exception.ptr(), reason.c_str());
1284 }
1285
1286
1287} // end of namespace Py
const char * name(StdAction id)
@ String
string
Definition property.h:71