| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #include "CXX/Extensions.hxx" |
| | #include "CXX/Exception.hxx" |
| | #include "CXX/Objects.hxx" |
| |
|
| | #include <assert.h> |
| |
|
| | #ifdef PYCXX_DEBUG |
| | |
| | |
| | |
| | void bpt( void ) |
| | { |
| | } |
| |
|
| | void printRefCount( PyObject *obj ) |
| | { |
| | std::cout << "RefCount of 0x" << std::hex << reinterpret_cast< unsigned long >( obj ) << std::dec << " is " << Py_REFCNT( obj ) << std::endl; |
| | } |
| | #endif |
| |
|
| | namespace Py |
| | { |
| |
|
| | void Object::validate() |
| | { |
| | |
| | if( !accepts( p ) ) |
| | { |
| | #if defined( _CPPRTTI ) || defined( __GNUG__ ) |
| | std::string s( "PyCXX: Error creating object of type " ); |
| | s += (typeid( *this )).name(); |
| |
|
| | if( p != NULL ) |
| | { |
| | String from_repr = repr(); |
| | s += " from "; |
| | s += from_repr.as_std_string(); |
| | } |
| | else |
| | { |
| | s += " from (nil)"; |
| | } |
| | #endif |
| | release(); |
| |
|
| | |
| | ifPyErrorThrowCxxException(); |
| |
|
| | |
| | #if defined( _CPPRTTI ) || defined( __GNUG__ ) |
| | throw TypeError( s ); |
| | #else |
| | throw TypeError( "PyCXX: type error." ); |
| | #endif |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | PyMethodDef MethodTable::method( const char *method_name, PyCFunction f, int flags, const char *doc ) |
| | { |
| | PyMethodDef m; |
| | m.ml_name = const_cast<char *>( method_name ); |
| | m.ml_meth = f; |
| | m.ml_flags = flags; |
| | m.ml_doc = const_cast<char *>( doc ); |
| | return m; |
| | } |
| |
|
| | MethodTable::MethodTable() |
| | { |
| | t.push_back( method( 0, 0, 0, 0 ) ); |
| | mt = NULL; |
| | } |
| |
|
| | MethodTable::~MethodTable() |
| | { |
| | delete [] mt; |
| | } |
| |
|
| | void MethodTable::add( const char *method_name, PyCFunction f, const char *doc, int flag ) |
| | { |
| | if( !mt ) |
| | { |
| | t.insert( t.end()-1, method( method_name, f, flag, doc ) ); |
| | } |
| | else |
| | { |
| | throw RuntimeError( "Too late to add a module method!" ); |
| | } |
| | } |
| |
|
| | PyMethodDef *MethodTable::table() |
| | { |
| | if( !mt ) |
| | { |
| | Py_ssize_t t1size = t.size(); |
| | mt = new PyMethodDef[ t1size ]; |
| | int j = 0; |
| | for( std::vector<PyMethodDef>::iterator i = t.begin(); i != t.end(); i++ ) |
| | { |
| | mt[ j++ ] = *i; |
| | } |
| | } |
| | return mt; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | ExtensionModuleBase::ExtensionModuleBase( const char *name ) |
| | : m_module_name( name ) |
| | #if defined( Py_LIMITED_API ) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12) |
| | , m_full_module_name( m_module_name ) |
| | #else |
| | , m_full_module_name( __Py_PackageContext() != NULL ? std::string( __Py_PackageContext() ) : m_module_name ) |
| | #endif |
| | , m_method_table() |
| | |
| | , m_module( NULL ) |
| | {} |
| |
|
| | ExtensionModuleBase::~ExtensionModuleBase() |
| | {} |
| |
|
| | const std::string &ExtensionModuleBase::name() const |
| | { |
| | return m_module_name; |
| | } |
| |
|
| | const std::string &ExtensionModuleBase::fullName() const |
| | { |
| | return m_full_module_name; |
| | } |
| |
|
| | class ExtensionModuleBasePtr : public PythonExtension<ExtensionModuleBasePtr> |
| | { |
| | public: |
| | ExtensionModuleBasePtr( ExtensionModuleBase *_module ) |
| | : module( _module ) |
| | {} |
| |
|
| | virtual ~ExtensionModuleBasePtr() |
| | {} |
| |
|
| | ExtensionModuleBase *module; |
| | }; |
| |
|
| | void initExceptions(); |
| |
|
| | void ExtensionModuleBase::initialize( const char *module_doc ) |
| | { |
| | |
| | initExceptions(); |
| |
|
| | memset( &m_module_def, 0, sizeof( m_module_def ) ); |
| |
|
| | m_module_def.m_name = const_cast<char *>( m_module_name.c_str() ); |
| | m_module_def.m_doc = const_cast<char *>( module_doc ); |
| | m_module_def.m_methods = m_method_table.table(); |
| | |
| |
|
| | m_module = PyModule_Create( &m_module_def ); |
| | } |
| |
|
| | Module ExtensionModuleBase::module( void ) const |
| | { |
| | return Module( m_module ); |
| | } |
| |
|
| | Dict ExtensionModuleBase::moduleDictionary( void ) const |
| | { |
| | return module().getDict(); |
| | } |
| |
|
| | Object ExtensionModuleBase::moduleObject( void ) const |
| | { |
| | return Object( m_module ); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | extern "C" |
| | { |
| | static void standard_dealloc( PyObject *p ); |
| | |
| | |
| | |
| | |
| | #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 |
| | static int print_handler( PyObject *, FILE *, int ); |
| | #endif |
| | static PyObject *getattr_handler( PyObject *, char * ); |
| | static int setattr_handler( PyObject *, char *, PyObject * ); |
| | static PyObject *getattro_handler( PyObject *, PyObject * ); |
| | static int setattro_handler( PyObject *, PyObject *, PyObject * ); |
| | static PyObject *rich_compare_handler( PyObject *, PyObject *, int ); |
| | static PyObject *repr_handler( PyObject * ); |
| | static PyObject *str_handler( PyObject * ); |
| | static Py_hash_t hash_handler( PyObject * ); |
| | static PyObject *call_handler( PyObject *, PyObject *, PyObject * ); |
| | static PyObject *iter_handler( PyObject * ); |
| | static PyObject *iternext_handler( PyObject * ); |
| |
|
| | |
| | static Py_ssize_t sequence_length_handler( PyObject * ); |
| | static PyObject *sequence_concat_handler( PyObject *,PyObject * ); |
| | static PyObject *sequence_repeat_handler( PyObject *, Py_ssize_t ); |
| | static PyObject *sequence_item_handler( PyObject *, Py_ssize_t ); |
| | static int sequence_ass_item_handler( PyObject *, Py_ssize_t, PyObject * ); |
| |
|
| | static PyObject *sequence_inplace_concat_handler( PyObject *, PyObject * ); |
| | static PyObject *sequence_inplace_repeat_handler( PyObject *, Py_ssize_t ); |
| |
|
| | static int sequence_contains_handler( PyObject *, PyObject * ); |
| |
|
| | |
| | static Py_ssize_t mapping_length_handler( PyObject * ); |
| | static PyObject *mapping_subscript_handler( PyObject *, PyObject * ); |
| | static int mapping_ass_subscript_handler( PyObject *, PyObject *, PyObject * ); |
| |
|
| | |
| | static PyObject *number_negative_handler( PyObject * ); |
| | static PyObject *number_positive_handler( PyObject * ); |
| | static PyObject *number_absolute_handler( PyObject * ); |
| | static PyObject *number_invert_handler( PyObject * ); |
| | static PyObject *number_int_handler( PyObject * ); |
| | static PyObject *number_float_handler( PyObject * ); |
| | static PyObject *number_add_handler( PyObject *, PyObject * ); |
| | static PyObject *number_subtract_handler( PyObject *, PyObject * ); |
| | static PyObject *number_multiply_handler( PyObject *, PyObject * ); |
| | static PyObject *number_remainder_handler( PyObject *, PyObject * ); |
| | static PyObject *number_divmod_handler( PyObject *, PyObject * ); |
| | static PyObject *number_lshift_handler( PyObject *, PyObject * ); |
| | static PyObject *number_rshift_handler( PyObject *, PyObject * ); |
| | static PyObject *number_and_handler( PyObject *, PyObject * ); |
| | static PyObject *number_xor_handler( PyObject *, PyObject * ); |
| | static PyObject *number_or_handler( PyObject *, PyObject * ); |
| | static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * ); |
| | static PyObject *number_floor_divide_handler( PyObject *, PyObject * ); |
| | static PyObject *number_true_divide_handler( PyObject *, PyObject * ); |
| | static PyObject *number_index_handler( PyObject * ); |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | static PyObject *number_matrix_multiply_handler( PyObject *, PyObject * ); |
| | #endif |
| |
|
| | static PyObject *number_inplace_add_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_subtract_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_multiply_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_remainder_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_power_handler( PyObject *, PyObject *, PyObject * ); |
| | static PyObject *number_inplace_lshift_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_rshift_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_and_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_xor_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_or_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_floor_divide_handler( PyObject *, PyObject * ); |
| | static PyObject *number_inplace_true_divide_handler( PyObject *, PyObject * ); |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | static PyObject *number_inplace_matrix_multiply_handler( PyObject *, PyObject * ); |
| | #endif |
| |
|
| | |
| | #if !defined( Py_LIMITED_API ) |
| | static int buffer_get_handler( PyObject *, Py_buffer *, int ); |
| | static void buffer_release_handler( PyObject *, Py_buffer * ); |
| | #endif |
| | } |
| |
|
| | extern "C" void standard_dealloc( PyObject *p ) |
| | { |
| | PyMem_DEL( p ); |
| | } |
| |
|
| | bool PythonType::readyType() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | if( !tp_object ) |
| | { |
| | std::vector<PyType_Slot> spec_slots( slots.size() + 1 ); |
| | int index = 0; |
| |
|
| | for (std::unordered_map<int, void*>::const_iterator i = slots.cbegin(); i != slots.cend(); i++) |
| | { |
| | spec_slots[ index ].slot = i->first; |
| | spec_slots[ index ].pfunc = i->second; |
| | index++; |
| | } |
| | spec_slots[ index ].slot = 0; |
| | spec->slots = spec_slots.data(); |
| | tp_object = reinterpret_cast<PyTypeObject *>( PyType_FromSpec(spec) ); |
| | } |
| | return tp_object != NULL; |
| | #else |
| | return PyType_Ready( table ) >= 0; |
| | #endif |
| | } |
| |
|
| | #if defined( Py_LIMITED_API ) |
| | #define FILL_SEQUENCE_SLOT(slot) \ |
| | if( methods_to_support&support_sequence_ ## slot ) { \ |
| | slots[ Py_sq_ ## slot ] = reinterpret_cast<void *>( sequence_ ## slot ## _handler ); \ |
| | } |
| | #else |
| | #define FILL_SEQUENCE_SLOT(slot) \ |
| | if( methods_to_support&support_sequence_ ## slot ) { \ |
| | sequence_table->sq_ ## slot = sequence_ ## slot ## _handler; \ |
| | } |
| | #endif |
| |
|
| | PythonType &PythonType::supportSequenceType( int methods_to_support ) { |
| | #if !defined( Py_LIMITED_API ) |
| | if(sequence_table) |
| | { |
| | return *this; |
| | } |
| | sequence_table = new PySequenceMethods; |
| | memset( sequence_table, 0, sizeof( PySequenceMethods ) ); |
| | table->tp_as_sequence = sequence_table; |
| | #endif |
| |
|
| | FILL_SEQUENCE_SLOT(length) |
| | FILL_SEQUENCE_SLOT(concat) |
| | FILL_SEQUENCE_SLOT(repeat) |
| | FILL_SEQUENCE_SLOT(item) |
| | FILL_SEQUENCE_SLOT(ass_item) |
| | FILL_SEQUENCE_SLOT(inplace_concat) |
| | FILL_SEQUENCE_SLOT(inplace_repeat) |
| | FILL_SEQUENCE_SLOT(contains) |
| | return *this; |
| | } |
| |
|
| | #undef FILL_SEQUENCE_SLOT |
| |
|
| | #if defined( Py_LIMITED_API ) |
| | #define FILL_MAPPING_SLOT(slot) \ |
| | if( methods_to_support&support_mapping_ ## slot ) { \ |
| | slots[ Py_mp_ ## slot ] = reinterpret_cast<void *>( mapping_ ## slot ## _handler ); \ |
| | } |
| | #else |
| | #define FILL_MAPPING_SLOT(slot) \ |
| | if( methods_to_support&support_mapping_ ## slot ) { \ |
| | mapping_table->mp_ ## slot = mapping_ ## slot ## _handler; \ |
| | } |
| | #endif |
| |
|
| | PythonType &PythonType::supportMappingType( int methods_to_support ) |
| | { |
| | #if !defined( Py_LIMITED_API ) |
| | if( mapping_table ) |
| | { |
| | return *this; |
| | } |
| | mapping_table = new PyMappingMethods; |
| | memset( mapping_table, 0, sizeof( PyMappingMethods ) ); |
| | table->tp_as_mapping = mapping_table; |
| | #endif |
| | FILL_MAPPING_SLOT(length) |
| | FILL_MAPPING_SLOT(subscript) |
| | FILL_MAPPING_SLOT(ass_subscript) |
| | return *this; |
| | } |
| |
|
| | #undef FILL_MAPPING_SLOT |
| |
|
| | #if defined( Py_LIMITED_API ) |
| | #define FILL_NUMBER_SLOT(slot) \ |
| | if( methods_to_support&support_number_ ## slot ) { \ |
| | slots[ Py_nb_ ## slot ] = reinterpret_cast<void *>( number_ ## slot ## _handler ); \ |
| | } |
| | #define FILL_NUMBER_INPLACE_SLOT(slot) \ |
| | if( inplace_methods_to_support&support_number_ ## slot ) { \ |
| | slots[ Py_nb_ ## slot ] = reinterpret_cast<void *>( number_ ## slot ## _handler ); \ |
| | } |
| | #else |
| | #define FILL_NUMBER_SLOT(slot) \ |
| | if( methods_to_support&support_number_ ## slot ) { \ |
| | number_table->nb_ ## slot = number_ ## slot ## _handler; \ |
| | } |
| | #define FILL_NUMBER_INPLACE_SLOT(slot) \ |
| | if( inplace_methods_to_support&support_number_ ## slot ) { \ |
| | number_table->nb_ ## slot = number_ ## slot ## _handler; \ |
| | } |
| | #endif |
| |
|
| | PythonType &PythonType::supportNumberType( int methods_to_support, int inplace_methods_to_support ) |
| | { |
| | #if !defined( Py_LIMITED_API ) |
| | if( number_table ) |
| | { |
| | return *this; |
| | } |
| | number_table = new PyNumberMethods; |
| | memset( number_table, 0, sizeof( PyNumberMethods ) ); |
| | table->tp_as_number = number_table; |
| | #endif |
| |
|
| | FILL_NUMBER_SLOT(add) |
| | FILL_NUMBER_SLOT(subtract) |
| | FILL_NUMBER_SLOT(multiply) |
| | FILL_NUMBER_SLOT(remainder) |
| | FILL_NUMBER_SLOT(divmod) |
| | FILL_NUMBER_SLOT(power) |
| | FILL_NUMBER_SLOT(negative) |
| | FILL_NUMBER_SLOT(positive) |
| | FILL_NUMBER_SLOT(absolute) |
| | FILL_NUMBER_SLOT(invert) |
| | FILL_NUMBER_SLOT(lshift) |
| | FILL_NUMBER_SLOT(rshift) |
| | FILL_NUMBER_SLOT(and) |
| | FILL_NUMBER_SLOT(xor) |
| | FILL_NUMBER_SLOT(or) |
| | FILL_NUMBER_SLOT(int) |
| | FILL_NUMBER_SLOT(float) |
| | FILL_NUMBER_SLOT(floor_divide) |
| | FILL_NUMBER_SLOT(true_divide) |
| | FILL_NUMBER_SLOT(index) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | FILL_NUMBER_SLOT(matrix_multiply) |
| | #endif |
| |
|
| | FILL_NUMBER_INPLACE_SLOT(inplace_add) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_subtract) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_multiply) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_remainder) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_power) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_lshift) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_rshift) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_and) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_xor) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_or) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_floor_divide) |
| | FILL_NUMBER_INPLACE_SLOT(inplace_true_divide) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | FILL_NUMBER_INPLACE_SLOT(inplace_matrix_multiply) |
| | #endif |
| |
|
| | return *this; |
| | } |
| |
|
| | #undef FILL_NUMBER_SLOT |
| |
|
| | #if !defined( Py_LIMITED_API ) |
| | PythonType &PythonType::supportBufferType( int methods_to_support ) |
| | { |
| | if( !buffer_table ) |
| | { |
| | buffer_table = new PyBufferProcs; |
| | memset( buffer_table, 0, sizeof( PyBufferProcs ) ); |
| | table->tp_as_buffer = buffer_table; |
| |
|
| | if( methods_to_support&support_buffer_getbuffer ) |
| | { |
| | buffer_table->bf_getbuffer = buffer_get_handler; |
| | } |
| | if( methods_to_support&support_buffer_releasebuffer ) |
| | { |
| | buffer_table->bf_releasebuffer = buffer_release_handler; |
| | } |
| | } |
| | return *this; |
| | } |
| | #endif |
| |
|
| | |
| | |
| |
|
| | #if defined( Py_LIMITED_API ) |
| | PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name ) |
| | : spec( new PyType_Spec ) |
| | { |
| | memset( spec, 0, sizeof( PyType_Spec ) ); |
| | spec->name = const_cast<char *>( default_name ); |
| | spec->basicsize = basic_size; |
| | spec->itemsize = itemsize; |
| | spec->flags = Py_TPFLAGS_DEFAULT; |
| |
|
| | slots[ Py_tp_dealloc ] = reinterpret_cast<void *>( standard_dealloc ); |
| |
|
| | tp_object = 0; |
| | } |
| |
|
| | #else |
| | PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name ) |
| | : table( new PyTypeObject ) |
| | , sequence_table( NULL ) |
| | , mapping_table( NULL ) |
| | , number_table( NULL ) |
| | , buffer_table( NULL ) |
| | { |
| | |
| |
|
| | memset( table, 0, sizeof( PyTypeObject ) ); |
| | *reinterpret_cast<PyObject *>( table ) = py_object_initializer; |
| | reinterpret_cast<PyObject *>( table )->ob_type = _Type_Type(); |
| | |
| | table->tp_name = const_cast<char *>( default_name ); |
| | table->tp_basicsize = basic_size; |
| | table->tp_itemsize = itemsize; |
| |
|
| | |
| | table->tp_dealloc = (destructor)standard_dealloc; |
| | #if PY_VERSION_HEX < 0x03080000 |
| | table->tp_print = 0; |
| | #else |
| | table->tp_vectorcall_offset = 0; |
| | #endif |
| | table->tp_getattr = 0; |
| | table->tp_setattr = 0; |
| | table->tp_repr = 0; |
| |
|
| | |
| | table->tp_as_number = 0; |
| | table->tp_as_sequence = 0; |
| | table->tp_as_mapping = 0; |
| |
|
| | |
| | table->tp_hash = 0; |
| | table->tp_call = 0; |
| | table->tp_str = 0; |
| | table->tp_getattro = 0; |
| | table->tp_setattro = 0; |
| |
|
| | |
| | table->tp_as_buffer = 0; |
| |
|
| | |
| | table->tp_flags = Py_TPFLAGS_DEFAULT; |
| |
|
| | |
| | table->tp_doc = 0; |
| |
|
| | table->tp_traverse = 0; |
| |
|
| | |
| | table->tp_clear = 0; |
| |
|
| | |
| | |
| | table->tp_richcompare = 0; |
| | |
| | table->tp_weaklistoffset = 0; |
| |
|
| | |
| | table->tp_iter = 0; |
| | table->tp_iternext = 0; |
| |
|
| | |
| | table->tp_methods = 0; |
| | table->tp_members = 0; |
| | table->tp_getset = 0; |
| | table->tp_base = 0; |
| | table->tp_dict = 0; |
| | table->tp_descr_get = 0; |
| | table->tp_descr_set = 0; |
| | table->tp_dictoffset = 0; |
| | table->tp_init = 0; |
| | table->tp_alloc = 0; |
| | table->tp_new = 0; |
| | table->tp_free = 0; |
| | table->tp_is_gc = 0; |
| | table->tp_bases = 0; |
| | table->tp_mro = 0; |
| | table->tp_cache = 0; |
| | table->tp_subclasses = 0; |
| | table->tp_weaklist = 0; |
| | table->tp_del = 0; |
| |
|
| | |
| | table->tp_version_tag = 0; |
| |
|
| | #ifdef COUNT_ALLOCS |
| | table->tp_alloc = 0; |
| | table->tp_free = 0; |
| | table->tp_maxalloc = 0; |
| | table->tp_orev = 0; |
| | table->tp_next = 0; |
| | #endif |
| | } |
| | #endif |
| |
|
| | PythonType::~PythonType() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | delete spec; |
| | PyObject_Free( tp_object ); |
| | #else |
| | delete table; |
| | delete sequence_table; |
| | delete mapping_table; |
| | delete number_table; |
| | delete buffer_table; |
| | #endif |
| | } |
| |
|
| | PyTypeObject *PythonType::type_object() const |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | return tp_object; |
| | #else |
| | return table; |
| | #endif |
| | } |
| |
|
| | PythonType &PythonType::name( const char *nam ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | spec->name = nam; |
| | #else |
| | table->tp_name = const_cast<char *>( nam ); |
| | #endif |
| | return *this; |
| | } |
| |
|
| | const char *PythonType::getName() const |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | return spec->name; |
| | #else |
| | return table->tp_name; |
| | #endif |
| | } |
| |
|
| | PythonType &PythonType::doc( const char *d ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_doc ] = reinterpret_cast<void *>( const_cast<char *>( d ) ); |
| | #else |
| | table->tp_doc = const_cast<char *>( d ); |
| | #endif |
| | return *this; |
| | } |
| |
|
| | const char *PythonType::getDoc() const |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | if( tp_object ) |
| | return reinterpret_cast<char *>( PyType_GetSlot( tp_object, Py_tp_doc ) ); |
| |
|
| | std::unordered_map<int, void*>::const_iterator slot = slots.find( Py_tp_doc ); |
| | if( slot == slots.end() ) |
| | return NULL; |
| | return reinterpret_cast<char *>( slot->second ); |
| | #else |
| | return table->tp_doc; |
| | #endif |
| | } |
| |
|
| | PythonType &PythonType::set_tp_dealloc( void (*tp_dealloc)( PyObject *self ) ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_dealloc ] = reinterpret_cast<void *>( tp_dealloc ); |
| | #else |
| | table->tp_dealloc = tp_dealloc; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::set_tp_init( int (*tp_init)( PyObject *self, PyObject *args, PyObject *kwds ) ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_init ] = reinterpret_cast<void *>( tp_init ); |
| | #else |
| | table->tp_init = tp_init; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::set_tp_new( PyObject *(*tp_new)( PyTypeObject *subtype, PyObject *args, PyObject *kwds ) ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_new ] = reinterpret_cast<void *>( tp_new ); |
| | #else |
| | table->tp_new = tp_new; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::set_methods( PyMethodDef *methods ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_methods ] = reinterpret_cast<void *>( methods ); |
| | #else |
| | table->tp_methods = methods; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportClass() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | spec->flags |= Py_TPFLAGS_BASETYPE; |
| | #else |
| | table->tp_flags |= Py_TPFLAGS_BASETYPE; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 |
| | PythonType &PythonType::supportPrint() |
| | { |
| | #if PY_VERSION_HEX < 0x03080000 |
| | table->tp_print = print_handler; |
| | #endif |
| | return *this; |
| | } |
| | #endif |
| |
|
| | PythonType &PythonType::supportGetattr() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_getattr ] = reinterpret_cast<void *>( getattr_handler ); |
| | #else |
| | table->tp_getattr = getattr_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportSetattr() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_setattr ] = reinterpret_cast<void *>( setattr_handler ); |
| | #else |
| | table->tp_setattr = setattr_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportGetattro() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_getattro ] = reinterpret_cast<void *>( getattro_handler ); |
| | #else |
| | table->tp_getattro = getattro_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportSetattro() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_setattro ] = reinterpret_cast<void *>( setattro_handler ); |
| | #else |
| | table->tp_setattro = setattro_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | #ifdef PYCXX_PYTHON_2TO3 |
| | PythonType &PythonType::supportCompare( void ) |
| | { |
| | return *this; |
| | } |
| | #endif |
| |
|
| |
|
| | PythonType &PythonType::supportRichCompare() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_richcompare ] = reinterpret_cast<void *>( rich_compare_handler ); |
| | #else |
| | table->tp_richcompare = rich_compare_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportRepr() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_repr ] = reinterpret_cast<void *>( repr_handler ); |
| | #else |
| | table->tp_repr = repr_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportStr() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_str ] = reinterpret_cast<void *>( str_handler ); |
| | #else |
| | table->tp_str = str_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportHash() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_hash ] = reinterpret_cast<void *>( hash_handler ); |
| | #else |
| | table->tp_hash = hash_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportCall() |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_call ] = reinterpret_cast<void *>( call_handler ); |
| | #else |
| | table->tp_call = call_handler; |
| | #endif |
| | return *this; |
| | } |
| |
|
| | PythonType &PythonType::supportIter( int methods_to_support ) |
| | { |
| | if( methods_to_support&support_iter_iter ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_iter ] = reinterpret_cast<void *>( iter_handler ); |
| | #else |
| | table->tp_iter = iter_handler; |
| | #endif |
| | } |
| | if( methods_to_support&support_iter_iternext ) |
| | { |
| | #if defined( Py_LIMITED_API ) |
| | slots[ Py_tp_iternext ] = reinterpret_cast<void *>( iternext_handler ); |
| | #else |
| | table->tp_iternext = iternext_handler; |
| | #endif |
| | } |
| | return *this; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | PythonExtensionBase *getPythonExtensionBase( PyObject *self ) |
| | { |
| | if(PyType_HasFeature(self->ob_type, Py_TPFLAGS_BASETYPE)) |
| | { |
| | PythonClassInstance *instance = reinterpret_cast<PythonClassInstance *>( self ); |
| | return instance->m_pycxx_object; |
| | } |
| | else |
| | { |
| | return static_cast<PythonExtensionBase *>( self ); |
| | } |
| | } |
| |
|
| | #if defined( PYCXX_PYTHON_2TO3 ) && !defined ( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 |
| | extern "C" int print_handler( PyObject *self, FILE *fp, int flags ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->print( fp, flags ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| | #endif |
| |
|
| | extern "C" PyObject *getattr_handler( PyObject *self, char *name ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->getattr( name ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" int setattr_handler( PyObject *self, char *name, PyObject *value ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->setattr( name, Object( value ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *getattro_handler( PyObject *self, PyObject *name ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->getattro( String( name ) ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" int setattro_handler( PyObject *self, PyObject *name, PyObject *value ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->setattro( String( name ), Object( value ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *rich_compare_handler( PyObject *self, PyObject *other, int op ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->rich_compare( Object( other ), op ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *repr_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->repr() ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *str_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->str() ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" Py_hash_t hash_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->hash(); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | if( kw != NULL ) |
| | return new_reference_to( p->call( Object( args ), Object( kw ) ) ); |
| | else |
| | return new_reference_to( p->call( Object( args ), Object() ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *iter_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->iter() ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *iternext_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->iternext(); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| |
|
| | |
| | extern "C" Py_ssize_t sequence_length_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->sequence_length(); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *sequence_concat_handler( PyObject *self, PyObject *other ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->sequence_concat( Object( other ) ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *sequence_repeat_handler( PyObject *self, Py_ssize_t count ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->sequence_repeat( count ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *sequence_item_handler( PyObject *self, Py_ssize_t index ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->sequence_item( index ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" int sequence_ass_item_handler( PyObject *self, Py_ssize_t index, PyObject *value ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->sequence_ass_item( index, Object( value ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *sequence_inplace_concat_handler( PyObject *self, PyObject *o2 ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->sequence_inplace_concat( Object( o2 ) ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *sequence_inplace_repeat_handler( PyObject *self, Py_ssize_t count ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->sequence_inplace_repeat( count ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" int sequence_contains_handler( PyObject *self, PyObject *value ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->sequence_contains( Object( value ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | |
| | extern "C" Py_ssize_t mapping_length_handler( PyObject *self ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->mapping_length(); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *mapping_subscript_handler( PyObject *self, PyObject *key ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return new_reference_to( p->mapping_subscript( Object( key ) ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return NULL; |
| | } |
| | } |
| |
|
| | extern "C" int mapping_ass_subscript_handler( PyObject *self, PyObject *key, PyObject *value ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->mapping_ass_subscript( Object( key ), Object( value ) ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | |
| | #define NUMBER_UNARY( slot ) \ |
| | extern "C" PyObject *number_ ## slot ## _handler( PyObject *self ) \ |
| | { \ |
| | try \ |
| | { \ |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); \ |
| | return new_reference_to( p->number_ ## slot() ); \ |
| | } \ |
| | catch( BaseException & ) \ |
| | { \ |
| | return NULL; \ |
| | } \ |
| | } |
| |
|
| | #define NUMBER_BINARY( slot ) \ |
| | extern "C" PyObject *number_ ## slot ## _handler( PyObject *self, PyObject *other ) \ |
| | { \ |
| | try \ |
| | { \ |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); \ |
| | return new_reference_to( p->number_ ## slot( Object( other ) ) ); \ |
| | } \ |
| | catch( BaseException & ) \ |
| | { \ |
| | return NULL; \ |
| | } \ |
| | } |
| | #define NUMBER_TERNARY( slot ) \ |
| | extern "C" PyObject *number_ ## slot ## _handler( PyObject *self, PyObject *other1, PyObject *other2 ) \ |
| | { \ |
| | try \ |
| | { \ |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); \ |
| | return new_reference_to( p->number_ ## slot( Object( other1 ), Object( other2 ) ) ); \ |
| | } \ |
| | catch( BaseException & ) \ |
| | { \ |
| | return NULL; \ |
| | } \ |
| | } |
| |
|
| | NUMBER_UNARY( negative ) |
| | NUMBER_UNARY( positive ) |
| | NUMBER_UNARY( absolute ) |
| | NUMBER_UNARY( invert ) |
| | NUMBER_UNARY( int ) |
| | NUMBER_UNARY( float ) |
| | NUMBER_BINARY( add ) |
| | NUMBER_BINARY( subtract ) |
| | NUMBER_BINARY( multiply ) |
| | NUMBER_BINARY( remainder ) |
| | NUMBER_BINARY( divmod ) |
| | NUMBER_BINARY( lshift ) |
| | NUMBER_BINARY( rshift ) |
| | NUMBER_BINARY( and ) |
| | NUMBER_BINARY( xor ) |
| | NUMBER_BINARY( or ) |
| | NUMBER_TERNARY( power ) |
| | NUMBER_BINARY( floor_divide ) |
| | NUMBER_BINARY( true_divide ) |
| | NUMBER_UNARY( index ) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | NUMBER_BINARY( matrix_multiply ) |
| | #endif |
| | NUMBER_BINARY( inplace_add ) |
| | NUMBER_BINARY( inplace_subtract ) |
| | NUMBER_BINARY( inplace_multiply ) |
| | NUMBER_BINARY( inplace_remainder ) |
| | NUMBER_TERNARY( inplace_power ) |
| | NUMBER_BINARY( inplace_lshift ) |
| | NUMBER_BINARY( inplace_rshift ) |
| | NUMBER_BINARY( inplace_and ) |
| | NUMBER_BINARY( inplace_xor ) |
| | NUMBER_BINARY( inplace_or ) |
| | NUMBER_BINARY( inplace_floor_divide ) |
| | NUMBER_BINARY( inplace_true_divide ) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | NUMBER_BINARY( inplace_matrix_multiply ) |
| | #endif |
| |
|
| | #undef NUMBER_UNARY |
| | #undef NUMBER_BINARY |
| | #undef NUMBER_TERNARY |
| |
|
| | |
| | #ifndef Py_LIMITED_API |
| | extern "C" int buffer_get_handler( PyObject *self, Py_buffer *buf, int flags ) |
| | { |
| | try |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | return p->buffer_get( buf, flags ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return -1; |
| | } |
| | } |
| |
|
| | extern "C" void buffer_release_handler( PyObject *self, Py_buffer *buf ) |
| | { |
| | PythonExtensionBase *p = getPythonExtensionBase( self ); |
| | p->buffer_release( buf ); |
| | |
| | } |
| | #endif |
| |
|
| | |
| | |
| | |
| | |
| | |
| | #define missing_method( method ) \ |
| | throw RuntimeError( "Extension object missing implement of " #method ); |
| |
|
| | PythonExtensionBase::PythonExtensionBase() |
| | { |
| | ob_refcnt = 0; |
| | } |
| |
|
| | PythonExtensionBase::~PythonExtensionBase() |
| | { |
| | assert( ob_refcnt == 0 ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name ) |
| | { |
| | TupleN args; |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1 ) |
| | { |
| | TupleN args( arg1 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1, const Object &arg2 ) |
| | { |
| | TupleN args( arg1, arg2 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1, const Object &arg2, const Object &arg3 ) |
| | { |
| | TupleN args( arg1, arg2, arg3 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1, const Object &arg2, const Object &arg3, |
| | const Object &arg4 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1, const Object &arg2, const Object &arg3, |
| | const Object &arg4, const Object &arg5 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4, arg5 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::callOnSelf( const std::string &fn_name, |
| | const Object &arg1, const Object &arg2, const Object &arg3, |
| | const Object &arg4, const Object &arg5, const Object &arg6 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::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 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::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 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | Object PythonExtensionBase::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 ) |
| | { |
| | TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); |
| | return self().callMemberFunction( fn_name, args ); |
| | } |
| |
|
| | void PythonExtensionBase::reinit( Tuple & , Dict & ) |
| | { |
| | throw RuntimeError( "Must not call __init__ twice on this class" ); |
| | } |
| |
|
| |
|
| | Object PythonExtensionBase::genericGetAttro( const String &name ) |
| | { |
| | return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) ); |
| | } |
| |
|
| | int PythonExtensionBase::genericSetAttro( const String &name, const Object &value ) |
| | { |
| | return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() ); |
| | } |
| |
|
| | #if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 |
| | int PythonExtensionBase::print( FILE *, int ) |
| | { |
| | missing_method( print ); |
| | } |
| | #endif |
| |
|
| | Object PythonExtensionBase::getattr( const char * ) |
| | { |
| | missing_method( getattr ); |
| | } |
| |
|
| | int PythonExtensionBase::setattr( const char *, const Object & ) |
| | { |
| | missing_method( setattr ); |
| | } |
| |
|
| | Object PythonExtensionBase::getattro( const String &name ) |
| | { |
| | return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) ); |
| | } |
| |
|
| | int PythonExtensionBase::setattro( const String &name, const Object &value ) |
| | { |
| | return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() ); |
| | } |
| |
|
| |
|
| | int PythonExtensionBase::compare( const Object & ) |
| | { |
| | missing_method( compare ); |
| | } |
| |
|
| | Object PythonExtensionBase::rich_compare( const Object &, int ) |
| | { |
| | missing_method( rich_compare ); |
| | } |
| |
|
| | Object PythonExtensionBase::repr() |
| | { |
| | missing_method( repr ); |
| | } |
| |
|
| | Object PythonExtensionBase::str() |
| | { |
| | missing_method( str ); |
| | } |
| |
|
| | long PythonExtensionBase::hash() |
| | { |
| | missing_method( hash ); |
| | } |
| |
|
| | Object PythonExtensionBase::call( const Object &, const Object & ) |
| | { |
| | missing_method( call ); |
| | } |
| |
|
| | Object PythonExtensionBase::iter() |
| | { |
| | missing_method( iter ); |
| | } |
| |
|
| | PyObject *PythonExtensionBase::iternext() |
| | { |
| | missing_method( iternext ); |
| | } |
| |
|
| | |
| | PyCxx_ssize_t PythonExtensionBase::sequence_length() |
| | { |
| | missing_method( sequence_length ); |
| | } |
| |
|
| | Object PythonExtensionBase::sequence_concat( const Object & ) |
| | { |
| | missing_method( sequence_concat ); |
| | } |
| |
|
| | Object PythonExtensionBase::sequence_repeat( Py_ssize_t ) |
| | { |
| | missing_method( sequence_repeat ); |
| | } |
| |
|
| | Object PythonExtensionBase::sequence_item( Py_ssize_t ) |
| | { |
| | missing_method( sequence_item ); |
| | } |
| |
|
| | int PythonExtensionBase::sequence_ass_item( Py_ssize_t, const Object & ) |
| | { |
| | missing_method( sequence_ass_item ); |
| | } |
| |
|
| | Object PythonExtensionBase::sequence_inplace_concat( const Object & ) |
| | { |
| | missing_method( sequence_inplace_concat ); |
| | } |
| |
|
| | Object PythonExtensionBase::sequence_inplace_repeat( Py_ssize_t ) |
| | { |
| | missing_method( sequence_inplace_repeat ); |
| | } |
| |
|
| | int PythonExtensionBase::sequence_contains( const Object & ) |
| | { |
| | missing_method( sequence_contains ); |
| | } |
| |
|
| | |
| | PyCxx_ssize_t PythonExtensionBase::mapping_length() |
| | { |
| | missing_method( mapping_length ); |
| | } |
| |
|
| | Object PythonExtensionBase::mapping_subscript( const Object & ) |
| | { |
| | missing_method( mapping_subscript ); |
| | } |
| |
|
| | int PythonExtensionBase::mapping_ass_subscript( const Object &, const Object & ) |
| | { |
| | missing_method( mapping_ass_subscript ); |
| | } |
| |
|
| | |
| | #define NUMBER_UNARY( slot ) Object PythonExtensionBase::number_ ## slot() \ |
| | { missing_method( number_ ## slot ); } |
| | #define NUMBER_BINARY( slot ) Object PythonExtensionBase::number_ ## slot( const Object & ) \ |
| | { missing_method( number_ ## slot ); } |
| | #define NUMBER_TERNARY( slot ) Object PythonExtensionBase::number_ ## slot( const Object &, const Object & ) \ |
| | { missing_method( number_ ## slot ); } |
| |
|
| | NUMBER_UNARY( negative ) |
| | NUMBER_UNARY( positive ) |
| | NUMBER_UNARY( absolute ) |
| | NUMBER_UNARY( invert ) |
| | NUMBER_UNARY( int ) |
| | NUMBER_UNARY( float ) |
| | NUMBER_BINARY( add ) |
| | NUMBER_BINARY( subtract ) |
| | NUMBER_BINARY( multiply ) |
| | NUMBER_BINARY( remainder ) |
| | NUMBER_BINARY( divmod ) |
| | NUMBER_BINARY( lshift ) |
| | NUMBER_BINARY( rshift ) |
| | NUMBER_BINARY( and ) |
| | NUMBER_BINARY( xor ) |
| | NUMBER_BINARY( or ) |
| | NUMBER_TERNARY( power ) |
| | NUMBER_BINARY( floor_divide ) |
| | NUMBER_BINARY( true_divide ) |
| | NUMBER_UNARY( index ) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | NUMBER_BINARY( matrix_multiply ) |
| | #endif |
| |
|
| | NUMBER_BINARY( inplace_add ) |
| | NUMBER_BINARY( inplace_subtract ) |
| | NUMBER_BINARY( inplace_multiply ) |
| | NUMBER_BINARY( inplace_remainder ) |
| | NUMBER_TERNARY( inplace_power ) |
| | NUMBER_BINARY( inplace_lshift ) |
| | NUMBER_BINARY( inplace_rshift ) |
| | NUMBER_BINARY( inplace_and ) |
| | NUMBER_BINARY( inplace_xor ) |
| | NUMBER_BINARY( inplace_or ) |
| | NUMBER_BINARY( inplace_floor_divide ) |
| | NUMBER_BINARY( inplace_true_divide ) |
| | #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 |
| | NUMBER_BINARY( inplace_matrix_multiply ) |
| | #endif |
| |
|
| | #undef NUMBER_UNARY |
| | #undef NUMBER_BINARY |
| | #undef NUMBER_TERNARY |
| |
|
| |
|
| | |
| | #ifndef Py_LIMITED_API |
| | int PythonExtensionBase::buffer_get( Py_buffer * , int ) |
| | { |
| | missing_method( buffer_get ); |
| | } |
| |
|
| | int PythonExtensionBase::buffer_release( Py_buffer * ) |
| | { |
| | |
| | |
| | return 0; |
| | } |
| | #endif |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | extern "C" PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * ) |
| | { |
| | try |
| | { |
| | Tuple self_and_name_tuple( _self_and_name_tuple ); |
| |
|
| | PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); |
| | void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); |
| | if( self_as_void == NULL ) |
| | return NULL; |
| |
|
| | ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void ); |
| |
|
| | Object result( self->invoke_method_noargs( PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ) ); |
| |
|
| | return new_reference_to( result.ptr() ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return 0; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args ) |
| | { |
| | try |
| | { |
| | Tuple self_and_name_tuple( _self_and_name_tuple ); |
| |
|
| | PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); |
| | void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); |
| | if( self_as_void == NULL ) |
| | return NULL; |
| |
|
| | ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void ); |
| | Tuple args( _args ); |
| | Object result |
| | ( |
| | self->invoke_method_varargs |
| | ( |
| | PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), |
| | args |
| | ) |
| | ); |
| |
|
| | return new_reference_to( result.ptr() ); |
| | } |
| | catch( BaseException & ) |
| | { |
| | return 0; |
| | } |
| | } |
| |
|
| | extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords ) |
| | { |
| | try |
| | { |
| | Tuple self_and_name_tuple( _self_and_name_tuple ); |
| |
|
| | PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); |
| | void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); |
| | if( self_as_void == NULL ) |
| | return NULL; |
| |
|
| | ExtensionModuleBase *self = static_cast<ExtensionModuleBase *>( self_as_void ); |
| |
|
| | Tuple args( _args ); |
| |
|
| | if( _keywords == NULL ) |
| | { |
| | Dict keywords; |
| |
|
| | Object result |
| | ( |
| | self->invoke_method_keyword |
| | ( |
| | PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), |
| | args, |
| | keywords |
| | ) |
| | ); |
| |
|
| | return new_reference_to( result.ptr() ); |
| | } |
| | else |
| | { |
| | Dict keywords( _keywords ); |
| |
|
| | Object result |
| | ( |
| | self->invoke_method_keyword |
| | ( |
| | PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), |
| | args, |
| | keywords |
| | ) |
| | ); |
| |
|
| | return new_reference_to( result.ptr() ); |
| | } |
| | } |
| | catch( BaseException & ) |
| | { |
| | return 0; |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | ExtensionExceptionType::ExtensionExceptionType() |
| | : Object() |
| | { |
| | } |
| |
|
| | void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name ) |
| | { |
| | std::string module_name( module.fullName() ); |
| | module_name += "."; |
| | module_name += name; |
| |
|
| | set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), NULL, NULL ), true ); |
| | } |
| |
|
| | void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent ) |
| | { |
| | std::string module_name( module.fullName() ); |
| | module_name += "."; |
| | module_name += name; |
| |
|
| | set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true ); |
| | } |
| |
|
| | ExtensionExceptionType::~ExtensionExceptionType() |
| | { |
| | } |
| |
|
| | BaseException::BaseException( ExtensionExceptionType &exception, const std::string& reason ) |
| | { |
| | PyErr_SetString( exception.ptr(), reason.c_str() ); |
| | } |
| |
|
| | BaseException::BaseException( ExtensionExceptionType &exception, Object &reason ) |
| | { |
| | PyErr_SetObject( exception.ptr(), reason.ptr() ); |
| | } |
| |
|
| | BaseException::BaseException( PyObject *exception, Object &reason ) |
| | { |
| | PyErr_SetObject( exception, reason.ptr() ); |
| | } |
| |
|
| | BaseException::BaseException( PyObject *exception, const std::string &reason ) |
| | { |
| | PyErr_SetString( exception, reason.c_str() ); |
| | } |
| |
|
| | BaseException::BaseException() |
| | { |
| | } |
| |
|
| | void BaseException::clear() |
| | { |
| | PyErr_Clear(); |
| | } |
| |
|
| | |
| | bool BaseException::matches( ExtensionExceptionType &exc ) |
| | { |
| | return PyErr_ExceptionMatches( exc.ptr() ) != 0; |
| | } |
| |
|
| | Object BaseException::errorType() |
| | { |
| | PyObject *type, *value, *traceback; |
| | PyErr_Fetch( &type, &value, &traceback ); |
| |
|
| | Object result( type ); |
| |
|
| | PyErr_Restore( type, value, traceback ); |
| | return result; |
| | } |
| |
|
| | Object BaseException::errorValue() |
| | { |
| | PyObject *type, *value, *traceback; |
| | PyErr_Fetch( &type, &value, &traceback ); |
| |
|
| | Object result( value ); |
| |
|
| | PyErr_Restore( type, value, traceback ); |
| | return result; |
| | } |
| |
|
| |
|
| | |
| |
|
| | #if 1 |
| | |
| | |
| | bool operator!=( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() != b.as_long(); |
| | } |
| |
|
| | bool operator!=( const Long &a, int b ) |
| | { |
| | return a.as_long() != b; |
| | } |
| |
|
| | bool operator!=( const Long &a, long b ) |
| | { |
| | return a.as_long() != b; |
| | } |
| |
|
| | bool operator!=( int a, const Long &b ) |
| | { |
| | return a != b.as_long(); |
| | } |
| |
|
| | bool operator!=( long a, const Long &b ) |
| | { |
| | return a != b.as_long(); |
| | } |
| |
|
| | |
| | bool operator==( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() == b.as_long(); |
| | } |
| |
|
| | bool operator==( const Long &a, int b ) |
| | { |
| | return a.as_long() == b; |
| | } |
| |
|
| | bool operator==( const Long &a, long b ) |
| | { |
| | return a.as_long() == b; |
| | } |
| |
|
| | bool operator==( int a, const Long &b ) |
| | { |
| | return a == b.as_long(); |
| | } |
| |
|
| | bool operator==( long a, const Long &b ) |
| | { |
| | return a == b.as_long(); |
| | } |
| |
|
| | |
| | bool operator>( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() > b.as_long(); |
| | } |
| |
|
| | bool operator>( const Long &a, int b ) |
| | { |
| | return a.as_long() > b; |
| | } |
| |
|
| | bool operator>( const Long &a, long b ) |
| | { |
| | return a.as_long() > b; |
| | } |
| |
|
| | bool operator>( int a, const Long &b ) |
| | { |
| | return a > b.as_long(); |
| | } |
| |
|
| | bool operator>( long a, const Long &b ) |
| | { |
| | return a > b.as_long(); |
| | } |
| |
|
| | |
| | bool operator>=( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() >= b.as_long(); |
| | } |
| |
|
| | bool operator>=( const Long &a, int b ) |
| | { |
| | return a.as_long() >= b; |
| | } |
| |
|
| | bool operator>=( const Long &a, long b ) |
| | { |
| | return a.as_long() >= b; |
| | } |
| |
|
| | bool operator>=( int a, const Long &b ) |
| | { |
| | return a >= b.as_long(); |
| | } |
| |
|
| | bool operator>=( long a, const Long &b ) |
| | { |
| | return a >= b.as_long(); |
| | } |
| |
|
| | |
| | bool operator<( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() < b.as_long(); |
| | } |
| |
|
| | bool operator<( const Long &a, int b ) |
| | { |
| | return a.as_long() < b; |
| | } |
| |
|
| | bool operator<( const Long &a, long b ) |
| | { |
| | return a.as_long() < b; |
| | } |
| |
|
| | bool operator<( int a, const Long &b ) |
| | { |
| | return a < b.as_long(); |
| | } |
| |
|
| | bool operator<( long a, const Long &b ) |
| | { |
| | return a < b.as_long(); |
| | } |
| |
|
| | |
| | bool operator<=( const Long &a, const Long &b ) |
| | { |
| | return a.as_long() <= b.as_long(); |
| | } |
| |
|
| | bool operator<=( int a, const Long &b ) |
| | { |
| | return a <= b.as_long(); |
| | } |
| |
|
| | bool operator<=( long a, const Long &b ) |
| | { |
| | return a <= b.as_long(); |
| | } |
| |
|
| | bool operator<=( const Long &a, int b ) |
| | { |
| | return a.as_long() <= b; |
| | } |
| |
|
| | bool operator<=( const Long &a, long b ) |
| | { |
| | return a.as_long() <= b; |
| | } |
| |
|
| | #ifdef HAVE_LONG_LONG |
| | |
| | bool operator!=( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() != b; |
| | } |
| |
|
| | bool operator!=( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a != b.as_long_long(); |
| | } |
| |
|
| | |
| | bool operator==( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() == b; |
| | } |
| |
|
| | bool operator==( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a == b.as_long_long(); |
| | } |
| |
|
| | |
| | bool operator>( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() > b; |
| | } |
| |
|
| | bool operator>( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a > b.as_long_long(); |
| | } |
| |
|
| | |
| | bool operator>=( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() >= b; |
| | } |
| |
|
| | bool operator>=( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a >= b.as_long_long(); |
| | } |
| |
|
| | |
| | bool operator<( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() < b; |
| | } |
| |
|
| | bool operator<( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a < b.as_long_long(); |
| | } |
| |
|
| | |
| | bool operator<=( const Long &a, PY_LONG_LONG b ) |
| | { |
| | return a.as_long_long() <= b; |
| | } |
| |
|
| | bool operator<=( PY_LONG_LONG a, const Long &b ) |
| | { |
| | return a <= b.as_long_long(); |
| | } |
| | #endif |
| | #endif |
| |
|
| | |
| | |
| | bool operator!=( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() != b.as_double(); |
| | } |
| |
|
| | bool operator!=( const Float &a, double b ) |
| | { |
| | return a.as_double() != b; |
| | } |
| |
|
| | bool operator!=( double a, const Float &b ) |
| | { |
| | return a != b.as_double(); |
| | } |
| |
|
| | |
| | bool operator==( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() == b.as_double(); |
| | } |
| |
|
| | bool operator==( const Float &a, double b ) |
| | { |
| | return a.as_double() == b; |
| | } |
| |
|
| | bool operator==( double a, const Float &b ) |
| | { |
| | return a == b.as_double(); |
| | } |
| |
|
| | |
| | bool operator>( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() > b.as_double(); |
| | } |
| |
|
| | bool operator>( const Float &a, double b ) |
| | { |
| | return a.as_double() > b; |
| | } |
| |
|
| | bool operator>( double a, const Float &b ) |
| | { |
| | return a > b.as_double(); |
| | } |
| |
|
| | |
| | bool operator>=( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() >= b.as_double(); |
| | } |
| |
|
| | bool operator>=( const Float &a, double b ) |
| | { |
| | return a.as_double() >= b; |
| | } |
| |
|
| | bool operator>=( double a, const Float &b ) |
| | { |
| | return a >= b.as_double(); |
| | } |
| |
|
| | |
| | bool operator<( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() < b.as_double(); |
| | } |
| |
|
| | bool operator<( const Float &a, double b ) |
| | { |
| | return a.as_double() < b; |
| | } |
| |
|
| | bool operator<( double a, const Float &b ) |
| | { |
| | return a < b.as_double(); |
| | } |
| |
|
| | |
| | bool operator<=( const Float &a, const Float &b ) |
| | { |
| | return a.as_double() <= b.as_double(); |
| | } |
| |
|
| | bool operator<=( double a, const Float &b ) |
| | { |
| | return a <= b.as_double(); |
| | } |
| |
|
| | bool operator<=( const Float &a, double b ) |
| | { |
| | return a.as_double() <= b; |
| | } |
| |
|
| | } |
| |
|