diff --git a/CXX/Python2/Exception.hxx b/CXX/Python2/Exception.hxx index 1ef087cac9fe..3acc0ae4182a 100644 --- a/CXX/Python2/Exception.hxx +++ b/CXX/Python2/Exception.hxx @@ -163,6 +163,16 @@ namespace Py } }; + class NotImplementedError: public StandardError + { + public: + NotImplementedError (const std::string& reason) + : StandardError() + { + PyErr_SetString (Py::_Exc_NotImplementedError(), reason.c_str()); + } + }; + class SystemError: public StandardError { public: diff --git a/CXX/Python2/ExtensionModule.hxx b/CXX/Python2/ExtensionModule.hxx index 95413801f020..dde3ec6f854b 100644 --- a/CXX/Python2/ExtensionModule.hxx +++ b/CXX/Python2/ExtensionModule.hxx @@ -136,11 +136,19 @@ namespace Py { MethodDefExt *method_def = (*i).second; - static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc ); + #if PY_VERSION_HEX < 0x02070000 + static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc ); + #else + static PyObject *self = PyCapsule_New( this, NULL, NULL ); + #endif Tuple args( 2 ); args[0] = Object( self ); - args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) ); + #if PY_VERSION_HEX < 0x02070000 + args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) ); + #else + args[1] = Object( PyCapsule_New( method_def, NULL, NULL ) ); + #endif PyObject *func = PyCFunction_New ( diff --git a/CXX/Python2/ExtensionOldType.hxx b/CXX/Python2/ExtensionOldType.hxx index 8aa2a3e3cfe7..9702b00e7455 100644 --- a/CXX/Python2/ExtensionOldType.hxx +++ b/CXX/Python2/ExtensionOldType.hxx @@ -74,6 +74,11 @@ namespace Py return this; } + Object self() + { + return asObject( this ); + } + protected: explicit PythonExtension() : PythonExtensionBase() @@ -173,8 +178,11 @@ namespace Py Tuple self( 2 ); self[0] = Object( this ); - self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ), true ); - + #if PY_VERSION_HEX < 0x02070000 + self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ), true ); + #else + self[1] = Object( PyCapsule_New( method_def, NULL, NULL ), true ); + #endif PyObject *func = PyCFunction_New( &method_def->ext_meth_def, self.ptr() ); return Object(func, true); @@ -230,8 +238,12 @@ namespace Py PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); T *self = static_cast( self_in_cobject ); - MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + #if PY_VERSION_HEX < 0x02070000 + void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ); + #else + void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ); + #endif + MethodDefExt *meth_def = reinterpret_cast *>( capsule ); Object result; // Adding try & catch in case of STL debug-mode exceptions. @@ -266,8 +278,12 @@ namespace Py PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); T *self = static_cast( self_in_cobject ); - MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + #if PY_VERSION_HEX < 0x02070000 + void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ); + #else + void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ); + #endif + MethodDefExt *meth_def = reinterpret_cast *>( capsule ); Tuple args( _args ); Object result; @@ -303,8 +319,12 @@ namespace Py PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); T *self = static_cast( self_in_cobject ); - MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + #if PY_VERSION_HEX < 0x02070000 + void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ); + #else + void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ); + #endif + MethodDefExt *meth_def = reinterpret_cast *>( capsule ); Tuple args( _args ); diff --git a/CXX/Python2/ExtensionType.hxx b/CXX/Python2/ExtensionType.hxx index 2b41dbbf9701..4128960eea2a 100644 --- a/CXX/Python2/ExtensionType.hxx +++ b/CXX/Python2/ExtensionType.hxx @@ -45,44 +45,67 @@ #define PYCXX_NOARGS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_NOARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *, PyObject * ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Object r( (self->NAME)() ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Object r( (self->NAME)() ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } #define PYCXX_VARARGS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_VARARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject * ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Tuple a( _a ); \ - Py::Object r( (self->NAME)( a ) ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Tuple a( _a ); \ + Py::Object r( (self->NAME)( a ) ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } #define PYCXX_KEYWORDS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_KEYWORDS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject *_k ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Tuple a( _a ); \ - Py::Dict k; \ - if( _k != NULL ) \ - k = _k; \ - Py::Object r( (self->NAME)( a, k ) ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Tuple a( _a ); \ + Py::Dict k; \ + if( _k != NULL ) \ + k = _k; \ + Py::Object r( (self->NAME)( a, k ) ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } // need to support METH_STATIC and METH_CLASS -#define PYCXX_ADD_NOARGS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs ) -#define PYCXX_ADD_VARARGS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs ) -#define PYCXX_ADD_KEYWORDS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs ) +#define PYCXX_ADD_NOARGS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs ) +#define PYCXX_ADD_VARARGS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs ) +#define PYCXX_ADD_KEYWORDS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs ) namespace Py { + extern PythonExtensionBase *getPythonExtensionBase( PyObject *self ); + struct PythonClassInstance { PyObject_HEAD @@ -131,7 +154,7 @@ namespace Py { new_mt[ i ] = old_mt[ i ]; } - delete old_mt; + delete[] old_mt; m_methods_table = new_mt; } @@ -167,10 +190,8 @@ namespace Py protected: explicit PythonClass( PythonClassInstance *self, Tuple &args, Dict &kwds ) : PythonExtensionBase() - , m_self( self ) + , m_class_instance( self ) { - // we are a class - behaviors().supportClass(); } virtual ~PythonClass() @@ -203,6 +224,12 @@ namespace Py p->set_tp_new( extension_object_new ); p->set_tp_init( extension_object_init ); p->set_tp_dealloc( extension_object_deallocator ); + // we are a class + p->supportClass(); + + // always support get and set attr + p->supportGetattro(); + p->supportSetattro(); } return *p; @@ -238,7 +265,7 @@ namespace Py PythonClassInstance *self = reinterpret_cast( _self ); #ifdef PYCXX_DEBUG std::cout << "extension_object_init( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl; - std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl; + std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl; #endif if( self->m_pycxx_object == NULL ) @@ -268,9 +295,10 @@ namespace Py PythonClassInstance *self = reinterpret_cast< PythonClassInstance * >( _self ); #ifdef PYCXX_DEBUG std::cout << "extension_object_deallocator( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl; - std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl; + std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl; #endif delete self->m_pycxx_object; + _self->ob_type->tp_free( _self ); } public: @@ -295,14 +323,19 @@ namespace Py return check( ob.ptr() ); } - PyObject *selfPtr() + virtual PyObject *selfPtr() + { + return reinterpret_cast( m_class_instance ); + } + + virtual Object self() { - return reinterpret_cast( m_self ); + return Object( reinterpret_cast( m_class_instance ) ); } protected: private: - PythonClassInstance *m_self; + PythonClassInstance *m_class_instance; private: // @@ -361,7 +394,7 @@ namespace Py // T *getCxxObject( void ) { - return static_cast( ptr() ); + return dynamic_cast< T * >( getPythonExtensionBase( ptr() ) ); } }; } // Namespace Py diff --git a/CXX/Python2/ExtensionTypeBase.hxx b/CXX/Python2/ExtensionTypeBase.hxx index eaebe650b629..ad11029e71dc 100644 --- a/CXX/Python2/ExtensionTypeBase.hxx +++ b/CXX/Python2/ExtensionTypeBase.hxx @@ -131,8 +131,40 @@ namespace Py virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** ); virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* ); + public: + // helper functions to call function fn_name with 0 to 9 args + Object callOnSelf( const std::string &fn_name ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4, const Object &arg5 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4, const Object &arg5, const Object &arg6 ); + Object 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 ); + Object 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 ); + Object 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 ); + public: virtual PyObject *selfPtr() = 0; + virtual Object self() = 0; private: void missing_method( void ); diff --git a/CXX/Python2/IndirectPythonInterface.cxx b/CXX/Python2/IndirectPythonInterface.cxx index d36d1b52612d..203f3f9170ff 100644 --- a/CXX/Python2/IndirectPythonInterface.cxx +++ b/CXX/Python2/IndirectPythonInterface.cxx @@ -42,7 +42,9 @@ namespace Py bool _Buffer_Check( PyObject *op ) { return (op)->ob_type == _Buffer_Type(); } bool _CFunction_Check( PyObject *op ) { return (op)->ob_type == _CFunction_Type(); } bool _Class_Check( PyObject *op ) { return (op)->ob_type == _Class_Type(); } +#if PY_VERSION_HEX < 0x02070000 bool _CObject_Check( PyObject *op ) { return (op)->ob_type == _CObject_Type(); } +#endif bool _Complex_Check( PyObject *op ) { return (op)->ob_type == _Complex_Type(); } bool _Dict_Check( PyObject *op ) { return (op)->ob_type == _Dict_Type(); } bool _File_Check( PyObject *op ) { return (op)->ob_type == _File_Type(); } @@ -123,7 +125,9 @@ static PyObject *ptr__PyTrue = NULL; static PyTypeObject *ptr__Buffer_Type = NULL; static PyTypeObject *ptr__CFunction_Type = NULL; static PyTypeObject *ptr__Class_Type = NULL; +#if PY_VERSION_HEX < 0x02070000 static PyTypeObject *ptr__CObject_Type = NULL; +#endif static PyTypeObject *ptr__Complex_Type = NULL; static PyTypeObject *ptr__Dict_Type = NULL; static PyTypeObject *ptr__File_Type = NULL; @@ -310,7 +314,9 @@ bool InitialisePythonIndirectInterface() ptr__Buffer_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyBuffer_Type" ); ptr__CFunction_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCFunction_Type" ); ptr__Class_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyClass_Type" ); +#if PY_VERSION_HEX < 0x02070000 ptr__CObject_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCObject_Type" ); +#endif ptr__Complex_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyComplex_Type" ); ptr__Dict_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyDict_Type" ); ptr__File_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyFile_Type" ); @@ -398,7 +404,9 @@ PyObject * _True() { return ptr__PyTrue; } PyTypeObject * _Buffer_Type() { return ptr__Buffer_Type; } PyTypeObject * _CFunction_Type(){ return ptr__CFunction_Type; } PyTypeObject * _Class_Type() { return ptr__Class_Type; } +#if PY_VERSION_HEX < 0x02070000 PyTypeObject * _CObject_Type() { return ptr__CObject_Type; } +#endif PyTypeObject * _Complex_Type() { return ptr__Complex_Type; } PyTypeObject * _Dict_Type() { return ptr__Dict_Type; } PyTypeObject * _File_Type() { return ptr__File_Type; } @@ -542,7 +550,9 @@ PyObject * _True() { return Py_True; } PyTypeObject * _Buffer_Type() { return &PyBuffer_Type; } PyTypeObject * _CFunction_Type() { return &PyCFunction_Type; } PyTypeObject * _Class_Type() { return &PyClass_Type; } +#if PY_VERSION_HEX < 0x02070000 PyTypeObject * _CObject_Type() { return &PyCObject_Type; } +#endif PyTypeObject * _Complex_Type() { return &PyComplex_Type; } PyTypeObject * _Dict_Type() { return &PyDict_Type; } PyTypeObject * _File_Type() { return &PyFile_Type; } diff --git a/CXX/Python2/IndirectPythonInterface.hxx b/CXX/Python2/IndirectPythonInterface.hxx index a29a394c6c6a..33d4b83f34fc 100644 --- a/CXX/Python2/IndirectPythonInterface.hxx +++ b/CXX/Python2/IndirectPythonInterface.hxx @@ -113,8 +113,10 @@ bool _Instance_Check( PyObject *op ); PyTypeObject * _Method_Type(); bool _Method_Check( PyObject *op ); +#if PY_VERSION_HEX < 0x02070000 PyTypeObject * _CObject_Type(); bool _CObject_Check( PyObject *op ); +#endif PyTypeObject * _Complex_Type(); bool _Complex_Check( PyObject *op ); diff --git a/CXX/Python2/Objects.hxx b/CXX/Python2/Objects.hxx index ce1fa98f249a..286293ead71a 100644 --- a/CXX/Python2/Objects.hxx +++ b/CXX/Python2/Objects.hxx @@ -61,6 +61,8 @@ namespace Py class String; class List; template class MapBase; + class Tuple; + class Dict; // new_reference_to also overloaded below on Object inline PyObject* new_reference_to(PyObject* p) @@ -268,6 +270,10 @@ namespace Py return Object (PyObject_GetAttrString (p, const_cast(s.c_str())), true); } + Object callMemberFunction( const std::string &function_name ) const; + Object callMemberFunction( const std::string &function_name, const Tuple &args ) const; + Object callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const; + Object getItem (const Object& key) const { return Object (PyObject_GetItem(p, *key), true); @@ -1718,7 +1724,6 @@ namespace Py template bool operator<=(const EXPLICIT_TYPENAME SeqBase::const_iterator& left, const EXPLICIT_TYPENAME SeqBase::const_iterator& right); template bool operator>=(const EXPLICIT_TYPENAME SeqBase::const_iterator& left, const EXPLICIT_TYPENAME SeqBase::const_iterator& right); - extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right); extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right); extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right); @@ -1848,62 +1853,61 @@ namespace Py } String() - : SeqBase( PyString_FromStringAndSize( "", 0 ), true ) + : SeqBase( PyString_FromStringAndSize( "", 0 ), true ) { validate(); } String( const std::string& v ) - : SeqBase( PyString_FromStringAndSize( const_cast(v.data()), + : SeqBase( PyString_FromStringAndSize( const_cast(v.data()), static_cast( v.length() ) ), true ) { validate(); } - String( const char *s, const char *encoding, const char *error="strict" ) - : SeqBase( PyUnicode_Decode( s, strlen( s ), encoding, error ), true ) + String( const Py_UNICODE *s, int length ) + : SeqBase( PyUnicode_FromUnicode( s, length ), true ) { validate(); } - String( const char *s, int len, const char *encoding, const char *error="strict" ) - : SeqBase( PyUnicode_Decode( s, len, encoding, error ), true ) + String( const char *s, const char *encoding, const char *error="strict" ) + : SeqBase( PyUnicode_Decode( s, strlen( s ), encoding, error ), true ) { validate(); } - String( const std::string &s, const char *encoding, const char *error="strict" ) - : SeqBase( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true ) + String( const char *s, int len, const char *encoding, const char *error="strict" ) + : SeqBase( PyUnicode_Decode( s, len, encoding, error ), true ) { validate(); } - String( const std::string& v, std::string::size_type vsize ) - : SeqBase(PyString_FromStringAndSize( const_cast(v.data()), - static_cast( vsize ) ), true) + String( const std::string &s, const char *encoding, const char *error="strict" ) + : SeqBase( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true ) { validate(); } String( const char *v, int vsize ) - : SeqBase(PyString_FromStringAndSize( const_cast(v), vsize ), true ) + : SeqBase(PyString_FromStringAndSize( const_cast(v), vsize ), true ) { validate(); } - String( const char* v ) - : SeqBase( PyString_FromString( v ), true ) + String( const char *v ) + : SeqBase( PyString_FromString( v ), true ) { validate(); } // Assignment acquires new ownership of pointer - String& operator= ( const Object& rhs ) + String &operator=( const Object &rhs ) { return *this = *rhs; } - String& operator= (PyObject* rhsp) + String& operator= (PyObject *rhsp) { if( ptr() == rhsp ) return *this; @@ -1917,25 +1921,24 @@ namespace Py } // Assignment from C string - String& operator= (const std::string& v) + String& operator=( const std::string &v ) { set( PyString_FromStringAndSize( const_cast( v.data() ), static_cast( v.length() ) ), true ); return *this; } - String& operator= (const unicodestring& v) + String& operator=( const unicodestring &v ) { set( PyUnicode_FromUnicode( const_cast( v.data() ), static_cast( v.length() ) ), true ); return *this; } - // Encode Bytes encode( const char *encoding, const char *error="strict" ) const; // Queries - virtual size_type size () const + virtual size_type size() const { if( isUnicode() ) { @@ -1947,7 +1950,7 @@ namespace Py } } - operator std::string () const + operator std::string() const { return as_std_string( "utf-8" ); } @@ -1966,6 +1969,18 @@ namespace Py throw TypeError("can only return unicodestring from Unicode object"); } } + + const Py_UNICODE *unicode_data() const + { + if( isUnicode() ) + { + return PyUnicode_AS_UNICODE( ptr() ); + } + else + { + throw TypeError("can only return unicode_data from Unicode object"); + } + } }; class Bytes: public SeqBase { @@ -1997,12 +2012,6 @@ namespace Py validate(); } - Bytes( const std::string& v, std::string::size_type vsize ) - : SeqBase(PyString_FromStringAndSize( const_cast(v.data()), static_cast( vsize ) ), true) - { - validate(); - } - Bytes( const char *v, int vsize ) : SeqBase(PyString_FromStringAndSize( const_cast(v), vsize ), true ) { @@ -2050,7 +2059,7 @@ namespace Py String decode( const char *encoding, const char *error="strict" ) { - return Object( PyString_AsDecodedObject( ptr(), encoding, error ) ); + return Object( PyString_AsDecodedObject( ptr(), encoding, error ), true ); } // Queries @@ -2148,13 +2157,6 @@ namespace Py validate(); } - String( const std::string& v, std::string::size_type vsize ) - : SeqBase(PyString_FromStringAndSize( const_cast(v.data()), - static_cast( vsize ) ), true) - { - validate(); - } - String( const char *v, int vsize ) : SeqBase(PyString_FromStringAndSize( const_cast(v), vsize ), true ) { @@ -2206,17 +2208,17 @@ namespace Py { if( isUnicode() ) { - return String( PyUnicode_AsEncodedString( ptr(), encoding, error ) ); + return String( PyUnicode_AsEncodedString( ptr(), encoding, error ), true ); } else { - return String( PyString_AsEncodedObject( ptr(), encoding, error ) ); + return String( PyString_AsEncodedObject( ptr(), encoding, error ), true ); } } String decode( const char *encoding, const char *error="strict" ) { - return Object( PyString_AsDecodedObject( ptr(), encoding, error ) ); + return Object( PyString_AsDecodedObject( ptr(), encoding, error ), true ); } // Queries @@ -2346,6 +2348,118 @@ namespace Py }; + class TupleN: public Tuple + { + public: + TupleN() + : Tuple( 0 ) + { + } + + TupleN( const Object &obj1 ) + : Tuple( 1 ) + { + setItem( 0, obj1 ); + } + + TupleN( const Object &obj1, const Object &obj2 ) + : Tuple( 2 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3 ) + : Tuple( 3 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4 ) + : Tuple( 4 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5 ) + : Tuple( 5 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6 ) + : Tuple( 6 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7 ) + : Tuple( 7 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7, const Object &obj8 ) + : Tuple( 8 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + setItem( 7, obj8 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7, const Object &obj8, const Object &obj9 ) + : Tuple( 9 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + setItem( 7, obj8 ); + setItem( 8, obj9 ); + } + + virtual ~TupleN() + { } + }; + + // ================================================== // class List @@ -3154,6 +3268,26 @@ namespace Py } }; + // Call function helper + inline Object Object::callMemberFunction( const std::string &function_name ) const + { + Callable target( getAttr( function_name ) ); + Tuple args( 0 ); + return target.apply( args ); + } + + inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args ) const + { + Callable target( getAttr( function_name ) ); + return target.apply( args ); + } + + inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const + { + Callable target( getAttr( function_name ) ); + return target.apply( args, kw ); + } + // Numeric interface inline Object operator+ (const Object& a) { diff --git a/CXX/Python2/cxx_extensions.cxx b/CXX/Python2/cxx_extensions.cxx index 2c39dfd064de..6ae62c7cfb05 100644 --- a/CXX/Python2/cxx_extensions.cxx +++ b/CXX/Python2/cxx_extensions.cxx @@ -1320,6 +1320,84 @@ PythonExtensionBase::~PythonExtensionBase() assert( ob_refcnt == 0 ); } +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name ) +{ + Py::TupleN args; + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1 ) +{ + Py::TupleN args( arg1 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2 ) +{ + Py::TupleN args( arg1, arg2 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3 ) +{ + Py::TupleN args( arg1, arg2, arg3 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7, const Py::Object &arg8 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7, const Py::Object &arg8, const Py::Object &arg9 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); + return self().callMemberFunction( fn_name, args ); +} + void PythonExtensionBase::reinit( Tuple &args, Dict &kwds ) { throw RuntimeError( "Must not call __init__ twice on this class" ); @@ -1353,16 +1431,14 @@ int PythonExtensionBase::setattr( const char *, const Py::Object &) return -1; } -Py::Object PythonExtensionBase::getattro( const Py::String &) +Py::Object PythonExtensionBase::getattro( const Py::String &name ) { - missing_method( getattro ); - return Py::None(); + return genericGetAttro( name ); } -int PythonExtensionBase::setattro( const Py::String &, const Py::Object &) +int PythonExtensionBase::setattro( const Py::String &name, const Py::Object &value ) { - missing_method( setattro ); - return -1; + return genericSetAttro( name, value ); } int PythonExtensionBase::compare( const Py::Object &) @@ -1643,7 +1719,11 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple Tuple self_and_name_tuple( _self_and_name_tuple ); PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); - void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + #if PY_VERSION_HEX < 0x02070000 + void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + #else + void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); + #endif if( self_as_void == NULL ) return NULL; @@ -1659,7 +1739,11 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_keyword ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #if PY_VERSION_HEX < 0x02070000 + PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #else + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), + #endif args, keywords ) @@ -1675,7 +1759,11 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_keyword ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #if PY_VERSION_HEX < 0x02070000 + PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #else + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), + #endif args, keywords ) @@ -1697,7 +1785,11 @@ extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple Tuple self_and_name_tuple( _self_and_name_tuple ); PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); - void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + #if PY_VERSION_HEX < 0x02070000 + void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + #else + void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); + #endif if( self_as_void == NULL ) return NULL; @@ -1708,7 +1800,11 @@ extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_varargs ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #if PY_VERSION_HEX < 0x02070000 + PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + #else + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), + #endif args ) ); diff --git a/CXX/Python3/Exception.hxx b/CXX/Python3/Exception.hxx index 07908d1ef4b2..0bd052d5cc7d 100644 --- a/CXX/Python3/Exception.hxx +++ b/CXX/Python3/Exception.hxx @@ -164,6 +164,16 @@ namespace Py } }; + class NotImplementedError: public StandardError + { + public: + NotImplementedError (const std::string& reason) + : StandardError() + { + PyErr_SetString (Py::_Exc_NotImplementedError(), reason.c_str()); + } + }; + class SystemError: public StandardError { public: diff --git a/CXX/Python3/ExtensionModule.hxx b/CXX/Python3/ExtensionModule.hxx index b41decc821c5..a892a6f8cde5 100644 --- a/CXX/Python3/ExtensionModule.hxx +++ b/CXX/Python3/ExtensionModule.hxx @@ -82,8 +82,6 @@ namespace Py extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args ); extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords ); - extern "C" void do_not_dealloc( void * ); - template class ExtensionModule : public ExtensionModuleBase { @@ -134,11 +132,11 @@ namespace Py { MethodDefExt *method_def = (*i).second; - static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc ); + static PyObject *self = PyCapsule_New( this, NULL, NULL ); Tuple args( 2 ); args[0] = Object( self ); - args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) ); + args[1] = Object( PyCapsule_New( method_def, NULL, NULL ) ); PyObject *func = PyCFunction_New ( diff --git a/CXX/Python3/ExtensionOldType.hxx b/CXX/Python3/ExtensionOldType.hxx index 56e6af2ecbfd..355dcfb220bb 100644 --- a/CXX/Python3/ExtensionOldType.hxx +++ b/CXX/Python3/ExtensionOldType.hxx @@ -74,6 +74,11 @@ namespace Py return this; } + Object self() + { + return asObject( this ); + } + protected: explicit PythonExtension() : PythonExtensionBase() @@ -173,7 +178,7 @@ namespace Py Tuple self( 2 ); self[0] = Object( this ); - self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) ); + self[1] = Object( PyCapsule_New( method_def, NULL, NULL ), true ); PyObject *func = PyCFunction_New( &method_def->ext_meth_def, self.ptr() ); @@ -232,7 +237,7 @@ namespace Py T *self = static_cast( self_in_cobject ); MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ); Object result; @@ -268,7 +273,7 @@ namespace Py PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); T *self = static_cast( self_in_cobject ); MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ); Tuple args( _args ); @@ -305,7 +310,7 @@ namespace Py PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); T *self = static_cast( self_in_cobject ); MethodDefExt *meth_def = reinterpret_cast *>( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ); + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ); Tuple args( _args ); diff --git a/CXX/Python3/ExtensionType.hxx b/CXX/Python3/ExtensionType.hxx index c1b8721e4357..df680dbdfe15 100644 --- a/CXX/Python3/ExtensionType.hxx +++ b/CXX/Python3/ExtensionType.hxx @@ -45,44 +45,66 @@ #define PYCXX_NOARGS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_NOARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *, PyObject * ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Object r( (self->NAME)() ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Object r( (self->NAME)() ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } #define PYCXX_VARARGS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_VARARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject * ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Tuple a( _a ); \ - Py::Object r( (self->NAME)( a ) ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Tuple a( _a ); \ + Py::Object r( (self->NAME)( a ) ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } #define PYCXX_KEYWORDS_METHOD_DECL( CLS, NAME ) \ static PyObject *PYCXX_KEYWORDS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject *_k ) \ { \ - Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ - CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ - Py::Tuple a( _a ); \ - Py::Dict k; \ - if( _k != NULL ) \ - k = _k; \ - Py::Object r( (self->NAME)( a, k ) ); \ - return Py::new_reference_to( r.ptr() ); \ + try \ + { \ + Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \ + CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \ + Py::Tuple a( _a ); \ + Py::Dict k; \ + if( _k != NULL ) \ + k = _k; \ + Py::Object r( (self->NAME)( a, k ) ); \ + return Py::new_reference_to( r.ptr() ); \ + } \ + catch( Py::Exception & ) \ + { \ + return 0; \ + } \ } // need to support METH_STATIC and METH_CLASS -#define PYCXX_ADD_NOARGS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs ) -#define PYCXX_ADD_VARARGS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs ) -#define PYCXX_ADD_KEYWORDS_METHOD( NAME, docs ) \ - add_method( #NAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs ) +#define PYCXX_ADD_NOARGS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs ) +#define PYCXX_ADD_VARARGS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs ) +#define PYCXX_ADD_KEYWORDS_METHOD( PYNAME, NAME, docs ) \ + add_method( #PYNAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs ) namespace Py { + extern PythonExtensionBase *getPythonExtensionBase( PyObject *self ); struct PythonClassInstance { PyObject_HEAD @@ -131,7 +153,7 @@ namespace Py { new_mt[ i ] = old_mt[ i ]; } - delete old_mt; + delete[] old_mt; m_methods_table = new_mt; } @@ -167,10 +189,8 @@ namespace Py protected: explicit PythonClass( PythonClassInstance *self, Tuple &args, Dict &kwds ) : PythonExtensionBase() - , m_self( self ) + , m_class_instance( self ) { - // we are a class - behaviors().supportClass(); } virtual ~PythonClass() @@ -203,6 +223,13 @@ namespace Py p->set_tp_new( extension_object_new ); p->set_tp_init( extension_object_init ); p->set_tp_dealloc( extension_object_deallocator ); + + // we are a class + p->supportClass(); + + // always support get and set attr + p->supportGetattro(); + p->supportSetattro(); } return *p; @@ -238,7 +265,7 @@ namespace Py PythonClassInstance *self = reinterpret_cast( _self ); #ifdef PYCXX_DEBUG std::cout << "extension_object_init( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl; - std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl; + std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl; #endif if( self->m_pycxx_object == NULL ) @@ -268,9 +295,10 @@ namespace Py PythonClassInstance *self = reinterpret_cast< PythonClassInstance * >( _self ); #ifdef PYCXX_DEBUG std::cout << "extension_object_deallocator( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl; - std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl; + std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl; #endif delete self->m_pycxx_object; + _self->ob_type->tp_free( _self ); } public: @@ -295,14 +323,19 @@ namespace Py return check( ob.ptr() ); } - PyObject *selfPtr() + virtual PyObject *selfPtr() + { + return reinterpret_cast( m_class_instance ); + } + + virtual Object self() { - return reinterpret_cast( m_self ); + return Object( reinterpret_cast( m_class_instance ) ); } protected: private: - PythonClassInstance *m_self; + PythonClassInstance *m_class_instance; private: // @@ -361,7 +394,7 @@ namespace Py // T *getCxxObject( void ) { - return static_cast( ptr() ); + return dynamic_cast< T * >( getPythonExtensionBase( ptr() ) ); } }; } // Namespace Py diff --git a/CXX/Python3/ExtensionTypeBase.hxx b/CXX/Python3/ExtensionTypeBase.hxx index 5b83b033a7ff..3936ccc28801 100644 --- a/CXX/Python3/ExtensionTypeBase.hxx +++ b/CXX/Python3/ExtensionTypeBase.hxx @@ -121,10 +121,43 @@ namespace Py virtual Object number_power( const Object &, const Object & ); // Buffer - // QQQ need to add py3 interface + virtual int buffer_get( Py_buffer *, int flags ); + virtual int buffer_release( Py_buffer *buf ); + + public: + // helper functions to call function fn_name with 0 to 9 args + Object callOnSelf( const std::string &fn_name ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4, const Object &arg5 ); + Object callOnSelf( const std::string &fn_name, + const Object &arg1, const Object &arg2, const Object &arg3, + const Object &arg4, const Object &arg5, const Object &arg6 ); + Object 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 ); + Object 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 ); + Object 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 ); public: virtual PyObject *selfPtr() = 0; + virtual Object self() = 0; private: void missing_method( void ); diff --git a/CXX/Python3/IndirectPythonInterface.cxx b/CXX/Python3/IndirectPythonInterface.cxx index 28784fd532c0..2b7ff41b75da 100644 --- a/CXX/Python3/IndirectPythonInterface.cxx +++ b/CXX/Python3/IndirectPythonInterface.cxx @@ -40,7 +40,6 @@ namespace Py { bool _CFunction_Check( PyObject *op ) { return op->ob_type == _CFunction_Type(); } -bool _CObject_Check( PyObject *op ) { return op->ob_type == _CObject_Type(); } bool _Complex_Check( PyObject *op ) { return op->ob_type == _Complex_Type(); } bool _Dict_Check( PyObject *op ) { return op->ob_type == _Dict_Type(); } bool _Float_Check( PyObject *op ) { return op->ob_type == _Float_Type(); } @@ -80,7 +79,6 @@ static PyObject *ptr__Exc_KeyboardInterrupt = NULL; static PyObject *ptr__Exc_KeyError = NULL; static PyObject *ptr__Exc_LookupError = NULL; static PyObject *ptr__Exc_MemoryError = NULL; -static PyObject *ptr__Exc_MemoryErrorInst = NULL; static PyObject *ptr__Exc_NameError = NULL; static PyObject *ptr__Exc_NotImplementedError = NULL; static PyObject *ptr__Exc_OSError = NULL; @@ -106,7 +104,6 @@ static PyObject *ptr__PyNone = NULL; static PyObject *ptr__PyFalse = NULL; static PyObject *ptr__PyTrue = NULL; static PyTypeObject *ptr__CFunction_Type = NULL; -static PyTypeObject *ptr__CObject_Type = NULL; static PyTypeObject *ptr__Complex_Type = NULL; static PyTypeObject *ptr__Dict_Type = NULL; static PyTypeObject *ptr__Float_Type = NULL; @@ -245,7 +242,6 @@ bool InitialisePythonIndirectInterface() ptr__Exc_KeyError = GetPyObjectPointer_As_PyObjectPointer( "PyExc_KeyError" ); ptr__Exc_LookupError = GetPyObjectPointer_As_PyObjectPointer( "PyExc_LookupError" ); ptr__Exc_MemoryError = GetPyObjectPointer_As_PyObjectPointer( "PyExc_MemoryError" ); - ptr__Exc_MemoryErrorInst = GetPyObjectPointer_As_PyObjectPointer( "PyExc_MemoryErrorInst" ); ptr__Exc_NameError = GetPyObjectPointer_As_PyObjectPointer( "PyExc_NameError" ); ptr__Exc_NotImplementedError= GetPyObjectPointer_As_PyObjectPointer( "PyExc_NotImplementedError" ); ptr__Exc_OSError = GetPyObjectPointer_As_PyObjectPointer( "PyExc_OSError" ); @@ -271,7 +267,6 @@ bool InitialisePythonIndirectInterface() ptr__PyTrue = GetPyObject_As_PyObjectPointer( "_Py_TrueStruct" ); ptr__CFunction_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCFunction_Type" ); - ptr__CObject_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCObject_Type" ); ptr__Complex_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyComplex_Type" ); ptr__Dict_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyDict_Type" ); ptr__Float_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyFloat_Type" ); @@ -318,7 +313,6 @@ PyObject *_Exc_KeyboardInterrupt() { return ptr__Exc_KeyboardInterrupt; } PyObject *_Exc_KeyError() { return ptr__Exc_KeyError; } PyObject *_Exc_LookupError() { return ptr__Exc_LookupError; } PyObject *_Exc_MemoryError() { return ptr__Exc_MemoryError; } -PyObject *_Exc_MemoryErrorInst() { return ptr__Exc_MemoryErrorInst; } PyObject *_Exc_NameError() { return ptr__Exc_NameError; } PyObject *_Exc_NotImplementedError() { return ptr__Exc_NotImplementedError; } PyObject *_Exc_OSError() { return ptr__Exc_OSError; } @@ -348,7 +342,6 @@ PyObject *_False() { return ptr__PyFalse; } PyObject *_True() { return ptr__PyTrue; } PyTypeObject *_CFunction_Type() { return ptr__CFunction_Type; } -PyTypeObject *_CObject_Type() { return ptr__CObject_Type; } PyTypeObject *_Complex_Type() { return ptr__Complex_Type; } PyTypeObject *_Dict_Type() { return ptr__Dict_Type; } PyTypeObject *_Float_Type() { return ptr__Float_Type; } @@ -449,7 +442,6 @@ PyObject *_Exc_KeyboardInterrupt() { return ::PyExc_KeyboardInterrupt; } PyObject *_Exc_KeyError() { return ::PyExc_KeyError; } PyObject *_Exc_LookupError() { return ::PyExc_LookupError; } PyObject *_Exc_MemoryError() { return ::PyExc_MemoryError; } -PyObject *_Exc_MemoryErrorInst() { return ::PyExc_MemoryErrorInst; } PyObject *_Exc_NameError() { return ::PyExc_NameError; } PyObject *_Exc_NotImplementedError() { return ::PyExc_NotImplementedError; } PyObject *_Exc_OSError() { return ::PyExc_OSError; } @@ -482,7 +474,6 @@ PyObject *_False() { return Py_False; } PyObject *_True() { return Py_True; } PyTypeObject *_CFunction_Type() { return &PyCFunction_Type; } -PyTypeObject *_CObject_Type() { return &PyCObject_Type; } PyTypeObject *_Complex_Type() { return &PyComplex_Type; } PyTypeObject *_Dict_Type() { return &PyDict_Type; } PyTypeObject *_Float_Type() { return &PyFloat_Type; } diff --git a/CXX/Python3/IndirectPythonInterface.hxx b/CXX/Python3/IndirectPythonInterface.hxx index fed8e3c2a18f..cdae3ad35e75 100644 --- a/CXX/Python3/IndirectPythonInterface.hxx +++ b/CXX/Python3/IndirectPythonInterface.hxx @@ -78,8 +78,6 @@ PyObject * _Exc_ZeroDivisionError(); PyObject * _Exc_WindowsError(); #endif -PyObject * _Exc_MemoryErrorInst(); - PyObject * _Exc_IndentationError(); PyObject * _Exc_TabError(); PyObject * _Exc_UnboundLocalError(); @@ -111,9 +109,6 @@ bool _Instance_Check( PyObject *op ); PyTypeObject * _Method_Type(); bool _Method_Check( PyObject *op ); -PyTypeObject * _CObject_Type(); -bool _CObject_Check( PyObject *op ); - PyTypeObject * _Complex_Type(); bool _Complex_Check( PyObject *op ); diff --git a/CXX/Python3/Objects.hxx b/CXX/Python3/Objects.hxx index 4ed1a7c00ce4..96f824c8ffc4 100644 --- a/CXX/Python3/Objects.hxx +++ b/CXX/Python3/Objects.hxx @@ -63,6 +63,8 @@ namespace Py class String; class List; template class MapBase; + class Tuple; + class Dict; //===========================================================================// // class Object @@ -265,6 +267,10 @@ namespace Py return Object( PyObject_GetAttrString( p, const_cast( s.c_str() ) ), true ); } + Object callMemberFunction( const std::string &function_name ) const; + Object callMemberFunction( const std::string &function_name, const Tuple &args ) const; + Object callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const; + Object getItem( const Object &key ) const { return Object( PyObject_GetItem( p, *key ), true ); @@ -2012,7 +2018,7 @@ namespace Py } String() - : SeqBase( PyUnicode_FromString( "" ), true ) + : SeqBase( PyUnicode_FromString( "" ) ) { validate(); } @@ -2053,19 +2059,25 @@ namespace Py */ String( const std::string &s, const char *encoding, const char *errors=NULL ) - : SeqBase( PyUnicode_Decode( s.c_str(), s.size(), encoding, errors ) ) + : SeqBase( PyUnicode_Decode( s.c_str(), s.size(), encoding, errors ), true ) { validate(); } String( const char *s, const char *encoding, const char *errors=NULL ) - : SeqBase( PyUnicode_Decode( s, strlen(s), encoding, errors ) ) + : SeqBase( PyUnicode_Decode( s, strlen(s), encoding, errors ), true ) { validate(); } String( const char *s, Py_ssize_t size, const char *encoding, const char *errors=NULL ) - : SeqBase( PyUnicode_Decode( s, size, encoding, errors ) ) + : SeqBase( PyUnicode_Decode( s, size, encoding, errors ), true ) + { + validate(); + } + + String( const Py_UNICODE *s, int length ) + : SeqBase( PyUnicode_FromUnicode( s, length ), true ) { validate(); } @@ -2092,7 +2104,7 @@ namespace Py // Encode Bytes encode( const char *encoding, const char *error="strict" ) const { - return Bytes( PyUnicode_AsEncodedString( ptr(), encoding, error ) ); + return Bytes( PyUnicode_AsEncodedString( ptr(), encoding, error ), true ); } // Queries @@ -2117,6 +2129,11 @@ namespace Py Bytes b( encode( encoding, error ) ); return b.as_std_string(); } + + const Py_UNICODE *unicode_data() const + { + return PyUnicode_AS_UNICODE( ptr() ); + } }; // ================================================== @@ -2201,6 +2218,117 @@ namespace Py }; + class TupleN: public Tuple + { + public: + TupleN() + : Tuple( 0 ) + { + } + + TupleN( const Object &obj1 ) + : Tuple( 1 ) + { + setItem( 0, obj1 ); + } + + TupleN( const Object &obj1, const Object &obj2 ) + : Tuple( 2 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3 ) + : Tuple( 3 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4 ) + : Tuple( 4 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5 ) + : Tuple( 5 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6 ) + : Tuple( 6 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7 ) + : Tuple( 7 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7, const Object &obj8 ) + : Tuple( 8 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + setItem( 7, obj8 ); + } + + TupleN( const Object &obj1, const Object &obj2, const Object &obj3, + const Object &obj4, const Object &obj5, const Object &obj6, + const Object &obj7, const Object &obj8, const Object &obj9 ) + : Tuple( 9 ) + { + setItem( 0, obj1 ); + setItem( 1, obj2 ); + setItem( 2, obj3 ); + setItem( 3, obj4 ); + setItem( 4, obj5 ); + setItem( 5, obj6 ); + setItem( 6, obj7 ); + setItem( 7, obj8 ); + setItem( 8, obj9 ); + } + + virtual ~TupleN() + { } + }; + // ================================================== // class List @@ -3067,6 +3195,26 @@ namespace Py } }; + // Call function helper + inline Object Object::callMemberFunction( const std::string &function_name ) const + { + Callable target( getAttr( function_name ) ); + Tuple args( 0 ); + return target.apply( args ); + } + + inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args ) const + { + Callable target( getAttr( function_name ) ); + return target.apply( args ); + } + + inline Object Object::callMemberFunction( const std::string &function_name, const Tuple &args, const Dict &kw ) const + { + Callable target( getAttr( function_name ) ); + return target.apply( args, kw ); + } + // Numeric interface inline Object operator+( const Object &a ) { diff --git a/CXX/Python3/cxx_extensions.cxx b/CXX/Python3/cxx_extensions.cxx index c7f42bd9a927..b6e3aa083d0b 100644 --- a/CXX/Python3/cxx_extensions.cxx +++ b/CXX/Python3/cxx_extensions.cxx @@ -262,7 +262,8 @@ extern "C" static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * ); // Buffer - // QQQ + static int buffer_get_handler( PyObject *, Py_buffer *, int ); + static void buffer_release_handler( PyObject *, Py_buffer * ); } extern "C" void standard_dealloc( PyObject *p ) @@ -345,8 +346,8 @@ PythonType &PythonType::supportBufferType() buffer_table = new PyBufferProcs; memset( buffer_table, 0, sizeof( PyBufferProcs ) ); // ensure new fields are 0 table->tp_as_buffer = buffer_table; - // QQQ bf_getbuffer - // QQQ bf_releasebuffer + buffer_table->bf_getbuffer = buffer_get_handler; + buffer_table->bf_releasebuffer = buffer_release_handler; } return *this; } @@ -1099,6 +1100,25 @@ extern "C" PyObject *number_power_handler( PyObject *self, PyObject *x1, PyObjec } // Buffer +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( Py::Exception & ) + { + return -1; // indicate error + } +} + +extern "C" void buffer_release_handler( PyObject *self, Py_buffer *buf ) +{ + PythonExtensionBase *p = getPythonExtensionBase( self ); + p->buffer_release( buf ); + // NOTE: No way to indicate error to Python +} //================================================================================ // @@ -1118,6 +1138,84 @@ PythonExtensionBase::~PythonExtensionBase() assert( ob_refcnt == 0 ); } +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name ) +{ + Py::TupleN args; + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1 ) +{ + Py::TupleN args( arg1 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2 ) +{ + Py::TupleN args( arg1, arg2 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3 ) +{ + Py::TupleN args( arg1, arg2, arg3 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7, const Py::Object &arg8 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ); + return self().callMemberFunction( fn_name, args ); +} + +Py::Object PythonExtensionBase::callOnSelf( const std::string &fn_name, + const Py::Object &arg1, const Py::Object &arg2, const Py::Object &arg3, + const Py::Object &arg4, const Py::Object &arg5, const Py::Object &arg6, + const Py::Object &arg7, const Py::Object &arg8, const Py::Object &arg9 ) +{ + Py::TupleN args( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 ); + return self().callMemberFunction( fn_name, args ); +} + void PythonExtensionBase::reinit( Tuple &args, Dict &kwds ) { throw RuntimeError( "Must not call __init__ twice on this class" ); @@ -1154,16 +1252,14 @@ int PythonExtensionBase::setattr( const char *, const Py::Object & ) return -1; } -Py::Object PythonExtensionBase::getattro( const Py::String & ) +Py::Object PythonExtensionBase::getattro( const Py::String &name ) { - missing_method( getattro ); - return Py::None(); + return asObject( PyObject_GenericGetAttr( selfPtr(), name.ptr() ) ); } -int PythonExtensionBase::setattro( const Py::String &, const Py::Object & ) +int PythonExtensionBase::setattro( const Py::String &name, const Py::Object &value ) { - missing_method( setattro ); - return -1; + return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() ); } @@ -1378,7 +1474,18 @@ Py::Object PythonExtensionBase::number_power( const Py::Object &, const Py::Obje // Buffer -// QQQ +int PythonExtensionBase::buffer_get( Py_buffer *buf, int flags ) +{ + missing_method( buffer_get ); + return -1; +} + +int PythonExtensionBase::buffer_release( Py_buffer *buf ) +{ + /* This method is optional and only required if the buffer's + memory is dynamic. */ + return 0; +} //-------------------------------------------------------------------------------- // @@ -1395,13 +1502,13 @@ extern "C" PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, Tuple self_and_name_tuple( _self_and_name_tuple ); PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); - void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); if( self_as_void == NULL ) return NULL; ExtensionModuleBase *self = static_cast( self_as_void ); - Object result( self->invoke_method_noargs( PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) ) ); + Object result( self->invoke_method_noargs( PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ) ); return new_reference_to( result.ptr() ); } @@ -1418,7 +1525,7 @@ extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple Tuple self_and_name_tuple( _self_and_name_tuple ); PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); - void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); if( self_as_void == NULL ) return NULL; @@ -1428,7 +1535,7 @@ extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_varargs ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), args ) ); @@ -1448,7 +1555,7 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple Tuple self_and_name_tuple( _self_and_name_tuple ); PyObject *self_in_cobject = self_and_name_tuple[0].ptr(); - void *self_as_void = PyCObject_AsVoidPtr( self_in_cobject ); + void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL ); if( self_as_void == NULL ) return NULL; @@ -1464,7 +1571,7 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_keyword ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), args, keywords ) @@ -1480,7 +1587,7 @@ extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple ( self->invoke_method_keyword ( - PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ), + PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ), args, keywords ) diff --git a/CXX/Version.hxx b/CXX/Version.hxx index 398889c90148..ff78b1622f1d 100644 --- a/CXX/Version.hxx +++ b/CXX/Version.hxx @@ -39,8 +39,8 @@ #define __PyCXX_version_hxx__ #define PYCXX_VERSION_MAJOR 6 -#define PYCXX_VERSION_MINOR 1 -#define PYCXX_VERSION_PATCH 1 +#define PYCXX_VERSION_MINOR 2 +#define PYCXX_VERSION_PATCH 4 #define PYCXX_MAKEVERSION( major, minor, patch ) ((major<<16)|(minor<<8)|(patch)) #define PYCXX_VERSION PYCXX_MAKEVERSION( PYCXX_VERSION_MAJOR, PYCXX_VERSION_MINOR, PYCXX_VERSION_PATCH ) #endif diff --git a/CXX/WrapPython.h b/CXX/WrapPython.h index f62d5b4aca4c..118a8740f8ad 100644 --- a/CXX/WrapPython.h +++ b/CXX/WrapPython.h @@ -38,12 +38,23 @@ #ifndef __PyCXX_wrap_python_hxx__ #define __PyCXX_wrap_python_hxx__ -/* Python API mandates Python.h is included *first* */ -#include "Python.h" - // On some platforms we have to include time.h to get select defined #if !defined(__WIN32__) && !defined(WIN32) && !defined(_WIN32) && !defined(_WIN64) #include #endif +// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h +#if defined(__sun) || defined(sun) +#if defined(_XPG4) +#undef _XPG4 +#endif +#endif + +// Python.h will redefine these and generate warning in the process +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE + +// pull in python definitions +#include + #endif