1 //-----------------------------------------------------------------------------
2 //
3 // Copyright (c) 1998 - 2007, The Regents of the University of California
4 // Produced at the Lawrence Livermore National Laboratory
5 // All rights reserved.
6 //
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.
10 //
11 // Redistribution  and  use  in  source  and  binary  forms,  with  or  without
12 // modification, are permitted provided that the following conditions are met:
13 //
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.
22 //
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
34 // DAMAGE.
35 //
36 //-----------------------------------------------------------------------------
37 #include "CXX/Extensions.hxx"
38 #include "CXX/Exception.hxx"
39 #include "CXX/Objects.hxx"
40 
41 #include <assert.h>
42 
43 #ifdef PYCXX_DEBUG
44 //
45 //  Functions useful when debugging PyCXX
46 //
bpt(void)47 void bpt( void )
48 {
49 }
50 
printRefCount(PyObject * obj)51 void printRefCount( PyObject *obj )
52 {
53     std::cout << "RefCount of 0x" << std::hex << reinterpret_cast< unsigned long >( obj ) << std::dec << " is " << Py_REFCNT( obj ) << std::endl;
54 }
55 #endif
56 
57 namespace Py
58 {
59 
validate()60 void Object::validate()
61 {
62     // release pointer if not the right type
63     if( !accepts( p ) )
64     {
65 #if defined( _CPPRTTI ) || defined( __GNUG__ )
66         std::string s( "PyCXX: Error creating object of type " );
67         s += (typeid( *this )).name();
68 
69         if( p != NULL )
70         {
71             String from_repr = repr();
72             s += " from ";
73             s += from_repr.as_std_string();
74         }
75         else
76         {
77             s += " from (nil)";
78         }
79 #endif
80         release();
81 
82         // If error message already set
83         ifPyErrorThrowCxxException();
84 
85         // Better error message if RTTI available
86 #if defined( _CPPRTTI ) || defined( __GNUG__ )
87         throw TypeError( s );
88 #else
89         throw TypeError( "PyCXX: type error." );
90 #endif
91     }
92 }
93 
94 //================================================================================
95 //
96 //    Implementation of MethodTable
97 //
98 //================================================================================
99 
method(const char * method_name,PyCFunction f,int flags,const char * doc)100 PyMethodDef MethodTable::method( const char *method_name, PyCFunction f, int flags, const char *doc )
101 {
102     PyMethodDef m;
103     m.ml_name = const_cast<char *>( method_name );
104     m.ml_meth = f;
105     m.ml_flags = flags;
106     m.ml_doc = const_cast<char *>( doc );
107     return m;
108 }
109 
MethodTable()110 MethodTable::MethodTable()
111 {
112     t.push_back( method( 0, 0, 0, 0 ) );
113     mt = NULL;
114 }
115 
~MethodTable()116 MethodTable::~MethodTable()
117 {
118     delete [] mt;
119 }
120 
add(const char * method_name,PyCFunction f,const char * doc,int flag)121 void MethodTable::add( const char *method_name, PyCFunction f, const char *doc, int flag )
122 {
123     if( !mt )
124     {
125         t.insert( t.end()-1, method( method_name, f, flag, doc ) );
126     }
127     else
128     {
129         throw RuntimeError( "Too late to add a module method!" );
130     }
131 }
132 
table()133 PyMethodDef *MethodTable::table()
134 {
135     if( !mt )
136     {
137         Py_ssize_t t1size = t.size();
138         mt = new PyMethodDef[ t1size ];
139         int j = 0;
140         for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ )
141         {
142             mt[ j++ ] = *i;
143         }
144     }
145     return mt;
146 }
147 
148 //================================================================================
149 //
150 //    Implementation of ExtensionModule
151 //
152 //================================================================================
ExtensionModuleBase(const char * name)153 ExtensionModuleBase::ExtensionModuleBase( const char *name )
154 : m_module_name( name )
155 #if defined( Py_LIMITED_API )
156 , m_full_module_name( m_module_name )
157 #else
158 , m_full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : m_module_name )
159 #endif
160 , m_method_table()
161 //m_module_def
162 , m_module( NULL )
163 {}
164 
~ExtensionModuleBase()165 ExtensionModuleBase::~ExtensionModuleBase()
166 {}
167 
name() const168 const std::string &ExtensionModuleBase::name() const
169 {
170     return m_module_name;
171 }
172 
fullName() const173 const std::string &ExtensionModuleBase::fullName() const
174 {
175     return m_full_module_name;
176 }
177 
178 class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr>
179 {
180 public:
ExtensionModuleBasePtr(ExtensionModuleBase * _module)181     ExtensionModuleBasePtr( ExtensionModuleBase *_module )
182     : module( _module )
183     {}
184 
~ExtensionModuleBasePtr()185     virtual ~ExtensionModuleBasePtr()
186     {}
187 
188     ExtensionModuleBase *module;
189 };
190 
191 void initExceptions();
192 
initialize(const char * module_doc)193 void ExtensionModuleBase::initialize( const char *module_doc )
194 {
195     // init the exception code
196     initExceptions();
197 
198     memset( &m_module_def, 0, sizeof( m_module_def ) );
199 
200     m_module_def.m_name = const_cast<char *>( m_module_name.c_str() );
201     m_module_def.m_doc = const_cast<char *>( module_doc );
202     m_module_def.m_methods = m_method_table.table();
203     // where does module_ptr get passed in?
204 
205     m_module = PyModule_Create( &m_module_def );
206 }
207 
module(void) const208 Module ExtensionModuleBase::module( void ) const
209 {
210     return Module( m_module );
211 }
212 
moduleDictionary(void) const213 Dict ExtensionModuleBase::moduleDictionary( void ) const
214 {
215     return module().getDict();
216 }
217 
moduleObject(void) const218 Object ExtensionModuleBase::moduleObject( void ) const
219 {
220     return Object( m_module );
221 }
222 
223 //================================================================================
224 //
225 //    Implementation of PythonType
226 //
227 //================================================================================
228 extern "C"
229 {
230     static void standard_dealloc( PyObject *p );
231     //
232     // All the following functions redirect the call from Python
233     // onto the matching virtual function in PythonExtensionBase
234     //
235 #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7
236     static int print_handler( PyObject *, FILE *, int );
237 #endif
238     static PyObject *getattr_handler( PyObject *, char * );
239     static int setattr_handler( PyObject *, char *, PyObject * );
240     static PyObject *getattro_handler( PyObject *, PyObject * );
241     static int setattro_handler( PyObject *, PyObject *, PyObject * );
242     static PyObject *rich_compare_handler( PyObject *, PyObject *, int );
243     static PyObject *repr_handler( PyObject * );
244     static PyObject *str_handler( PyObject * );
245     static Py_hash_t hash_handler( PyObject * );
246     static PyObject *call_handler( PyObject *, PyObject *, PyObject * );
247     static PyObject *iter_handler( PyObject * );
248     static PyObject *iternext_handler( PyObject * );
249 
250     // Sequence methods
251     static Py_ssize_t sequence_length_handler( PyObject * );
252     static PyObject *sequence_concat_handler( PyObject *,PyObject * );
253     static PyObject *sequence_repeat_handler( PyObject *, Py_ssize_t );
254     static PyObject *sequence_item_handler( PyObject *, Py_ssize_t );
255     static int sequence_ass_item_handler( PyObject *, Py_ssize_t, PyObject * );
256 
257     static PyObject *sequence_inplace_concat_handler( PyObject *, PyObject * );
258     static PyObject *sequence_inplace_repeat_handler( PyObject *, Py_ssize_t );
259 
260     static int sequence_contains_handler( PyObject *, PyObject * );
261 
262     // Mapping
263     static Py_ssize_t mapping_length_handler( PyObject * );
264     static PyObject *mapping_subscript_handler( PyObject *, PyObject * );
265     static int mapping_ass_subscript_handler( PyObject *, PyObject *, PyObject * );
266 
267     // Numeric methods
268     static PyObject *number_negative_handler( PyObject * );
269     static PyObject *number_positive_handler( PyObject * );
270     static PyObject *number_absolute_handler( PyObject * );
271     static PyObject *number_invert_handler( PyObject * );
272     static PyObject *number_int_handler( PyObject * );
273     static PyObject *number_float_handler( PyObject * );
274     static PyObject *number_add_handler( PyObject *, PyObject * );
275     static PyObject *number_subtract_handler( PyObject *, PyObject * );
276     static PyObject *number_multiply_handler( PyObject *, PyObject * );
277     static PyObject *number_remainder_handler( PyObject *, PyObject * );
278     static PyObject *number_divmod_handler( PyObject *, PyObject * );
279     static PyObject *number_lshift_handler( PyObject *, PyObject * );
280     static PyObject *number_rshift_handler( PyObject *, PyObject * );
281     static PyObject *number_and_handler( PyObject *, PyObject * );
282     static PyObject *number_xor_handler( PyObject *, PyObject * );
283     static PyObject *number_or_handler( PyObject *, PyObject * );
284     static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * );
285     static PyObject *number_floor_divide_handler( PyObject *, PyObject * );
286     static PyObject *number_true_divide_handler( PyObject *, PyObject * );
287     static PyObject *number_index_handler( PyObject * );
288 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
289     static PyObject *number_matrix_multiply_handler( PyObject *, PyObject * );
290 #endif
291 
292     static PyObject *number_inplace_add_handler( PyObject *, PyObject * );
293     static PyObject *number_inplace_subtract_handler( PyObject *, PyObject * );
294     static PyObject *number_inplace_multiply_handler( PyObject *, PyObject * );
295     static PyObject *number_inplace_remainder_handler( PyObject *, PyObject * );
296     static PyObject *number_inplace_power_handler( PyObject *, PyObject *, PyObject * );
297     static PyObject *number_inplace_lshift_handler( PyObject *, PyObject * );
298     static PyObject *number_inplace_rshift_handler( PyObject *, PyObject * );
299     static PyObject *number_inplace_and_handler( PyObject *, PyObject * );
300     static PyObject *number_inplace_xor_handler( PyObject *, PyObject * );
301     static PyObject *number_inplace_or_handler( PyObject *, PyObject * );
302     static PyObject *number_inplace_floor_divide_handler( PyObject *, PyObject * );
303     static PyObject *number_inplace_true_divide_handler( PyObject *, PyObject * );
304 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
305     static PyObject *number_inplace_matrix_multiply_handler( PyObject *, PyObject * );
306 #endif
307 
308     // Buffer
309 #if !defined( Py_LIMITED_API )
310     static int buffer_get_handler( PyObject *, Py_buffer *, int );
311     static void buffer_release_handler( PyObject *, Py_buffer * );
312 #endif
313 }
314 
standard_dealloc(PyObject * p)315 extern "C" void standard_dealloc( PyObject *p )
316 {
317     PyMem_DEL( p );
318 }
319 
readyType()320 bool PythonType::readyType()
321 {
322 #if defined( Py_LIMITED_API )
323     if( !tp_object )
324     {
325         std::vector<PyType_Slot> spec_slots( slots.size() + 1 );
326         int index = 0;
327 
328         for (std::unordered_map<int, void*>::const_iterator i = slots.cbegin(); i != slots.cend(); i++)
329         {
330             spec_slots[ index ].slot = i->first;
331             spec_slots[ index ].pfunc = i->second;
332             index++;
333         }
334         spec_slots[ index ].slot = 0;
335         spec->slots = spec_slots.data();
336         tp_object = reinterpret_cast<PyTypeObject *>( PyType_FromSpec(spec) );
337     }
338     return tp_object != NULL;
339 #else
340     return PyType_Ready( table ) >= 0;
341 #endif
342 }
343 
344 #if defined( Py_LIMITED_API )
345 #define FILL_SEQUENCE_SLOT(slot) \
346     if( methods_to_support&support_sequence_ ## slot ) { \
347         slots[ Py_sq_ ## slot ] = reinterpret_cast<void *>( sequence_ ## slot ## _handler ); \
348     }
349 #else
350 #define FILL_SEQUENCE_SLOT(slot) \
351     if( methods_to_support&support_sequence_ ## slot ) { \
352         sequence_table->sq_ ## slot = sequence_ ## slot ## _handler; \
353     }
354 #endif
355 
supportSequenceType(int methods_to_support)356 PythonType &PythonType::supportSequenceType( int methods_to_support ) {
357 #if !defined( Py_LIMITED_API )
358     if(sequence_table)
359     {
360         return *this;
361     }
362     sequence_table = new PySequenceMethods;
363     memset( sequence_table, 0, sizeof( PySequenceMethods ) );   // ensure new fields are 0
364     table->tp_as_sequence = sequence_table;
365 #endif
366 
367     FILL_SEQUENCE_SLOT(length)
368     FILL_SEQUENCE_SLOT(concat)
369     FILL_SEQUENCE_SLOT(repeat)
370     FILL_SEQUENCE_SLOT(item)
371     FILL_SEQUENCE_SLOT(ass_item)
372     FILL_SEQUENCE_SLOT(inplace_concat)
373     FILL_SEQUENCE_SLOT(inplace_repeat)
374     FILL_SEQUENCE_SLOT(contains)
375     return *this;
376 }
377 
378 #undef FILL_SEQUENCE_SLOT
379 
380 #if defined( Py_LIMITED_API )
381 #define FILL_MAPPING_SLOT(slot) \
382     if( methods_to_support&support_mapping_ ## slot ) { \
383         slots[ Py_mp_ ## slot ] = reinterpret_cast<void *>( mapping_ ## slot ## _handler ); \
384     }
385 #else
386 #define FILL_MAPPING_SLOT(slot) \
387     if( methods_to_support&support_mapping_ ## slot ) { \
388         mapping_table->mp_ ## slot = mapping_ ## slot ## _handler; \
389     }
390 #endif
391 
supportMappingType(int methods_to_support)392 PythonType &PythonType::supportMappingType( int methods_to_support )
393 {
394 #if !defined( Py_LIMITED_API )
395     if( mapping_table )
396     {
397         return *this;
398     }
399     mapping_table = new PyMappingMethods;
400     memset( mapping_table, 0, sizeof( PyMappingMethods ) );   // ensure new fields are 0
401     table->tp_as_mapping = mapping_table;
402 #endif
403     FILL_MAPPING_SLOT(length)
404     FILL_MAPPING_SLOT(subscript)
405     FILL_MAPPING_SLOT(ass_subscript)
406     return *this;
407 }
408 
409 #undef FILL_MAPPING_SLOT
410 
411 #if defined( Py_LIMITED_API )
412 #define FILL_NUMBER_SLOT(slot) \
413     if( methods_to_support&support_number_ ## slot ) { \
414         slots[ Py_nb_ ## slot ] = reinterpret_cast<void *>( number_ ## slot ## _handler ); \
415     }
416 #define FILL_NUMBER_INPLACE_SLOT(slot) \
417     if( inplace_methods_to_support&support_number_ ## slot ) { \
418         slots[ Py_nb_ ## slot ] = reinterpret_cast<void *>( number_ ## slot ## _handler ); \
419     }
420 #else
421 #define FILL_NUMBER_SLOT(slot) \
422     if( methods_to_support&support_number_ ## slot ) { \
423         number_table->nb_ ## slot = number_ ## slot ## _handler; \
424     }
425 #define FILL_NUMBER_INPLACE_SLOT(slot) \
426     if( inplace_methods_to_support&support_number_ ## slot ) { \
427         number_table->nb_ ## slot = number_ ## slot ## _handler; \
428     }
429 #endif
430 
supportNumberType(int methods_to_support,int inplace_methods_to_support)431 PythonType &PythonType::supportNumberType( int methods_to_support, int inplace_methods_to_support )
432 {
433 #if !defined( Py_LIMITED_API )
434     if( number_table )
435     {
436         return *this;
437     }
438     number_table = new PyNumberMethods;
439     memset( number_table, 0, sizeof( PyNumberMethods ) );   // ensure new fields are 0
440     table->tp_as_number = number_table;
441 #endif
442 
443     FILL_NUMBER_SLOT(add)
444     FILL_NUMBER_SLOT(subtract)
445     FILL_NUMBER_SLOT(multiply)
446     FILL_NUMBER_SLOT(remainder)
447     FILL_NUMBER_SLOT(divmod)
448     FILL_NUMBER_SLOT(power)
449     FILL_NUMBER_SLOT(negative)
450     FILL_NUMBER_SLOT(positive)
451     FILL_NUMBER_SLOT(absolute)
452     FILL_NUMBER_SLOT(invert)
453     FILL_NUMBER_SLOT(lshift)
454     FILL_NUMBER_SLOT(rshift)
455     FILL_NUMBER_SLOT(and)
456     FILL_NUMBER_SLOT(xor)
457     FILL_NUMBER_SLOT(or)
458     FILL_NUMBER_SLOT(int)
459     FILL_NUMBER_SLOT(float)
460     FILL_NUMBER_SLOT(floor_divide)
461     FILL_NUMBER_SLOT(true_divide)
462     FILL_NUMBER_SLOT(index)
463 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
464     FILL_NUMBER_SLOT(matrix_multiply)
465 #endif
466 
467     FILL_NUMBER_INPLACE_SLOT(inplace_add)
468     FILL_NUMBER_INPLACE_SLOT(inplace_subtract)
469     FILL_NUMBER_INPLACE_SLOT(inplace_multiply)
470     FILL_NUMBER_INPLACE_SLOT(inplace_remainder)
471     FILL_NUMBER_INPLACE_SLOT(inplace_power)
472     FILL_NUMBER_INPLACE_SLOT(inplace_lshift)
473     FILL_NUMBER_INPLACE_SLOT(inplace_rshift)
474     FILL_NUMBER_INPLACE_SLOT(inplace_and)
475     FILL_NUMBER_INPLACE_SLOT(inplace_xor)
476     FILL_NUMBER_INPLACE_SLOT(inplace_or)
477     FILL_NUMBER_INPLACE_SLOT(inplace_floor_divide)
478     FILL_NUMBER_INPLACE_SLOT(inplace_true_divide)
479 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
480     FILL_NUMBER_INPLACE_SLOT(inplace_matrix_multiply)
481 #endif
482 
483     return *this;
484 }
485 
486 #undef FILL_NUMBER_SLOT
487 
488 #if !defined( Py_LIMITED_API )
supportBufferType(int methods_to_support)489 PythonType &PythonType::supportBufferType( int methods_to_support )
490 {
491     if( !buffer_table )
492     {
493         buffer_table = new PyBufferProcs;
494         memset( buffer_table, 0, sizeof( PyBufferProcs ) );   // ensure new fields are 0
495         table->tp_as_buffer = buffer_table;
496 
497         if( methods_to_support&support_buffer_getbuffer )
498         {
499             buffer_table->bf_getbuffer = buffer_get_handler;
500         }
501         if( methods_to_support&support_buffer_releasebuffer )
502         {
503             buffer_table->bf_releasebuffer = buffer_release_handler;
504         }
505     }
506     return *this;
507 }
508 #endif
509 
510 // if you define one sequence method you must define
511 // all of them except the assigns
512 
513 #if defined( Py_LIMITED_API )
PythonType(size_t basic_size,int itemsize,const char * default_name)514 PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
515 : spec( new PyType_Spec )
516 {
517     memset( spec, 0, sizeof( PyType_Spec ) );
518     spec->name = const_cast<char *>( default_name );
519     spec->basicsize = basic_size;
520     spec->itemsize = itemsize;
521     spec->flags = Py_TPFLAGS_DEFAULT;
522 
523     slots[ Py_tp_dealloc ] = reinterpret_cast<void *>( standard_dealloc );
524 
525     tp_object = 0;
526 }
527 
528 #else
PythonType(size_t basic_size,int itemsize,const char * default_name)529 PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
530 : table( new PyTypeObject )
531 , sequence_table( NULL )
532 , mapping_table( NULL )
533 , number_table( NULL )
534 , buffer_table( NULL )
535 {
536     // PyTypeObject is defined in <python-sources>/Include/object.h
537 
538     memset( table, 0, sizeof( PyTypeObject ) );   // ensure new fields are 0
539     *reinterpret_cast<PyObject *>( table ) = py_object_initializer;
540     reinterpret_cast<PyObject *>( table )->ob_type = _Type_Type();
541     // QQQ table->ob_size = 0;
542     table->tp_name = const_cast<char *>( default_name );
543     table->tp_basicsize = basic_size;
544     table->tp_itemsize = itemsize;
545 
546     // Methods to implement standard operations
547     table->tp_dealloc = (destructor)standard_dealloc;
548 #if PY_MINOR_VERSION <= 7
549     table->tp_print = 0;
550 #endif
551     table->tp_getattr = 0;
552     table->tp_setattr = 0;
553     table->tp_repr = 0;
554 
555     // Method suites for standard classes
556     table->tp_as_number = 0;
557     table->tp_as_sequence = 0;
558     table->tp_as_mapping =  0;
559 
560     // More standard operations (here for binary compatibility)
561     table->tp_hash = 0;
562     table->tp_call = 0;
563     table->tp_str = 0;
564     table->tp_getattro = 0;
565     table->tp_setattro = 0;
566 
567     // Functions to access object as input/output buffer
568     table->tp_as_buffer = 0;
569 
570     // Flags to define presence of optional/expanded features
571     table->tp_flags = Py_TPFLAGS_DEFAULT;
572 
573     // Documentation string
574     table->tp_doc = 0;
575 
576     table->tp_traverse = 0;
577 
578     // delete references to contained objects
579     table->tp_clear = 0;
580 
581     // Assigned meaning in release 2.1
582     // rich comparisons
583     table->tp_richcompare = 0;
584     // weak reference enabler
585     table->tp_weaklistoffset = 0;
586 
587     // Iterators
588     table->tp_iter = 0;
589     table->tp_iternext = 0;
590 
591     // Attribute descriptor and subclassing stuff
592     table->tp_methods = 0;
593     table->tp_members = 0;
594     table->tp_getset = 0;
595     table->tp_base = 0;
596     table->tp_dict = 0;
597     table->tp_descr_get = 0;
598     table->tp_descr_set = 0;
599     table->tp_dictoffset = 0;
600     table->tp_init = 0;
601     table->tp_alloc = 0;
602     table->tp_new = 0;
603     table->tp_free = 0;     // Low-level free-memory routine
604     table->tp_is_gc = 0;    // For PyObject_IS_GC
605     table->tp_bases = 0;
606     table->tp_mro = 0;      // method resolution order
607     table->tp_cache = 0;
608     table->tp_subclasses = 0;
609     table->tp_weaklist = 0;
610     table->tp_del = 0;
611 
612     // Type attribute cache version tag. Added in version 2.6
613     table->tp_version_tag = 0;
614 
615 #ifdef COUNT_ALLOCS
616     table->tp_alloc = 0;
617     table->tp_free = 0;
618     table->tp_maxalloc = 0;
619     table->tp_orev = 0;
620     table->tp_next = 0;
621 #endif
622 }
623 #endif
624 
~PythonType()625 PythonType::~PythonType()
626 {
627 #if defined( Py_LIMITED_API )
628     delete spec;
629     PyObject_Free( tp_object );
630 #else
631     delete table;
632     delete sequence_table;
633     delete mapping_table;
634     delete number_table;
635     delete buffer_table;
636 #endif
637 }
638 
type_object() const639 PyTypeObject *PythonType::type_object() const
640 {
641 #if defined( Py_LIMITED_API )
642     return tp_object;
643 #else
644     return table;
645 #endif
646 }
647 
name(const char * nam)648 PythonType &PythonType::name( const char *nam )
649 {
650 #if defined( Py_LIMITED_API )
651     spec->name = nam;
652 #else
653     table->tp_name = const_cast<char *>( nam );
654 #endif
655     return *this;
656 }
657 
getName() const658 const char *PythonType::getName() const
659 {
660 #if defined( Py_LIMITED_API )
661     return spec->name;
662 #else
663     return table->tp_name;
664 #endif
665 }
666 
doc(const char * d)667 PythonType &PythonType::doc( const char *d )
668 {
669 #if defined( Py_LIMITED_API )
670     slots[ Py_tp_doc ] = reinterpret_cast<void *>( const_cast<char *>( d ) );
671 #else
672     table->tp_doc = const_cast<char *>( d );
673 #endif
674     return *this;
675 }
676 
getDoc() const677 const char *PythonType::getDoc() const
678 {
679 #if defined( Py_LIMITED_API )
680     if( tp_object )
681         return reinterpret_cast<char *>( PyType_GetSlot( tp_object, Py_tp_doc ) );
682 
683     std::unordered_map<int, void*>::const_iterator slot = slots.find( Py_tp_doc );
684     if( slot == slots.end() )
685         return NULL;
686     return reinterpret_cast<char *>( slot->second );
687 #else
688     return table->tp_doc;
689 #endif
690 }
691 
set_tp_dealloc(void (* tp_dealloc)(PyObject * self))692 PythonType &PythonType::set_tp_dealloc( void (*tp_dealloc)( PyObject *self ) )
693 {
694 #if defined( Py_LIMITED_API )
695     slots[ Py_tp_dealloc ] = reinterpret_cast<void *>( tp_dealloc );
696 #else
697     table->tp_dealloc = tp_dealloc;
698 #endif
699     return *this;
700 }
701 
set_tp_init(int (* tp_init)(PyObject * self,PyObject * args,PyObject * kwds))702 PythonType &PythonType::set_tp_init( int (*tp_init)( PyObject *self, PyObject *args, PyObject *kwds ) )
703 {
704 #if defined( Py_LIMITED_API )
705     slots[ Py_tp_init ] = reinterpret_cast<void *>( tp_init );
706 #else
707     table->tp_init = tp_init;
708 #endif
709     return *this;
710 }
711 
set_tp_new(PyObject * (* tp_new)(PyTypeObject * subtype,PyObject * args,PyObject * kwds))712 PythonType &PythonType::set_tp_new( PyObject *(*tp_new)( PyTypeObject *subtype, PyObject *args, PyObject *kwds ) )
713 {
714 #if defined( Py_LIMITED_API )
715     slots[ Py_tp_new ] = reinterpret_cast<void *>( tp_new );
716 #else
717     table->tp_new = tp_new;
718 #endif
719     return *this;
720 }
721 
set_methods(PyMethodDef * methods)722 PythonType &PythonType::set_methods( PyMethodDef *methods )
723 {
724 #if defined( Py_LIMITED_API )
725     slots[ Py_tp_methods ] = reinterpret_cast<void *>( methods );
726 #else
727     table->tp_methods = methods;
728 #endif
729     return *this;
730 }
731 
supportClass()732 PythonType &PythonType::supportClass()
733 {
734 #if defined( Py_LIMITED_API )
735     spec->flags |= Py_TPFLAGS_BASETYPE;
736 #else
737     table->tp_flags |= Py_TPFLAGS_BASETYPE;
738 #endif
739     return *this;
740 }
741 
742 #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7
supportPrint()743 PythonType &PythonType::supportPrint()
744 {
745     table->tp_print = print_handler;
746     return *this;
747 }
748 #endif
749 
supportGetattr()750 PythonType &PythonType::supportGetattr()
751 {
752 #if defined( Py_LIMITED_API )
753     slots[ Py_tp_getattr ] = reinterpret_cast<void *>( getattr_handler );
754 #else
755     table->tp_getattr = getattr_handler;
756 #endif
757     return *this;
758 }
759 
supportSetattr()760 PythonType &PythonType::supportSetattr()
761 {
762 #if defined( Py_LIMITED_API )
763     slots[ Py_tp_setattr ] = reinterpret_cast<void *>( setattr_handler );
764 #else
765     table->tp_setattr = setattr_handler;
766 #endif
767     return *this;
768 }
769 
supportGetattro()770 PythonType &PythonType::supportGetattro()
771 {
772 #if defined( Py_LIMITED_API )
773     slots[ Py_tp_getattro ] = reinterpret_cast<void *>( getattro_handler );
774 #else
775     table->tp_getattro = getattro_handler;
776 #endif
777     return *this;
778 }
779 
supportSetattro()780 PythonType &PythonType::supportSetattro()
781 {
782 #if defined( Py_LIMITED_API )
783     slots[ Py_tp_setattro ] = reinterpret_cast<void *>( setattro_handler );
784 #else
785     table->tp_setattro = setattro_handler;
786 #endif
787     return *this;
788 }
789 
790 #ifdef PYCXX_PYTHON_2TO3
supportCompare(void)791 PythonType &PythonType::supportCompare( void )
792 {
793     return *this;
794 }
795 #endif
796 
797 
supportRichCompare()798 PythonType &PythonType::supportRichCompare()
799 {
800 #if defined( Py_LIMITED_API )
801     slots[ Py_tp_richcompare ] = reinterpret_cast<void *>( rich_compare_handler );
802 #else
803     table->tp_richcompare = rich_compare_handler;
804 #endif
805     return *this;
806 }
807 
supportRepr()808 PythonType &PythonType::supportRepr()
809 {
810 #if defined( Py_LIMITED_API )
811     slots[ Py_tp_repr ] = reinterpret_cast<void *>( repr_handler );
812 #else
813     table->tp_repr = repr_handler;
814 #endif
815     return *this;
816 }
817 
supportStr()818 PythonType &PythonType::supportStr()
819 {
820 #if defined( Py_LIMITED_API )
821     slots[ Py_tp_str ] = reinterpret_cast<void *>( str_handler );
822 #else
823     table->tp_str = str_handler;
824 #endif
825     return *this;
826 }
827 
supportHash()828 PythonType &PythonType::supportHash()
829 {
830 #if defined( Py_LIMITED_API )
831     slots[ Py_tp_hash ] = reinterpret_cast<void *>( hash_handler );
832 #else
833     table->tp_hash = hash_handler;
834 #endif
835     return *this;
836 }
837 
supportCall()838 PythonType &PythonType::supportCall()
839 {
840 #if defined( Py_LIMITED_API )
841     slots[ Py_tp_call ] = reinterpret_cast<void *>( call_handler );
842 #else
843     table->tp_call = call_handler;
844 #endif
845     return *this;
846 }
847 
supportIter(int methods_to_support)848 PythonType &PythonType::supportIter( int methods_to_support )
849 {
850     if( methods_to_support&support_iter_iter )
851     {
852 #if defined( Py_LIMITED_API )
853         slots[ Py_tp_iter ] = reinterpret_cast<void *>( iter_handler );
854 #else
855         table->tp_iter = iter_handler;
856 #endif
857     }
858     if( methods_to_support&support_iter_iternext )
859     {
860 #if defined( Py_LIMITED_API )
861         slots[ Py_tp_iternext ] = reinterpret_cast<void *>( iternext_handler );
862 #else
863         table->tp_iternext = iternext_handler;
864 #endif
865     }
866     return *this;
867 }
868 
869 //--------------------------------------------------------------------------------
870 //
871 //    Handlers
872 //
873 //--------------------------------------------------------------------------------
getPythonExtensionBase(PyObject * self)874 PythonExtensionBase *getPythonExtensionBase( PyObject *self )
875 {
876     if(PyType_HasFeature(self->ob_type, Py_TPFLAGS_BASETYPE))
877     {
878         PythonClassInstance *instance = reinterpret_cast<PythonClassInstance *>( self );
879         return instance->m_pycxx_object;
880     }
881     else
882     {
883         return static_cast<PythonExtensionBase *>( self );
884     }
885 }
886 
887 #if defined( PYCXX_PYTHON_2TO3 ) && !defined ( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7
print_handler(PyObject * self,FILE * fp,int flags)888 extern "C" int print_handler( PyObject *self, FILE *fp, int flags )
889 {
890     try
891     {
892         PythonExtensionBase *p = getPythonExtensionBase( self );
893         return p->print( fp, flags );
894     }
895     catch( BaseException & )
896     {
897         return -1;    // indicate error
898     }
899 }
900 #endif
901 
getattr_handler(PyObject * self,char * name)902 extern "C" PyObject *getattr_handler( PyObject *self, char *name )
903 {
904     try
905     {
906         PythonExtensionBase *p = getPythonExtensionBase( self );
907         return new_reference_to( p->getattr( name ) );
908     }
909     catch( BaseException & )
910     {
911         return NULL;    // indicate error
912     }
913 }
914 
setattr_handler(PyObject * self,char * name,PyObject * value)915 extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value )
916 {
917     try
918     {
919         PythonExtensionBase *p = getPythonExtensionBase( self );
920         return p->setattr( name, Object( value ) );
921     }
922     catch( BaseException & )
923     {
924         return -1;    // indicate error
925     }
926 }
927 
getattro_handler(PyObject * self,PyObject * name)928 extern "C" PyObject *getattro_handler( PyObject *self, PyObject *name )
929 {
930     try
931     {
932         PythonExtensionBase *p = getPythonExtensionBase( self );
933         return new_reference_to( p->getattro( String( name ) ) );
934     }
935     catch( BaseException & )
936     {
937         return NULL;    // indicate error
938     }
939 }
940 
setattro_handler(PyObject * self,PyObject * name,PyObject * value)941 extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value )
942 {
943     try
944     {
945         PythonExtensionBase *p = getPythonExtensionBase( self );
946         return p->setattro( String( name ), Object( value ) );
947     }
948     catch( BaseException & )
949     {
950         return -1;    // indicate error
951     }
952 }
953 
rich_compare_handler(PyObject * self,PyObject * other,int op)954 extern "C" PyObject *rich_compare_handler( PyObject *self, PyObject *other, int op )
955 {
956     try
957     {
958         PythonExtensionBase *p = getPythonExtensionBase( self );
959         return new_reference_to( p->rich_compare( Object( other ), op ) );
960     }
961     catch( BaseException & )
962     {
963         return NULL;    // indicate error
964     }
965 }
966 
repr_handler(PyObject * self)967 extern "C" PyObject *repr_handler( PyObject *self )
968 {
969     try
970     {
971         PythonExtensionBase *p = getPythonExtensionBase( self );
972         return new_reference_to( p->repr() );
973     }
974     catch( BaseException & )
975     {
976         return NULL;    // indicate error
977     }
978 }
979 
str_handler(PyObject * self)980 extern "C" PyObject *str_handler( PyObject *self )
981 {
982     try
983     {
984         PythonExtensionBase *p = getPythonExtensionBase( self );
985         return new_reference_to( p->str() );
986     }
987     catch( BaseException & )
988     {
989         return NULL;    // indicate error
990     }
991 }
992 
hash_handler(PyObject * self)993 extern "C" Py_hash_t hash_handler( PyObject *self )
994 {
995     try
996     {
997         PythonExtensionBase *p = getPythonExtensionBase( self );
998         return p->hash();
999     }
1000     catch( BaseException & )
1001     {
1002         return -1;    // indicate error
1003     }
1004 }
1005 
call_handler(PyObject * self,PyObject * args,PyObject * kw)1006 extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
1007 {
1008     try
1009     {
1010         PythonExtensionBase *p = getPythonExtensionBase( self );
1011         if( kw != NULL )
1012             return new_reference_to( p->call( Object( args ), Object( kw ) ) );
1013         else
1014             return new_reference_to( p->call( Object( args ), Object() ) );
1015     }
1016     catch( BaseException & )
1017     {
1018         return NULL;    // indicate error
1019     }
1020 }
1021 
iter_handler(PyObject * self)1022 extern "C" PyObject *iter_handler( PyObject *self )
1023 {
1024     try
1025     {
1026         PythonExtensionBase *p = getPythonExtensionBase( self );
1027         return new_reference_to( p->iter() );
1028     }
1029     catch( BaseException & )
1030     {
1031         return NULL;    // indicate error
1032     }
1033 }
1034 
iternext_handler(PyObject * self)1035 extern "C" PyObject *iternext_handler( PyObject *self )
1036 {
1037     try
1038     {
1039         PythonExtensionBase *p = getPythonExtensionBase( self );
1040         return p->iternext();  // might be a NULL ptr on end of iteration
1041     }
1042     catch( BaseException & )
1043     {
1044         return NULL;    // indicate error
1045     }
1046 }
1047 
1048 
1049 // Sequence methods
sequence_length_handler(PyObject * self)1050 extern "C" Py_ssize_t sequence_length_handler( PyObject *self )
1051 {
1052     try
1053     {
1054         PythonExtensionBase *p = getPythonExtensionBase( self );
1055         return p->sequence_length();
1056     }
1057     catch( BaseException & )
1058     {
1059         return -1;    // indicate error
1060     }
1061 }
1062 
sequence_concat_handler(PyObject * self,PyObject * other)1063 extern "C" PyObject *sequence_concat_handler( PyObject *self, PyObject *other )
1064 {
1065     try
1066     {
1067         PythonExtensionBase *p = getPythonExtensionBase( self );
1068         return new_reference_to( p->sequence_concat( Object( other ) ) );
1069     }
1070     catch( BaseException & )
1071     {
1072         return NULL;    // indicate error
1073     }
1074 }
1075 
sequence_repeat_handler(PyObject * self,Py_ssize_t count)1076 extern "C" PyObject *sequence_repeat_handler( PyObject *self, Py_ssize_t count )
1077 {
1078     try
1079     {
1080         PythonExtensionBase *p = getPythonExtensionBase( self );
1081         return new_reference_to( p->sequence_repeat( count ) );
1082     }
1083     catch( BaseException & )
1084     {
1085         return NULL;    // indicate error
1086     }
1087 }
1088 
sequence_item_handler(PyObject * self,Py_ssize_t index)1089 extern "C" PyObject *sequence_item_handler( PyObject *self, Py_ssize_t index )
1090 {
1091     try
1092     {
1093         PythonExtensionBase *p = getPythonExtensionBase( self );
1094         return new_reference_to( p->sequence_item( index ) );
1095     }
1096     catch( BaseException & )
1097     {
1098         return NULL;    // indicate error
1099     }
1100 }
1101 
sequence_ass_item_handler(PyObject * self,Py_ssize_t index,PyObject * value)1102 extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value )
1103 {
1104     try
1105     {
1106         PythonExtensionBase *p = getPythonExtensionBase( self );
1107         return p->sequence_ass_item( index, Object( value ) );
1108     }
1109     catch( BaseException & )
1110     {
1111         return -1;    // indicate error
1112     }
1113 }
1114 
sequence_inplace_concat_handler(PyObject * self,PyObject * o2)1115 extern "C" PyObject *sequence_inplace_concat_handler( PyObject *self, PyObject *o2 )
1116 {
1117     try
1118     {
1119         PythonExtensionBase *p = getPythonExtensionBase( self );
1120         return new_reference_to( p->sequence_inplace_concat( Object( o2 ) ) );
1121     }
1122     catch( BaseException & )
1123     {
1124         return NULL;    // indicate error
1125     }
1126 }
1127 
sequence_inplace_repeat_handler(PyObject * self,Py_ssize_t count)1128 extern "C" PyObject *sequence_inplace_repeat_handler( PyObject *self, Py_ssize_t count )
1129 {
1130     try
1131     {
1132         PythonExtensionBase *p = getPythonExtensionBase( self );
1133         return new_reference_to( p->sequence_inplace_repeat( count ) );
1134     }
1135     catch( BaseException & )
1136     {
1137         return NULL;    // indicate error
1138     }
1139 }
1140 
sequence_contains_handler(PyObject * self,PyObject * value)1141 extern "C" int sequence_contains_handler( PyObject *self, PyObject *value )
1142 {
1143     try
1144     {
1145         PythonExtensionBase *p = getPythonExtensionBase( self );
1146         return p->sequence_contains( Object( value ) );
1147     }
1148     catch( BaseException & )
1149     {
1150         return -1;    // indicate error
1151     }
1152 }
1153 
1154 // Mapping
mapping_length_handler(PyObject * self)1155 extern "C" Py_ssize_t mapping_length_handler( PyObject *self )
1156 {
1157     try
1158     {
1159         PythonExtensionBase *p = getPythonExtensionBase( self );
1160         return p->mapping_length();
1161     }
1162     catch( BaseException & )
1163     {
1164         return -1;    // indicate error
1165     }
1166 }
1167 
mapping_subscript_handler(PyObject * self,PyObject * key)1168 extern "C" PyObject *mapping_subscript_handler( PyObject *self, PyObject *key )
1169 {
1170     try
1171     {
1172         PythonExtensionBase *p = getPythonExtensionBase( self );
1173         return new_reference_to( p->mapping_subscript( Object( key ) ) );
1174     }
1175     catch( BaseException & )
1176     {
1177         return NULL;    // indicate error
1178     }
1179 }
1180 
mapping_ass_subscript_handler(PyObject * self,PyObject * key,PyObject * value)1181 extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value )
1182 {
1183     try
1184     {
1185         PythonExtensionBase *p = getPythonExtensionBase( self );
1186         return p->mapping_ass_subscript( Object( key ), Object( value ) );
1187     }
1188     catch( BaseException & )
1189     {
1190         return -1;    // indicate error
1191     }
1192 }
1193 
1194 // Number
1195 #define NUMBER_UNARY( slot ) \
1196 extern "C" PyObject *number_ ## slot ## _handler( PyObject *self ) \
1197 { \
1198     try \
1199     { \
1200         PythonExtensionBase *p = getPythonExtensionBase( self ); \
1201         return new_reference_to( p->number_ ## slot() ); \
1202     } \
1203     catch( BaseException & ) \
1204     { \
1205         return NULL; /* indicates error */ \
1206     } \
1207 }
1208 
1209 #define NUMBER_BINARY( slot ) \
1210 extern "C" PyObject *number_ ## slot ## _handler( PyObject *self, PyObject *other ) \
1211 { \
1212     try \
1213     { \
1214         PythonExtensionBase *p = getPythonExtensionBase( self ); \
1215         return new_reference_to( p->number_ ## slot( Object( other ) ) ); \
1216     } \
1217     catch( BaseException & ) \
1218     { \
1219         return NULL; /* indicates error */ \
1220     } \
1221 }
1222 #define NUMBER_TERNARY( slot ) \
1223 extern "C" PyObject *number_ ## slot ## _handler( PyObject *self, PyObject *other1, PyObject *other2 ) \
1224 { \
1225     try \
1226     { \
1227         PythonExtensionBase *p = getPythonExtensionBase( self ); \
1228         return new_reference_to( p->number_ ## slot( Object( other1 ), Object( other2 ) ) ); \
1229     } \
1230     catch( BaseException & ) \
1231     { \
1232         return NULL; /* indicates error */ \
1233     } \
1234 }
1235 
1236 NUMBER_UNARY( negative )
NUMBER_UNARY(positive)1237 NUMBER_UNARY( positive )
1238 NUMBER_UNARY( absolute )
1239 NUMBER_UNARY( invert )
1240 NUMBER_UNARY( int )
1241 NUMBER_UNARY( float )
1242 NUMBER_BINARY( add )
1243 NUMBER_BINARY( subtract )
1244 NUMBER_BINARY( multiply )
1245 NUMBER_BINARY( remainder )
1246 NUMBER_BINARY( divmod )
1247 NUMBER_BINARY( lshift )
1248 NUMBER_BINARY( rshift )
1249 NUMBER_BINARY( and )
1250 NUMBER_BINARY( xor )
1251 NUMBER_BINARY( or )
1252 NUMBER_TERNARY( power )
1253 NUMBER_BINARY( floor_divide )
1254 NUMBER_BINARY( true_divide )
1255 NUMBER_UNARY( index )
1256 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1257 NUMBER_BINARY( matrix_multiply )
1258 #endif
1259 NUMBER_BINARY( inplace_add )
1260 NUMBER_BINARY( inplace_subtract )
1261 NUMBER_BINARY( inplace_multiply )
1262 NUMBER_BINARY( inplace_remainder )
1263 NUMBER_TERNARY( inplace_power )
1264 NUMBER_BINARY( inplace_lshift )
1265 NUMBER_BINARY( inplace_rshift )
1266 NUMBER_BINARY( inplace_and )
1267 NUMBER_BINARY( inplace_xor )
1268 NUMBER_BINARY( inplace_or )
1269 NUMBER_BINARY( inplace_floor_divide )
1270 NUMBER_BINARY( inplace_true_divide )
1271 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1272 NUMBER_BINARY( inplace_matrix_multiply )
1273 #endif
1274 
1275 #undef NUMBER_UNARY
1276 #undef NUMBER_BINARY
1277 #undef NUMBER_TERNARY
1278 
1279 // Buffer
1280 #ifndef Py_LIMITED_API
1281 extern "C" int buffer_get_handler( PyObject *self, Py_buffer *buf, int flags )
1282 {
1283     try
1284     {
1285         PythonExtensionBase *p = getPythonExtensionBase( self );
1286         return p->buffer_get( buf, flags );
1287     }
1288     catch( BaseException & )
1289     {
1290         return -1;    // indicate error
1291     }
1292 }
1293 
buffer_release_handler(PyObject * self,Py_buffer * buf)1294 extern "C" void buffer_release_handler( PyObject *self, Py_buffer *buf )
1295 {
1296     PythonExtensionBase *p = getPythonExtensionBase( self );
1297     p->buffer_release( buf );
1298     // NOTE: No way to indicate error to Python
1299 }
1300 #endif
1301 
1302 //================================================================================
1303 //
1304 //    Implementation of PythonExtensionBase
1305 //
1306 //================================================================================
1307 #define missing_method( method ) \
1308     throw RuntimeError( "Extension object missing implement of " #method );
1309 
PythonExtensionBase()1310 PythonExtensionBase::PythonExtensionBase()
1311 {
1312     ob_refcnt = 0;
1313 }
1314 
~PythonExtensionBase()1315 PythonExtensionBase::~PythonExtensionBase()
1316 {
1317     assert( ob_refcnt == 0 );
1318 }
1319 
callOnSelf(const std::string & fn_name)1320 Object PythonExtensionBase::callOnSelf( const std::string &fn_name )
1321 {
1322     TupleN args;
1323     return  self().callMemberFunction( fn_name, args );
1324 }
1325 
callOnSelf(const std::string & fn_name,const Object & arg1)1326 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1327                                             const Object &arg1 )
1328 {
1329     TupleN args( arg1 );
1330     return  self().callMemberFunction( fn_name, args );
1331 }
1332 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2)1333 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1334                                             const Object &arg1, const Object &arg2 )
1335 {
1336     TupleN args( arg1, arg2 );
1337     return self().callMemberFunction( fn_name, args );
1338 }
1339 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3)1340 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1341                                             const Object &arg1, const Object &arg2, const Object &arg3 )
1342 {
1343     TupleN args( arg1, arg2, arg3 );
1344     return self().callMemberFunction( fn_name, args );
1345 }
1346 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4)1347 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1348                                             const Object &arg1, const Object &arg2, const Object &arg3,
1349                                             const Object &arg4 )
1350 {
1351     TupleN args( arg1, arg2, arg3, arg4 );
1352     return self().callMemberFunction( fn_name, args );
1353 }
1354 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4,const Object & arg5)1355 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1356                                             const Object &arg1, const Object &arg2, const Object &arg3,
1357                                             const Object &arg4, const Object &arg5 )
1358 {
1359     TupleN args( arg1, arg2, arg3, arg4, arg5 );
1360     return self().callMemberFunction( fn_name, args );
1361 }
1362 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4,const Object & arg5,const Object & arg6)1363 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1364                                             const Object &arg1, const Object &arg2, const Object &arg3,
1365                                             const Object &arg4, const Object &arg5, const Object &arg6 )
1366 {
1367     TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 );
1368     return self().callMemberFunction( fn_name, args );
1369 }
1370 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4,const Object & arg5,const Object & arg6,const Object & arg7)1371 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1372                                             const Object &arg1, const Object &arg2, const Object &arg3,
1373                                             const Object &arg4, const Object &arg5, const Object &arg6,
1374                                             const Object &arg7 )
1375 {
1376     TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
1377     return self().callMemberFunction( fn_name, args );
1378 }
1379 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4,const Object & arg5,const Object & arg6,const Object & arg7,const Object & arg8)1380 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1381                                             const Object &arg1, const Object &arg2, const Object &arg3,
1382                                             const Object &arg4, const Object &arg5, const Object &arg6,
1383                                             const Object &arg7, const Object &arg8 )
1384 {
1385     TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 );
1386     return self().callMemberFunction( fn_name, args );
1387 }
1388 
callOnSelf(const std::string & fn_name,const Object & arg1,const Object & arg2,const Object & arg3,const Object & arg4,const Object & arg5,const Object & arg6,const Object & arg7,const Object & arg8,const Object & arg9)1389 Object PythonExtensionBase::callOnSelf( const std::string &fn_name,
1390                                             const Object &arg1, const Object &arg2, const Object &arg3,
1391                                             const Object &arg4, const Object &arg5, const Object &arg6,
1392                                             const Object &arg7, const Object &arg8, const Object &arg9 )
1393 {
1394     TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 );
1395     return self().callMemberFunction( fn_name, args );
1396 }
1397 
reinit(Tuple &,Dict &)1398 void PythonExtensionBase::reinit( Tuple &/*args*/, Dict &/*kwds*/ )
1399 {
1400     throw RuntimeError( "Must not call __init__ twice on this class" );
1401 }
1402 
1403 
genericGetAttro(const String & name)1404 Object PythonExtensionBase::genericGetAttro( const String &name )
1405 {
1406     return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) );
1407 }
1408 
genericSetAttro(const String & name,const Object & value)1409 int PythonExtensionBase::genericSetAttro( const String &name, const Object &value )
1410 {
1411     return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() );
1412 }
1413 
1414 #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7
print(FILE *,int)1415 int PythonExtensionBase::print( FILE *, int )
1416 {
1417     missing_method( print );
1418 }
1419 #endif
1420 
getattr(const char *)1421 Object PythonExtensionBase::getattr( const char * )
1422 {
1423     missing_method( getattr );
1424 }
1425 
setattr(const char *,const Object &)1426 int PythonExtensionBase::setattr( const char *, const Object & )
1427 {
1428     missing_method( setattr );
1429 }
1430 
getattro(const String & name)1431 Object PythonExtensionBase::getattro( const String &name )
1432 {
1433     return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) );
1434 }
1435 
setattro(const String & name,const Object & value)1436 int PythonExtensionBase::setattro( const String &name, const Object &value )
1437 {
1438     return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() );
1439 }
1440 
1441 
compare(const Object &)1442 int PythonExtensionBase::compare( const Object & )
1443 {
1444     missing_method( compare );
1445 }
1446 
rich_compare(const Object &,int)1447 Object PythonExtensionBase::rich_compare( const Object &, int )
1448 {
1449     missing_method( rich_compare );
1450 }
1451 
repr()1452 Object PythonExtensionBase::repr()
1453 {
1454     missing_method( repr );
1455 }
1456 
str()1457 Object PythonExtensionBase::str()
1458 {
1459     missing_method( str );
1460 }
1461 
hash()1462 long PythonExtensionBase::hash()
1463 {
1464     missing_method( hash );
1465 }
1466 
call(const Object &,const Object &)1467 Object PythonExtensionBase::call( const Object &, const Object & )
1468 {
1469     missing_method( call );
1470 }
1471 
iter()1472 Object PythonExtensionBase::iter()
1473 {
1474     missing_method( iter );
1475 }
1476 
iternext()1477 PyObject *PythonExtensionBase::iternext()
1478 {
1479     missing_method( iternext );
1480 }
1481 
1482 // Sequence methods
sequence_length()1483 Sequence::size_type PythonExtensionBase::sequence_length()
1484 {
1485     missing_method( sequence_length );
1486 }
1487 
sequence_concat(const Object &)1488 Object PythonExtensionBase::sequence_concat( const Object & )
1489 {
1490     missing_method( sequence_concat );
1491 }
1492 
sequence_repeat(Py_ssize_t)1493 Object PythonExtensionBase::sequence_repeat( Py_ssize_t )
1494 {
1495     missing_method( sequence_repeat );
1496 }
1497 
sequence_item(Py_ssize_t)1498 Object PythonExtensionBase::sequence_item( Py_ssize_t )
1499 {
1500     missing_method( sequence_item );
1501 }
1502 
sequence_ass_item(Py_ssize_t,const Object &)1503 int PythonExtensionBase::sequence_ass_item( Py_ssize_t, const Object & )
1504 {
1505     missing_method( sequence_ass_item );
1506 }
1507 
sequence_inplace_concat(const Object &)1508 Object PythonExtensionBase::sequence_inplace_concat( const Object & )
1509 {
1510     missing_method( sequence_inplace_concat );
1511 }
1512 
sequence_inplace_repeat(Py_ssize_t)1513 Object PythonExtensionBase::sequence_inplace_repeat( Py_ssize_t )
1514 {
1515     missing_method( sequence_inplace_repeat );
1516 }
1517 
sequence_contains(const Object &)1518 int PythonExtensionBase::sequence_contains( const Object & )
1519 {
1520     missing_method( sequence_contains );
1521 }
1522 
1523 // Mapping
mapping_length()1524 PyCxx_ssize_t PythonExtensionBase::mapping_length()
1525 {
1526     missing_method( mapping_length );
1527 }
1528 
mapping_subscript(const Object &)1529 Object PythonExtensionBase::mapping_subscript( const Object & )
1530 {
1531     missing_method( mapping_subscript );
1532 }
1533 
mapping_ass_subscript(const Object &,const Object &)1534 int PythonExtensionBase::mapping_ass_subscript( const Object &, const Object & )
1535 {
1536     missing_method( mapping_ass_subscript );
1537 }
1538 
1539 // Number
1540 #define NUMBER_UNARY( slot ) Object PythonExtensionBase::number_ ## slot() \
1541     { missing_method( number_ ## slot ); }
1542 #define NUMBER_BINARY( slot ) Object PythonExtensionBase::number_ ## slot( const Object & ) \
1543     { missing_method( number_ ## slot ); }
1544 #define NUMBER_TERNARY( slot ) Object PythonExtensionBase::number_ ## slot( const Object &, const Object & ) \
1545     { missing_method( number_ ## slot ); }
1546 
1547 NUMBER_UNARY( negative )
NUMBER_UNARY(positive)1548 NUMBER_UNARY( positive )
1549 NUMBER_UNARY( absolute )
1550 NUMBER_UNARY( invert )
1551 NUMBER_UNARY( int )
1552 NUMBER_UNARY( float )
1553 NUMBER_BINARY( add )
1554 NUMBER_BINARY( subtract )
1555 NUMBER_BINARY( multiply )
1556 NUMBER_BINARY( remainder )
1557 NUMBER_BINARY( divmod )
1558 NUMBER_BINARY( lshift )
1559 NUMBER_BINARY( rshift )
1560 NUMBER_BINARY( and )
1561 NUMBER_BINARY( xor )
1562 NUMBER_BINARY( or )
1563 NUMBER_TERNARY( power )
1564 NUMBER_BINARY( floor_divide )
1565 NUMBER_BINARY( true_divide )
1566 NUMBER_UNARY( index )
1567 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1568 NUMBER_BINARY( matrix_multiply )
1569 #endif
1570 
1571 NUMBER_BINARY( inplace_add )
1572 NUMBER_BINARY( inplace_subtract )
1573 NUMBER_BINARY( inplace_multiply )
1574 NUMBER_BINARY( inplace_remainder )
1575 NUMBER_TERNARY( inplace_power )
1576 NUMBER_BINARY( inplace_lshift )
1577 NUMBER_BINARY( inplace_rshift )
1578 NUMBER_BINARY( inplace_and )
1579 NUMBER_BINARY( inplace_xor )
1580 NUMBER_BINARY( inplace_or )
1581 NUMBER_BINARY( inplace_floor_divide )
1582 NUMBER_BINARY( inplace_true_divide )
1583 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5
1584 NUMBER_BINARY( inplace_matrix_multiply )
1585 #endif
1586 
1587 #undef NUMBER_UNARY
1588 #undef NUMBER_BINARY
1589 #undef NUMBER_TERNARY
1590 
1591 
1592 // Buffer
1593 #ifndef Py_LIMITED_API
1594 int PythonExtensionBase::buffer_get( Py_buffer * /*buf*/, int /*flags*/ )
1595 {
1596     missing_method( buffer_get );
1597 }
1598 
buffer_release(Py_buffer *)1599 int PythonExtensionBase::buffer_release( Py_buffer * /*buf*/ )
1600 {
1601     // This method is optional and only required if the buffer's
1602     // memory is dynamic.
1603     return 0;
1604 }
1605 #endif
1606 
1607 //--------------------------------------------------------------------------------
1608 //
1609 //    Method call handlers for
1610 //        PythonExtensionBase
1611 //        ExtensionModuleBase
1612 //
1613 //--------------------------------------------------------------------------------
1614 // Note: Python calls noargs as varargs buts args==NULL
method_noargs_call_handler(PyObject * _self_and_name_tuple,PyObject *)1615 extern "C" PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * )
1616 {
1617     try
1618     {
1619         Tuple self_and_name_tuple( _self_and_name_tuple );
1620 
1621         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1622         void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
1623         if( self_as_void == NULL )
1624             return NULL;
1625 
1626         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1627 
1628         Object result( self->invoke_method_noargs( PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ) );
1629 
1630         return new_reference_to( result.ptr() );
1631     }
1632     catch( BaseException & )
1633     {
1634         return 0;
1635     }
1636 }
1637 
method_varargs_call_handler(PyObject * _self_and_name_tuple,PyObject * _args)1638 extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
1639 {
1640     try
1641     {
1642         Tuple self_and_name_tuple( _self_and_name_tuple );
1643 
1644         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1645         void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
1646         if( self_as_void == NULL )
1647             return NULL;
1648 
1649         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1650         Tuple args( _args );
1651         Object result
1652                 (
1653                 self->invoke_method_varargs
1654                     (
1655                     PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ),
1656                     args
1657                     )
1658                 );
1659 
1660         return new_reference_to( result.ptr() );
1661     }
1662     catch( BaseException & )
1663     {
1664         return 0;
1665     }
1666 }
1667 
method_keyword_call_handler(PyObject * _self_and_name_tuple,PyObject * _args,PyObject * _keywords)1668 extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
1669 {
1670     try
1671     {
1672         Tuple self_and_name_tuple( _self_and_name_tuple );
1673 
1674         PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
1675         void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
1676         if( self_as_void == NULL )
1677             return NULL;
1678 
1679         ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void );
1680 
1681         Tuple args( _args );
1682 
1683         if( _keywords == NULL )
1684         {
1685             Dict keywords;    // pass an empty dict
1686 
1687             Object result
1688                 (
1689                 self->invoke_method_keyword
1690                     (
1691                     PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ),
1692                     args,
1693                     keywords
1694                     )
1695                 );
1696 
1697             return new_reference_to( result.ptr() );
1698         }
1699         else
1700         {
1701             Dict keywords( _keywords ); // make dict
1702 
1703             Object result
1704                     (
1705                     self->invoke_method_keyword
1706                         (
1707                         PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ),
1708                         args,
1709                         keywords
1710                         )
1711                     );
1712 
1713             return new_reference_to( result.ptr() );
1714         }
1715     }
1716     catch( BaseException & )
1717     {
1718         return 0;
1719     }
1720 }
1721 
1722 
1723 //--------------------------------------------------------------------------------
1724 //
1725 //    ExtensionExceptionType
1726 //
1727 //--------------------------------------------------------------------------------
ExtensionExceptionType()1728 ExtensionExceptionType::ExtensionExceptionType()
1729 : Object()
1730 {
1731 }
1732 
init(ExtensionModuleBase & module,const std::string & name)1733 void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name )
1734 {
1735     std::string module_name( module.fullName() );
1736     module_name += ".";
1737     module_name += name;
1738 
1739     set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true );
1740 }
1741 
init(ExtensionModuleBase & module,const std::string & name,ExtensionExceptionType & parent)1742 void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent )
1743  {
1744      std::string module_name( module.fullName() );
1745      module_name += ".";
1746      module_name += name;
1747 
1748     set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
1749 }
1750 
~ExtensionExceptionType()1751 ExtensionExceptionType::~ExtensionExceptionType()
1752 {
1753 }
1754 
BaseException(ExtensionExceptionType & exception,const std::string & reason)1755 BaseException::BaseException( ExtensionExceptionType &exception, const std::string& reason )
1756 {
1757     PyErr_SetString( exception.ptr(), reason.c_str() );
1758 }
1759 
BaseException(ExtensionExceptionType & exception,Object & reason)1760 BaseException::BaseException( ExtensionExceptionType &exception, Object &reason )
1761 {
1762     PyErr_SetObject( exception.ptr(), reason.ptr() );
1763 }
1764 
BaseException(PyObject * exception,Object & reason)1765 BaseException::BaseException( PyObject *exception, Object &reason )
1766 {
1767     PyErr_SetObject( exception, reason.ptr() );
1768 }
1769 
BaseException(PyObject * exception,const std::string & reason)1770 BaseException::BaseException( PyObject *exception, const std::string &reason )
1771 {
1772     PyErr_SetString( exception, reason.c_str() );
1773 }
1774 
BaseException()1775 BaseException::BaseException()
1776 {
1777 }
1778 
clear()1779 void BaseException::clear()
1780 {
1781     PyErr_Clear();
1782 }
1783 
1784 // is the exception this specific exception 'exc'
matches(ExtensionExceptionType & exc)1785 bool BaseException::matches( ExtensionExceptionType &exc )
1786 {
1787     return PyErr_ExceptionMatches( exc.ptr() ) != 0;
1788 }
1789 
errorType()1790 Object BaseException::errorType()
1791 {
1792     PyObject *type, *value, *traceback;
1793     PyErr_Fetch( &type, &value, &traceback );
1794 
1795     Object result( type );
1796 
1797     PyErr_Restore( type, value, traceback );
1798     return result;
1799 }
1800 
errorValue()1801 Object BaseException::errorValue()
1802 {
1803     PyObject *type, *value, *traceback;
1804     PyErr_Fetch( &type, &value, &traceback );
1805 
1806     Object result( value );
1807 
1808     PyErr_Restore( type, value, traceback );
1809     return result;
1810 }
1811 
1812 
1813 //------------------------------------------------------------
1814 
1815 #if 1
1816 //------------------------------------------------------------
1817 // compare operators
operator !=(const Long & a,const Long & b)1818 bool operator!=( const Long &a, const Long &b )
1819 {
1820     return a.as_long() != b.as_long();
1821 }
1822 
operator !=(const Long & a,int b)1823 bool operator!=( const Long &a, int b )
1824 {
1825     return a.as_long() != b;
1826 }
1827 
operator !=(const Long & a,long b)1828 bool operator!=( const Long &a, long b )
1829 {
1830     return a.as_long() != b;
1831 }
1832 
operator !=(int a,const Long & b)1833 bool operator!=( int a, const Long &b )
1834 {
1835     return a != b.as_long();
1836 }
1837 
operator !=(long a,const Long & b)1838 bool operator!=( long a, const Long &b )
1839 {
1840     return a != b.as_long();
1841 }
1842 
1843 //------------------------------
operator ==(const Long & a,const Long & b)1844 bool operator==( const Long &a, const Long &b )
1845 {
1846     return a.as_long() == b.as_long();
1847 }
1848 
operator ==(const Long & a,int b)1849 bool operator==( const Long &a, int b )
1850 {
1851     return a.as_long() == b;
1852 }
1853 
operator ==(const Long & a,long b)1854 bool operator==( const Long &a, long b )
1855 {
1856     return a.as_long() == b;
1857 }
1858 
operator ==(int a,const Long & b)1859 bool operator==( int a, const Long &b )
1860 {
1861     return a == b.as_long();
1862 }
1863 
operator ==(long a,const Long & b)1864 bool operator==( long a, const Long &b )
1865 {
1866     return a == b.as_long();
1867 }
1868 
1869 //------------------------------
operator >(const Long & a,const Long & b)1870 bool operator>( const Long &a, const Long &b )
1871 {
1872     return a.as_long() > b.as_long();
1873 }
1874 
operator >(const Long & a,int b)1875 bool operator>( const Long &a, int b )
1876 {
1877     return a.as_long() > b;
1878 }
1879 
operator >(const Long & a,long b)1880 bool operator>( const Long &a, long b )
1881 {
1882     return a.as_long() > b;
1883 }
1884 
operator >(int a,const Long & b)1885 bool operator>( int a, const Long &b )
1886 {
1887     return a > b.as_long();
1888 }
1889 
operator >(long a,const Long & b)1890 bool operator>( long a, const Long &b )
1891 {
1892     return a > b.as_long();
1893 }
1894 
1895 //------------------------------
operator >=(const Long & a,const Long & b)1896 bool operator>=( const Long &a, const Long &b )
1897 {
1898     return a.as_long() >= b.as_long();
1899 }
1900 
operator >=(const Long & a,int b)1901 bool operator>=( const Long &a, int b )
1902 {
1903     return a.as_long() >= b;
1904 }
1905 
operator >=(const Long & a,long b)1906 bool operator>=( const Long &a, long b )
1907 {
1908     return a.as_long() >= b;
1909 }
1910 
operator >=(int a,const Long & b)1911 bool operator>=( int a, const Long &b )
1912 {
1913     return a >= b.as_long();
1914 }
1915 
operator >=(long a,const Long & b)1916 bool operator>=( long a, const Long &b )
1917 {
1918     return a >= b.as_long();
1919 }
1920 
1921 //------------------------------
operator <(const Long & a,const Long & b)1922 bool operator<( const Long &a, const Long &b )
1923 {
1924     return a.as_long() < b.as_long();
1925 }
1926 
operator <(const Long & a,int b)1927 bool operator<( const Long &a, int b )
1928 {
1929     return a.as_long() < b;
1930 }
1931 
operator <(const Long & a,long b)1932 bool operator<( const Long &a, long b )
1933 {
1934     return a.as_long() < b;
1935 }
1936 
operator <(int a,const Long & b)1937 bool operator<( int a, const Long &b )
1938 {
1939     return a < b.as_long();
1940 }
1941 
operator <(long a,const Long & b)1942 bool operator<( long a, const Long &b )
1943 {
1944     return a < b.as_long();
1945 }
1946 
1947 //------------------------------
operator <=(const Long & a,const Long & b)1948 bool operator<=( const Long &a, const Long &b )
1949 {
1950     return a.as_long() <= b.as_long();
1951 }
1952 
operator <=(int a,const Long & b)1953 bool operator<=( int a, const Long &b )
1954 {
1955     return a <= b.as_long();
1956 }
1957 
operator <=(long a,const Long & b)1958 bool operator<=( long a, const Long &b )
1959 {
1960     return a <= b.as_long();
1961 }
1962 
operator <=(const Long & a,int b)1963 bool operator<=( const Long &a, int b )
1964 {
1965     return a.as_long() <= b;
1966 }
1967 
operator <=(const Long & a,long b)1968 bool operator<=( const Long &a, long b )
1969 {
1970     return a.as_long() <= b;
1971 }
1972 
1973 #ifdef HAVE_LONG_LONG
1974 //------------------------------
operator !=(const Long & a,PY_LONG_LONG b)1975 bool operator!=( const Long &a, PY_LONG_LONG b )
1976 {
1977     return a.as_long_long() != b;
1978 }
1979 
operator !=(PY_LONG_LONG a,const Long & b)1980 bool operator!=( PY_LONG_LONG a, const Long &b )
1981 {
1982     return a != b.as_long_long();
1983 }
1984 
1985 //------------------------------
operator ==(const Long & a,PY_LONG_LONG b)1986 bool operator==( const Long &a, PY_LONG_LONG b )
1987 {
1988     return a.as_long_long() == b;
1989 }
1990 
operator ==(PY_LONG_LONG a,const Long & b)1991 bool operator==( PY_LONG_LONG a, const Long &b )
1992 {
1993     return a == b.as_long_long();
1994 }
1995 
1996 //------------------------------
operator >(const Long & a,PY_LONG_LONG b)1997 bool operator>( const Long &a, PY_LONG_LONG b )
1998 {
1999     return a.as_long_long() > b;
2000 }
2001 
operator >(PY_LONG_LONG a,const Long & b)2002 bool operator>( PY_LONG_LONG a, const Long &b )
2003 {
2004     return a > b.as_long_long();
2005 }
2006 
2007 //------------------------------
operator >=(const Long & a,PY_LONG_LONG b)2008 bool operator>=( const Long &a, PY_LONG_LONG b )
2009 {
2010     return a.as_long_long() >= b;
2011 }
2012 
operator >=(PY_LONG_LONG a,const Long & b)2013 bool operator>=( PY_LONG_LONG a, const Long &b )
2014 {
2015     return a >= b.as_long_long();
2016 }
2017 
2018 //------------------------------
operator <(const Long & a,PY_LONG_LONG b)2019 bool operator<( const Long &a, PY_LONG_LONG b )
2020 {
2021     return a.as_long_long() < b;
2022 }
2023 
operator <(PY_LONG_LONG a,const Long & b)2024 bool operator<( PY_LONG_LONG a, const Long &b )
2025 {
2026     return a < b.as_long_long();
2027 }
2028 
2029 //------------------------------
operator <=(const Long & a,PY_LONG_LONG b)2030 bool operator<=( const Long &a, PY_LONG_LONG b )
2031 {
2032     return a.as_long_long() <= b;
2033 }
2034 
operator <=(PY_LONG_LONG a,const Long & b)2035 bool operator<=( PY_LONG_LONG a, const Long &b )
2036 {
2037     return a <= b.as_long_long();
2038 }
2039 #endif
2040 #endif
2041 
2042 //------------------------------------------------------------
2043 // compare operators
operator !=(const Float & a,const Float & b)2044 bool operator!=( const Float &a, const Float &b )
2045 {
2046     return a.as_double() != b.as_double();
2047 }
2048 
operator !=(const Float & a,double b)2049 bool operator!=( const Float &a, double b )
2050 {
2051     return a.as_double() != b;
2052 }
2053 
operator !=(double a,const Float & b)2054 bool operator!=( double a, const Float &b )
2055 {
2056     return a != b.as_double();
2057 }
2058 
2059 //------------------------------
operator ==(const Float & a,const Float & b)2060 bool operator==( const Float &a, const Float &b )
2061 {
2062     return a.as_double() == b.as_double();
2063 }
2064 
operator ==(const Float & a,double b)2065 bool operator==( const Float &a, double b )
2066 {
2067     return a.as_double() == b;
2068 }
2069 
operator ==(double a,const Float & b)2070 bool operator==( double a, const Float &b )
2071 {
2072     return a == b.as_double();
2073 }
2074 
2075 //------------------------------
operator >(const Float & a,const Float & b)2076 bool operator>( const Float &a, const Float &b )
2077 {
2078     return a.as_double() > b.as_double();
2079 }
2080 
operator >(const Float & a,double b)2081 bool operator>( const Float &a, double b )
2082 {
2083     return a.as_double() > b;
2084 }
2085 
operator >(double a,const Float & b)2086 bool operator>( double a, const Float &b )
2087 {
2088     return a > b.as_double();
2089 }
2090 
2091 //------------------------------
operator >=(const Float & a,const Float & b)2092 bool operator>=( const Float &a, const Float &b )
2093 {
2094     return a.as_double() >= b.as_double();
2095 }
2096 
operator >=(const Float & a,double b)2097 bool operator>=( const Float &a, double b )
2098 {
2099     return a.as_double() >= b;
2100 }
2101 
operator >=(double a,const Float & b)2102 bool operator>=( double a, const Float &b )
2103 {
2104     return a >= b.as_double();
2105 }
2106 
2107 //------------------------------
operator <(const Float & a,const Float & b)2108 bool operator<( const Float &a, const Float &b )
2109 {
2110     return a.as_double() < b.as_double();
2111 }
2112 
operator <(const Float & a,double b)2113 bool operator<( const Float &a, double b )
2114 {
2115     return a.as_double() < b;
2116 }
2117 
operator <(double a,const Float & b)2118 bool operator<( double a, const Float &b )
2119 {
2120     return a < b.as_double();
2121 }
2122 
2123 //------------------------------
operator <=(const Float & a,const Float & b)2124 bool operator<=( const Float &a, const Float &b )
2125 {
2126     return a.as_double() <= b.as_double();
2127 }
2128 
operator <=(double a,const Float & b)2129 bool operator<=( double a, const Float &b )
2130 {
2131     return a <= b.as_double();
2132 }
2133 
operator <=(const Float & a,double b)2134 bool operator<=( const Float &a, double b )
2135 {
2136     return a.as_double() <= b;
2137 }
2138 
2139 }    // end of namespace Py
2140