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