diff --git a/src/CXX/IndirectPythonInterface.cxx b/src/CXX/IndirectPythonInterface.cxx index 20bd11e06806..38fdd1b5ada7 100644 --- a/src/CXX/IndirectPythonInterface.cxx +++ b/src/CXX/IndirectPythonInterface.cxx @@ -43,11 +43,15 @@ PYCXX_EXPORT bool _CFunction_Check( PyObject *op ) { return op->ob_type == _CF PYCXX_EXPORT bool _Complex_Check( PyObject *op ) { return op->ob_type == _Complex_Type(); } PYCXX_EXPORT bool _Dict_Check( PyObject *op ) { return op->ob_type == _Dict_Type(); } PYCXX_EXPORT bool _Float_Check( PyObject *op ) { return op->ob_type == _Float_Type(); } +#if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT bool _Function_Check( PyObject *op ) { return op->ob_type == _Function_Type(); } +#endif PYCXX_EXPORT bool _Boolean_Check( PyObject *op ) { return op->ob_type == _Bool_Type(); } PYCXX_EXPORT bool _List_Check( PyObject *op ) { return op->ob_type == _List_Type(); } PYCXX_EXPORT bool _Long_Check( PyObject *op ) { return op->ob_type == _Long_Type(); } +#if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT bool _Method_Check( PyObject *op ) { return op->ob_type == _Method_Type(); } +#endif PYCXX_EXPORT bool _Module_Check( PyObject *op ) { return op->ob_type == _Module_Type(); } PYCXX_EXPORT bool _Range_Check( PyObject *op ) { return op->ob_type == _Range_Type(); } PYCXX_EXPORT bool _Slice_Check( PyObject *op ) { return op->ob_type == _Slice_Type(); } @@ -72,26 +76,30 @@ PYCXX_EXPORT bool _Bytes_Check( PyObject *op ) { return op->ob_type == _By static HMODULE python_dll; -#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ +# define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ static PyObject *ptr_Exc_##eclass = NULL; -#if PY_MAJOR_VERSION == 2 -#include "CXX/Python2/cxx_standard_exceptions.hxx" -#else -#include "CXX/Python3/cxx_standard_exceptions.hxx" -#endif +# if PY_MAJOR_VERSION == 2 +# include "CXX/Python2/cxx_standard_exceptions.hxx" +# else +# include "CXX/Python3/cxx_standard_exceptions.hxx" +# endif -#undef PYCXX_STANDARD_EXCEPTION +# undef PYCXX_STANDARD_EXCEPTION static PyTypeObject *ptr__CFunction_Type = NULL; static PyTypeObject *ptr__Complex_Type = NULL; static PyTypeObject *ptr__Dict_Type = NULL; static PyTypeObject *ptr__Float_Type = NULL; +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) static PyTypeObject *ptr__Function_Type = NULL; +# endif static PyTypeObject *ptr__Bool_Type = NULL; static PyTypeObject *ptr__List_Type = NULL; static PyTypeObject *ptr__Long_Type = NULL; +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) static PyTypeObject *ptr__Method_Type = NULL; +# endif static PyTypeObject *ptr__Module_Type = NULL; static PyTypeObject *ptr__Range_Type = NULL; static PyTypeObject *ptr__Slice_Type = NULL; @@ -108,7 +116,7 @@ static PyTypeObject *ptr__CObject_Type = NULL; static PyTypeObject *ptr__Bytes_Type = NULL; # endif - +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) static int *ptr_Py_DebugFlag = NULL; static int *ptr_Py_InteractiveFlag = NULL; static int *ptr_Py_OptimizeFlag = NULL; @@ -116,6 +124,7 @@ static int *ptr_Py_NoSiteFlag = NULL; static int *ptr_Py_VerboseFlag = NULL; static char **ptr__Py_PackageContext = NULL; +# endif # ifdef Py_REF_DEBUG int *ptr_Py_RefTotal; @@ -212,23 +221,25 @@ bool InitialisePythonIndirectInterface() # ifdef Py_REF_DEBUG ptr_Py_RefTotal = GetInt_as_IntPointer( "_Py_RefTotal" ); # endif +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) ptr_Py_DebugFlag = GetInt_as_IntPointer( "Py_DebugFlag" ); ptr_Py_InteractiveFlag = GetInt_as_IntPointer( "Py_InteractiveFlag" ); ptr_Py_OptimizeFlag = GetInt_as_IntPointer( "Py_OptimizeFlag" ); ptr_Py_NoSiteFlag = GetInt_as_IntPointer( "Py_NoSiteFlag" ); ptr_Py_VerboseFlag = GetInt_as_IntPointer( "Py_VerboseFlag" ); ptr__Py_PackageContext = GetCharPointer_as_CharPointerPointer( "_Py_PackageContext" ); +# endif -#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) +# define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) ptr_Exc_#eclass = GetPyTypeObject_As_PyTypeObjectPointer( "PyExc_" #eclass ); -#if PY_MAJOR_VERSION == 2 -#include "CXX/Python2/cxx_standard_exceptions.hxx" -#else -#include "CXX/Python3/cxx_standard_exceptions.hxx" -#endif +# if PY_MAJOR_VERSION == 2 +# include "CXX/Python2/cxx_standard_exceptions.hxx" +# else +# include "CXX/Python3/cxx_standard_exceptions.hxx" +# endif -#undef PYCXX_STANDARD_EXCEPTION +# undef PYCXX_STANDARD_EXCEPTION ptr__PyNone = GetPyObject_As_PyObjectPointer( "_Py_NoneStruct" ); @@ -243,11 +254,15 @@ bool InitialisePythonIndirectInterface() ptr__Complex_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyComplex_Type" ); ptr__Dict_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyDict_Type" ); ptr__Float_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyFloat_Type" ); +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) ptr__Function_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyFunction_Type" ); +# endif ptr__Bool_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyBool_Type" ); ptr__List_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyList_Type" ); ptr__Long_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyLong_Type" ); +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) ptr__Method_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyMethod_Type" ); +# endif ptr__Module_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyModule_Type" ); ptr__Range_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyRange_Type" ); ptr__Slice_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PySlice_Type" ); @@ -328,11 +343,15 @@ PYCXX_EXPORT PyTypeObject *_CFunction_Type() { return ptr__CFunction_Typ PYCXX_EXPORT PyTypeObject *_Complex_Type() { return ptr__Complex_Type; } PYCXX_EXPORT PyTypeObject *_Dict_Type() { return ptr__Dict_Type; } PYCXX_EXPORT PyTypeObject *_Float_Type() { return ptr__Float_Type; } +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT PyTypeObject *_Function_Type() { return ptr__Function_Type; } +# endif PYCXX_EXPORT PyTypeObject *_Bool_Type() { return ptr__Bool_Type; } PYCXX_EXPORT PyTypeObject *_List_Type() { return ptr__List_Type; } PYCXX_EXPORT PyTypeObject *_Long_Type() { return ptr__Long_Type; } +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT PyTypeObject *_Method_Type() { return ptr__Method_Type; } +# endif PYCXX_EXPORT PyTypeObject *_Module_Type() { return ptr__Module_Type; } PYCXX_EXPORT PyTypeObject *_Range_Type() { return ptr__Range_Type; } PYCXX_EXPORT PyTypeObject *_Slice_Type() { return ptr__Slice_Type; } @@ -352,11 +371,13 @@ PYCXX_EXPORT PyTypeObject *_Bytes_Type() { return ptr__Bytes_Type; } // // wrap the Python Flag variables // +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT int &_Py_DebugFlag() { return *ptr_Py_DebugFlag; } PYCXX_EXPORT int &_Py_InteractiveFlag() { return *ptr_Py_InteractiveFlag; } PYCXX_EXPORT int &_Py_OptimizeFlag() { return *ptr_Py_OptimizeFlag; } PYCXX_EXPORT int &_Py_NoSiteFlag() { return *ptr_Py_NoSiteFlag; } PYCXX_EXPORT int &_Py_VerboseFlag() { return *ptr_Py_VerboseFlag; } +# endif PYCXX_EXPORT char *__Py_PackageContext() { return *ptr__Py_PackageContext; } @@ -416,16 +437,16 @@ void _XDECREF( PyObject *op ) // // Wrap variables as function calls // -#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ +# define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ PYCXX_EXPORT PyObject *_Exc_##eclass() { return ::PyExc_##eclass; } -#if PY_MAJOR_VERSION == 2 -#include "CXX/Python2/cxx_standard_exceptions.hxx" -#else -#include "CXX/Python3/cxx_standard_exceptions.hxx" -#endif +# if PY_MAJOR_VERSION == 2 +# include "CXX/Python2/cxx_standard_exceptions.hxx" +# else +# include "CXX/Python3/cxx_standard_exceptions.hxx" +# endif -#undef PYCXX_STANDARD_EXCEPTION +# undef PYCXX_STANDARD_EXCEPTION // // wrap items in Object.h @@ -439,11 +460,15 @@ PYCXX_EXPORT PyTypeObject *_CFunction_Type() { return &PyCFunction_Type; PYCXX_EXPORT PyTypeObject *_Complex_Type() { return &PyComplex_Type; } PYCXX_EXPORT PyTypeObject *_Dict_Type() { return &PyDict_Type; } PYCXX_EXPORT PyTypeObject *_Float_Type() { return &PyFloat_Type; } +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT PyTypeObject *_Function_Type() { return &PyFunction_Type; } +# endif PYCXX_EXPORT PyTypeObject *_Bool_Type() { return &PyBool_Type; } PYCXX_EXPORT PyTypeObject *_List_Type() { return &PyList_Type; } PYCXX_EXPORT PyTypeObject *_Long_Type() { return &PyLong_Type; } +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT PyTypeObject *_Method_Type() { return &PyMethod_Type; } +# endif PYCXX_EXPORT PyTypeObject *_Module_Type() { return &PyModule_Type; } PYCXX_EXPORT PyTypeObject *_Range_Type() { return &PyRange_Type; } PYCXX_EXPORT PyTypeObject *_Slice_Type() { return &PySlice_Type; } @@ -463,12 +488,14 @@ PYCXX_EXPORT PyTypeObject *_Bytes_Type() { return &PyBytes_Type; } // // wrap flags // +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT int &_Py_DebugFlag() { return Py_DebugFlag; } PYCXX_EXPORT int &_Py_InteractiveFlag() { return Py_InteractiveFlag; } PYCXX_EXPORT int &_Py_OptimizeFlag() { return Py_OptimizeFlag; } PYCXX_EXPORT int &_Py_NoSiteFlag() { return Py_NoSiteFlag; } PYCXX_EXPORT int &_Py_VerboseFlag() { return Py_VerboseFlag; } PYCXX_EXPORT const char *__Py_PackageContext() { return _Py_PackageContext; } +# endif // // Needed to keep the abstractions for delayload interface diff --git a/src/CXX/Python3/Config.hxx b/src/CXX/Python3/Config.hxx index 5b5802c57d15..08aa49526957 100644 --- a/src/CXX/Python3/Config.hxx +++ b/src/CXX/Python3/Config.hxx @@ -38,6 +38,10 @@ #ifndef __PyCXX_config_hh__ #define __PyCXX_config_hh__ +#if defined( Py_LIMITED_API ) && Py_LIMITED_API+0 < 0x03040000 +#error "PyCXX support for Python limited API requires version 3.4 or newer. Py_LIMITED_API=0x03040000" +#endif + // // Microsoft VC++ 6.0 has no traits // diff --git a/src/CXX/Python3/Exception.hxx b/src/CXX/Python3/Exception.hxx index 95ecd37a1dbe..eb35aad33e1a 100644 --- a/src/CXX/Python3/Exception.hxx +++ b/src/CXX/Python3/Exception.hxx @@ -85,6 +85,10 @@ namespace Py : BaseException( exception, reason ) {} + Exception( PyObject *exception, Object &reason ) + : BaseException( exception, reason ) + {} + Exception( PyObject *exception, const std::string &reason ) : BaseException( exception, reason ) {} diff --git a/src/CXX/Python3/ExtensionOldType.hxx b/src/CXX/Python3/ExtensionOldType.hxx index 96b68e66d760..e032713b20f2 100644 --- a/src/CXX/Python3/ExtensionOldType.hxx +++ b/src/CXX/Python3/ExtensionOldType.hxx @@ -119,15 +119,19 @@ namespace Py { std::string name( _name ); +#if !defined( Py_LIMITED_API ) if( name == "__name__" && type_object()->tp_name != NULL ) { return Py::String( type_object()->tp_name ); } +#endif +#if !defined( Py_LIMITED_API ) if( name == "__doc__" && type_object()->tp_doc != NULL ) { return Py::String( type_object()->tp_doc ); } +#endif // trying to fake out being a class for help() // else if( name == "__bases__" ) @@ -192,7 +196,7 @@ namespace Py self[0] = Object( this ); self[1] = Object( PyCapsule_New( method_def, NULL, NULL ), true ); - PyObject *func = PyCFunction_New( &method_def->ext_meth_def, self.ptr() ); + PyObject *func = PyCFunction_NewEx( &method_def->ext_meth_def, self.ptr(), NULL ); return Object(func, true); } diff --git a/src/CXX/Python3/ExtensionType.hxx b/src/CXX/Python3/ExtensionType.hxx index 0bb036c6c8b0..1f20714a212d 100644 --- a/src/CXX/Python3/ExtensionType.hxx +++ b/src/CXX/Python3/ExtensionType.hxx @@ -246,10 +246,15 @@ namespace Py #ifdef PYCXX_DEBUG std::cout << "extension_object_new()" << std::endl; #endif - PythonClassInstance *o = reinterpret_cast( subtype->tp_alloc( subtype, 0 ) ); - if( o == NULL ) +#if defined( Py_LIMITED_API ) + PyObject *object = reinterpret_cast( PyType_GetSlot( subtype, Py_tp_alloc ) )( subtype, 0 ); +#else + PyObject *object = subtype->tp_alloc( subtype, 0 ); +#endif + if( object == NULL ) return NULL; + PythonClassInstance *o = reinterpret_cast( object ); o->m_pycxx_object = NULL; PyObject *self = reinterpret_cast( o ); @@ -304,7 +309,12 @@ namespace Py std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned long >( self->m_pycxx_object ) << std::dec << std::endl; #endif delete self->m_pycxx_object; +#ifdef Py_LIMITED_API + freefunc fn = reinterpret_cast( PyType_GetSlot( _self->ob_type, Py_tp_free ) ); + fn( _self ); +#else _self->ob_type->tp_free( _self ); +#endif } public: diff --git a/src/CXX/Python3/ExtensionTypeBase.hxx b/src/CXX/Python3/ExtensionTypeBase.hxx index ddf6d0ffc64b..891dd928283b 100644 --- a/src/CXX/Python3/ExtensionTypeBase.hxx +++ b/src/CXX/Python3/ExtensionTypeBase.hxx @@ -127,9 +127,11 @@ namespace Py virtual Object number_or( const Object & ); virtual Object number_power( const Object &, const Object & ); +#if !defined( Py_LIMITED_API ) // Buffer virtual int buffer_get( Py_buffer *, int flags ); virtual int buffer_release( Py_buffer *buf ); +#endif public: // helper functions to call function fn_name with 0 to 9 args diff --git a/src/CXX/Python3/IndirectPythonInterface.hxx b/src/CXX/Python3/IndirectPythonInterface.hxx index 8f3b198e6af5..8c9bd2eea495 100644 --- a/src/CXX/Python3/IndirectPythonInterface.hxx +++ b/src/CXX/Python3/IndirectPythonInterface.hxx @@ -48,13 +48,13 @@ bool InitialisePythonIndirectInterface(); // // Wrap Exception variables as function calls // -PYCXX_EXPORT PyObject * _Exc_Exception(); +PYCXX_EXPORT PyObject * _Exc_BaseException(); -#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ +# define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \ PYCXX_EXPORT PyObject * _Exc_##eclass(); -#include "CXX/Python3/cxx_standard_exceptions.hxx" -#undef PYCXX_STANDARD_EXCEPTION +# include "CXX/Python3/cxx_standard_exceptions.hxx" +# undef PYCXX_STANDARD_EXCEPTION // // Wrap Object variables as function calls @@ -79,11 +79,13 @@ PYCXX_EXPORT bool _Class_Check( PyObject *op ); PYCXX_EXPORT PyTypeObject * _Instance_Type(); PYCXX_EXPORT bool _Instance_Check( PyObject *op ); +# if !defined( Py_LIMITED_API ) PYCXX_EXPORT PyTypeObject * _Method_Type(); PYCXX_EXPORT bool _Method_Check( PyObject *op ); PYCXX_EXPORT PyTypeObject * _Function_Type(); PYCXX_EXPORT bool _Function_Check( PyObject *op ); +# endif PYCXX_EXPORT PyTypeObject * _Complex_Type(); PYCXX_EXPORT bool _Complex_Check( PyObject *op ); @@ -139,15 +141,16 @@ PYCXX_EXPORT bool _TraceBack_Check( PyObject *v ); PYCXX_EXPORT PyTypeObject * _Tuple_Type(); PYCXX_EXPORT bool _Tuple_Check( PyObject *op ); +# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API ) PYCXX_EXPORT int &_Py_DebugFlag(); PYCXX_EXPORT int &_Py_InteractiveFlag(); PYCXX_EXPORT int &_Py_OptimizeFlag(); PYCXX_EXPORT int &_Py_NoSiteFlag(); PYCXX_EXPORT int &_Py_TabcheckFlag(); PYCXX_EXPORT int &_Py_VerboseFlag(); -PYCXX_EXPORT int &_Py_UnicodeFlag(); PYCXX_EXPORT const char *__Py_PackageContext(); +# endif PYCXX_EXPORT void _XINCREF( PyObject *op ); PYCXX_EXPORT void _XDECREF( PyObject *op ); diff --git a/src/CXX/Python3/Objects.hxx b/src/CXX/Python3/Objects.hxx index 1126115e6464..f097230a7d73 100644 --- a/src/CXX/Python3/Objects.hxx +++ b/src/CXX/Python3/Objects.hxx @@ -968,6 +968,7 @@ namespace Py bool operator<=( double a, const Float &b ); bool operator<=( const Float &a, double b ); +#if !defined( Py_LIMITED_API ) // =============================================== // class Complex class PYCXX_EXPORT Complex: public Object @@ -1055,6 +1056,7 @@ namespace Py return PyComplex_ImagAsDouble( ptr() ); } }; +#endif // Py_LIMITED_API // Sequences // Sequences are here represented as sequences of items of type T. @@ -1278,7 +1280,7 @@ namespace Py { public: // STL definitions - typedef Py_ssize_t size_type; + typedef PyCxx_ssize_t size_type; typedef seqref reference; typedef T const_reference; typedef seqref *pointer; @@ -1778,8 +1780,12 @@ namespace Py // Python strings return strings as individual elements. // I'll try having a class Char which is a String of length 1 // +#if !defined(Py_LIMITED_API) typedef std::basic_string unicodestring; extern Py_UNICODE unicode_null_string[1]; +#endif + typedef std::basic_string ucs4string; + extern Py_UCS4 ucs4_null_string[1]; class PYCXX_EXPORT Byte: public Object { @@ -1788,8 +1794,7 @@ namespace Py virtual bool accepts( PyObject *pyob ) const { return pyob != NULL -// QQQ _Unicode_Check for a Byte??? - && Py::_Unicode_Check( pyob ) + && Py::_Bytes_Check( pyob ) && PySequence_Length( pyob ) == 1; } @@ -1971,17 +1976,21 @@ namespace Py validate(); } +#if !defined( Py_LIMITED_API ) Char( Py_UNICODE v ) : Object( PyUnicode_FromOrdinal( v ), true ) { validate(); } +#endif +#if !defined( Py_LIMITED_API ) Char( const unicodestring &v ) : Object( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, const_cast( v.data() ),1 ), true ) { validate(); } +#endif // Assignment acquires new ownership of pointer Char &operator=( const Object &rhs ) @@ -1996,24 +2005,34 @@ namespace Py return *this; } +#if !defined( Py_LIMITED_API ) Char &operator=( const unicodestring &v ) { set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, const_cast( v.data() ), 1 ), true ); return *this; } +#endif +#if !defined( Py_LIMITED_API ) Char &operator=( int v_ ) { Py_UNICODE v( v_ ); set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, &v, 1 ), true ); return *this; } +#endif +#if !defined( Py_LIMITED_API ) Char &operator=( Py_UNICODE v ) { set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, &v, 1 ), true ); return *this; } +#endif + long ord() + { + return static_cast( PyUnicode_ReadChar( ptr(), 0 ) ); + } // Conversion operator String() const; @@ -2104,11 +2123,29 @@ namespace Py validate(); } +#if !defined( Py_UNICODE_WIDE ) + // Need these c'tors becuase Py_UNICODE is 2 bytes + // User may use "int" or "unsigned int" as the unicode type + String( const unsigned int *s, int length ) + : SeqBase( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, reinterpret_cast( s ), length ), true ) + { + validate(); + } + + String( const int *s, int length ) + : SeqBase( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, reinterpret_cast( s ), length ), true ) + { + validate(); + } +#endif + +#if !defined( Py_LIMITED_API ) String( const Py_UNICODE *s, int length ) : SeqBase( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, s, length ), true ) { validate(); } +#endif // Assignment acquires new ownership of pointer String &operator=( const Object &rhs ) @@ -2123,12 +2160,21 @@ namespace Py return *this; } +#if !defined( Py_LIMITED_API ) String &operator=( const unicodestring &v ) { set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, const_cast( v.data() ), v.length() ), true ); return *this; } +#endif +#if !defined( Py_UNICODE_WIDE ) && !defined( Py_LIMITED_API ) + String &operator=( const ucs4string &v ) + { + set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, reinterpret_cast( v.data() ), v.length() ), true ); + return *this; + } +#endif // Encode Bytes encode( const char *encoding, const char *error="strict" ) const { @@ -2141,17 +2187,31 @@ namespace Py return PyUnicode_GetLength( ptr() ); } -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9 +#if !defined( Py_LIMITED_API ) const Py_UNICODE *unicode_data() const { return PyUnicode_AS_UNICODE( ptr() ); } +#endif +#if !defined( Py_LIMITED_API ) unicodestring as_unicodestring() const { return unicodestring( unicode_data(), PyUnicode_GetLength( ptr() ) ); } #endif + ucs4string as_ucs4string() const + { + Py_UCS4 *buf = new Py_UCS4[ size() ]; + if( PyUnicode_AsUCS4( ptr(), buf, size(), 0 ) == NULL ) + { + ifPyErrorThrowCxxException(); + } + ucs4string ucs4( buf, size() ); + delete[] buf; + + return ucs4; + } operator std::string() const { diff --git a/src/CXX/Python3/PythonType.hxx b/src/CXX/Python3/PythonType.hxx index 1596f5aeb156..8ec0a39b3e1f 100644 --- a/src/CXX/Python3/PythonType.hxx +++ b/src/CXX/Python3/PythonType.hxx @@ -38,6 +38,10 @@ #ifndef __CXX_PythonType__h #define __CXX_PythonType__h +#if defined( Py_LIMITED_API ) +#include +#endif + namespace Py { class PYCXX_EXPORT PythonType @@ -57,7 +61,7 @@ namespace Py PythonType &doc( const char *d ); PythonType &supportClass( void ); -#ifdef PYCXX_PYTHON_2TO3 +#if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) PythonType &supportPrint( void ); #endif PythonType &supportGetattr( void ); @@ -150,7 +154,7 @@ namespace Py support_number_int | support_number_float ); - +#if !defined( Py_LIMITED_API ) enum { support_buffer_getbuffer = B(0), support_buffer_releasebuffer = B(1) @@ -159,6 +163,7 @@ namespace Py support_buffer_getbuffer | support_buffer_releasebuffer ); +#endif #undef B PythonType &set_tp_dealloc( void (*tp_dealloc)( PyObject * ) ); @@ -170,16 +175,17 @@ namespace Py bool readyType(); protected: - void init_sequence(); - void init_mapping(); - void init_number(); - void init_buffer(); - +#if defined( Py_LIMITED_API ) + std::unordered_map slots; + PyType_Spec *spec; + PyTypeObject *tp_object; +#else PyTypeObject *table; PySequenceMethods *sequence_table; PyMappingMethods *mapping_table; PyNumberMethods *number_table; PyBufferProcs *buffer_table; +#endif private: // diff --git a/src/CXX/Python3/cxx_extensions.cxx b/src/CXX/Python3/cxx_extensions.cxx index e55593a5ac88..3b2703de9359 100644 --- a/src/CXX/Python3/cxx_extensions.cxx +++ b/src/CXX/Python3/cxx_extensions.cxx @@ -152,7 +152,11 @@ PyMethodDef *MethodTable::table() //================================================================================ ExtensionModuleBase::ExtensionModuleBase( const char *name ) : m_module_name( name ) +#if defined( Py_LIMITED_API ) +, 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_def , m_module( NULL ) @@ -228,7 +232,7 @@ extern "C" // All the following functions redirect the call from Python // onto the matching virtual function in PythonExtensionBase // -#if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 +#if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) static int print_handler( PyObject *, FILE *, int ); #endif static PyObject *getattr_handler( PyObject *, char * ); @@ -280,8 +284,10 @@ extern "C" static PyObject *number_power_handler( PyObject *, PyObject *, PyObject * ); // Buffer +#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 ) @@ -291,158 +297,142 @@ extern "C" void standard_dealloc( PyObject *p ) bool PythonType::readyType() { +#if defined( Py_LIMITED_API ) + if( !tp_object ) + { + std::vector spec_slots( slots.size() + 1 ); + int index = 0; + + for (std::unordered_map::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( PyType_FromSpec(spec) ); + } + return tp_object != NULL; +#else return PyType_Ready( table ) >= 0; +#endif } -PythonType &PythonType::supportSequenceType( int methods_to_support ) -{ - if( !sequence_table ) +#if defined( Py_LIMITED_API ) +#define FILL_SEQUENCE_SLOT(slot) \ + if( methods_to_support&support_sequence_ ## slot ) { \ + slots[ Py_sq_ ## slot ] = reinterpret_cast( 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) { - sequence_table = new PySequenceMethods; - memset( sequence_table, 0, sizeof( PySequenceMethods ) ); // ensure new fields are 0 - table->tp_as_sequence = sequence_table; - if( methods_to_support&support_sequence_length ) - { - sequence_table->sq_length = sequence_length_handler; - } - if( methods_to_support&support_sequence_concat ) - { - sequence_table->sq_concat = sequence_concat_handler; - } - if( methods_to_support&support_sequence_repeat ) - { - sequence_table->sq_repeat = sequence_repeat_handler; - } - if( methods_to_support&support_sequence_item ) - { - sequence_table->sq_item = sequence_item_handler; - } - if( methods_to_support&support_sequence_ass_item ) - { - sequence_table->sq_ass_item = sequence_ass_item_handler; - } - if( methods_to_support&support_sequence_inplace_concat ) - { - sequence_table->sq_inplace_concat = sequence_inplace_concat_handler; - } - if( methods_to_support&support_sequence_inplace_repeat ) - { - sequence_table->sq_inplace_repeat = sequence_inplace_repeat_handler; - } - if( methods_to_support&support_sequence_contains ) - { - sequence_table->sq_contains = sequence_contains_handler; - } + return *this; } + sequence_table = new PySequenceMethods; + memset( sequence_table, 0, sizeof( PySequenceMethods ) ); // ensure new fields are 0 + 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( 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( !mapping_table ) +#if !defined( Py_LIMITED_API ) + if( mapping_table ) { - mapping_table = new PyMappingMethods; - memset( mapping_table, 0, sizeof( PyMappingMethods ) ); // ensure new fields are 0 - table->tp_as_mapping = mapping_table; - - if( methods_to_support&support_mapping_length ) - { - mapping_table->mp_length = mapping_length_handler; - } - if( methods_to_support&support_mapping_subscript ) - { - mapping_table->mp_subscript = mapping_subscript_handler; - } - if( methods_to_support&support_mapping_ass_subscript ) - { - mapping_table->mp_ass_subscript = mapping_ass_subscript_handler; - } + return *this; } + mapping_table = new PyMappingMethods; + memset( mapping_table, 0, sizeof( PyMappingMethods ) ); // ensure new fields are 0 + 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( number_ ## slot ## _handler ); \ + } +#else +#define FILL_NUMBER_SLOT(slot) \ + if( methods_to_support&support_number_ ## slot ) { \ + number_table->nb_ ## slot = number_ ## slot ## _handler; \ + } +#endif + PythonType &PythonType::supportNumberType( int methods_to_support ) { - if( !number_table ) +#if !defined( Py_LIMITED_API ) + if( number_table ) { - number_table = new PyNumberMethods; - memset( number_table, 0, sizeof( PyNumberMethods ) ); // ensure new fields are 0 - table->tp_as_number = number_table; - - if( methods_to_support&support_number_add ) - { - number_table->nb_add = number_add_handler; - } - if( methods_to_support&support_number_subtract ) - { - number_table->nb_subtract = number_subtract_handler; - } - if( methods_to_support&support_number_multiply ) - { - number_table->nb_multiply = number_multiply_handler; - } - if( methods_to_support&support_number_remainder ) - { - number_table->nb_remainder = number_remainder_handler; - } - if( methods_to_support&support_number_divmod ) - { - number_table->nb_divmod = number_divmod_handler; - } - if( methods_to_support&support_number_power ) - { - number_table->nb_power = number_power_handler; - } - if( methods_to_support&support_number_negative ) - { - number_table->nb_negative = number_negative_handler; - } - if( methods_to_support&support_number_positive ) - { - number_table->nb_positive = number_positive_handler; - } - if( methods_to_support&support_number_absolute ) - { - number_table->nb_absolute = number_absolute_handler; - } - if( methods_to_support&support_number_invert ) - { - number_table->nb_invert = number_invert_handler; - } - if( methods_to_support&support_number_lshift ) - { - number_table->nb_lshift = number_lshift_handler; - } - if( methods_to_support&support_number_rshift ) - { - number_table->nb_rshift = number_rshift_handler; - } - if( methods_to_support&support_number_and ) - { - number_table->nb_and = number_and_handler; - } - if( methods_to_support&support_number_xor ) - { - number_table->nb_xor = number_xor_handler; - } - if( methods_to_support&support_number_or ) - { - number_table->nb_or = number_or_handler; - } - if( methods_to_support&support_number_int ) - { - number_table->nb_int = number_int_handler; - } - if( methods_to_support&support_number_float ) - { - number_table->nb_float = number_float_handler; - } - - // QQQ lots of new methods to add + return *this; } + number_table = new PyNumberMethods; + memset( number_table, 0, sizeof( PyNumberMethods ) ); // ensure new fields are 0 + 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) return *this; } +#undef FILL_NUMBER_SLOT + +#if !defined( Py_LIMITED_API ) PythonType &PythonType::supportBufferType( int methods_to_support ) { if( !buffer_table ) @@ -462,10 +452,27 @@ PythonType &PythonType::supportBufferType( int methods_to_support ) } return *this; } +#endif // if you define one sequence method you must define // all of them except the assigns +#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( default_name ); + spec->basicsize = basic_size; + spec->itemsize = itemsize; + spec->flags = Py_TPFLAGS_DEFAULT; + + slots[ Py_tp_dealloc ] = reinterpret_cast( standard_dealloc ); + + tp_object = 0; +} + +#else PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name ) : table( new PyTypeObject ) , sequence_table( NULL ) @@ -562,70 +569,122 @@ PythonType::PythonType( size_t basic_size, int itemsize, const char *default_nam 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( 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( const_cast( d ) ); +#else table->tp_doc = const_cast( d ); +#endif return *this; } const char *PythonType::getDoc() const { +#if defined( Py_LIMITED_API ) + if( tp_object ) + return reinterpret_cast( PyType_GetSlot( tp_object, Py_tp_doc ) ); + + std::unordered_map::const_iterator slot = slots.find( Py_tp_doc ); + if( slot == slots.end() ) + return NULL; + return reinterpret_cast( 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( 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( 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( 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( 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; } @@ -641,25 +700,41 @@ PythonType &PythonType::supportPrint() PythonType &PythonType::supportGetattr() { +#if defined( Py_LIMITED_API ) + slots[ Py_tp_getattr ] = reinterpret_cast( 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( 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( 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( setattro_handler ); +#else table->tp_setattro = setattro_handler; +#endif return *this; } @@ -673,31 +748,51 @@ PythonType &PythonType::supportCompare( void ) PythonType &PythonType::supportRichCompare() { +#if defined( Py_LIMITED_API ) + slots[ Py_tp_richcompare ] = reinterpret_cast( 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( 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( 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( 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( call_handler ); +#else table->tp_call = call_handler; +#endif return *this; } @@ -705,11 +800,19 @@ 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( 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( iternext_handler ); +#else table->tp_iternext = iternext_handler; +#endif } return *this; } @@ -721,7 +824,7 @@ PythonType &PythonType::supportIter( int methods_to_support ) //-------------------------------------------------------------------------------- PythonExtensionBase *getPythonExtensionBase( PyObject *self ) { - if( self->ob_type->tp_flags&Py_TPFLAGS_BASETYPE ) + if(PyType_HasFeature(self->ob_type, Py_TPFLAGS_BASETYPE)) { PythonClassInstance *instance = reinterpret_cast( self ); return instance->m_pycxx_object; @@ -732,7 +835,7 @@ PythonExtensionBase *getPythonExtensionBase( PyObject *self ) } } -#if defined( PYCXX_PYTHON_2TO3 ) && !defined ( Py_LIMITED_API ) && PY_MINOR_VERSION <= 7 +#if defined( PYCXX_PYTHON_2TO3 ) && !defined ( Py_LIMITED_API ) extern "C" int print_handler( PyObject *self, FILE *fp, int flags ) { try @@ -1262,6 +1365,7 @@ extern "C" PyObject *number_power_handler( PyObject *self, PyObject *x1, PyObjec } // Buffer +#ifndef Py_LIMITED_API extern "C" int buffer_get_handler( PyObject *self, Py_buffer *buf, int flags ) { try @@ -1281,6 +1385,7 @@ extern "C" void buffer_release_handler( PyObject *self, Py_buffer *buf ) p->buffer_release( buf ); // NOTE: No way to indicate error to Python } +#endif //================================================================================ // @@ -1394,7 +1499,7 @@ int PythonExtensionBase::genericSetAttro( const String &name, const Object &valu return PyObject_GenericSetAttr( selfPtr(), name.ptr(), value.ptr() ); } -#if defined( PYCXX_PYTHON_2TO3 ) +#if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API ) int PythonExtensionBase::print( FILE *, int ) { missing_method( print ); @@ -1611,6 +1716,7 @@ Object PythonExtensionBase::number_power( const Object &, const Object & ) // Buffer +#ifndef Py_LIMITED_API int PythonExtensionBase::buffer_get( Py_buffer * /*buf*/, int /*flags*/ ) { missing_method( buffer_get ); @@ -1622,6 +1728,7 @@ int PythonExtensionBase::buffer_release( Py_buffer * /*buf*/ ) // memory is dynamic. return 0; } +#endif //-------------------------------------------------------------------------------- // diff --git a/src/CXX/Python3/cxx_standard_exceptions.hxx b/src/CXX/Python3/cxx_standard_exceptions.hxx index 4c53ad967d92..d16c14cae450 100644 --- a/src/CXX/Python3/cxx_standard_exceptions.hxx +++ b/src/CXX/Python3/cxx_standard_exceptions.hxx @@ -16,7 +16,7 @@ PYCXX_STANDARD_EXCEPTION( GeneratorExit, BaseException ) PYCXX_STANDARD_EXCEPTION( Exception, BaseException ) #endif PYCXX_STANDARD_EXCEPTION( StopIteration, Exception ) -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 +#if (defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x03050000 && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5) || (!defined( Py_LIMITED_API ) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5) PYCXX_STANDARD_EXCEPTION( StopAsyncIteration, Exception ) #endif PYCXX_STANDARD_EXCEPTION( ArithmeticError, Exception ) @@ -53,7 +53,7 @@ PYCXX_STANDARD_EXCEPTION( TimeoutError, OSError ) PYCXX_STANDARD_EXCEPTION( ReferenceError, Exception ) PYCXX_STANDARD_EXCEPTION( RuntimeError, Exception ) PYCXX_STANDARD_EXCEPTION( NotImplementedError, RuntimeError ) -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5 +#if (defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x03050000 && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5) || (!defined( Py_LIMITED_API ) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5) PYCXX_STANDARD_EXCEPTION( RecursionError, RuntimeError ) #endif PYCXX_STANDARD_EXCEPTION( SyntaxError, Exception ) diff --git a/src/CXX/Python3/cxxsupport.cxx b/src/CXX/Python3/cxxsupport.cxx index 3439306b7d8d..a22160bd026a 100644 --- a/src/CXX/Python3/cxxsupport.cxx +++ b/src/CXX/Python3/cxxsupport.cxx @@ -45,7 +45,10 @@ Py_ssize_t numeric_limits_max() return std::numeric_limits::max(); } +#if !defined(Py_LIMITED_API) Py_UNICODE unicode_null_string[1] = { 0 }; +#endif +Py_UCS4 ucs4_null_string[1] = { 0 }; Type Object::type() const { diff --git a/src/CXX/Version.hxx b/src/CXX/Version.hxx index 8247a731fa14..fabce5f60ca0 100644 --- a/src/CXX/Version.hxx +++ b/src/CXX/Version.hxx @@ -39,7 +39,7 @@ #define __PyCXX_version_hxx__ #define PYCXX_VERSION_MAJOR 7 -#define PYCXX_VERSION_MINOR 0 +#define PYCXX_VERSION_MINOR 1 #define PYCXX_VERSION_PATCH 0 #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 )