Commit 92a56d99 authored by Josué Ortega's avatar Josué Ortega

New upstream version 1.9.9

parent 59e4e31a
MAJOR=1
MINOR=9
PATCH=6
PATCH=9
BUILD=0
Version: 7.0.3 (23-April-2017)
Update Py::Long to support long long consitently between Python2 and Python3.
Version: 7.0.3 (23-April-2017)
Update Py::Long to support long long consitently between Python2 and Python3.
../Doc/Python2/PyCXX.html
\ No newline at end of file
../Doc/Python3/PyCXX.html
\ No newline at end of file
../README.html
\ No newline at end of file
#!/bin/bash
scp index.html barry-scott,cxx@web.sourceforge.net:/home/groups/c/cx/cxx/htdocs/
scp ../README.html barry-scott,cxx@web.sourceforge.net:/home/groups/c/cx/cxx/htdocs/
scp ../Doc/Python2/PyCXX.html barry-scott,cxx@web.sourceforge.net:/home/groups/c/cx/cxx/htdocs/PyCXX-Python2.html
scp ../Doc/Python3/style.css barry-scott,cxx@web.sourceforge.net:/home/groups/c/cx/cxx/htdocs/style.css
scp ../Doc/Python3/PyCXX.html barry-scott,cxx@web.sourceforge.net:/home/groups/c/cx/cxx/htdocs/PyCXX-Python3.html
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>PyCXX: Write Python Extensions in C++</title>
</head>
<body>
<center><b>PyCXX: Write Python Extensions in C++</b>
<p><b>Barry Scott, barry@barrys-emacs.org</b>
</center>
<p><b>The <a href="http://sourceforge.net/project/?group_id=3180">CXX
Project Page</a> at&nbsp;<a href="http://sourceforge.net"><img SRC="http://sourceforge.net/sflogo.php?group_id=3180&type=1" alt="SourceForge Home" nosave height="31" width="88" align="abscenter"></a>
gives you access to the releases, the Subversion repository, and more.</b>
<p>
<h1>PyCXX is designed to make it easier to extend Python with C++</h1>
<p>
CXX/Objects is a set of C++ facilities to make it easier
to write Python extensions. The chief way in which PyCXX makes it easier
to write Python extensions is that it greatly increases the probability
that your program will not make a reference-counting error and will not
have to continually check error returns from the Python C API. CXX/Objects
integrates Python with C++ in these ways:
<p>
<ul>
<li>
C++ exception handling is relied on to detect errors
and clean up. In a complicated function this is often a tremendous problem
when writing in C. With PyCXX, we let the compiler keep track of what objects
need to be dereferenced when an error occurs.</li>
<li>
The Standard Template Library (STL) and its many algorithms
plug and play with Python containers such as lists and tuples.
</li>
<li>
The optional CXX/Extensions facility allows you to replace the clumsy C tables with objects
and method calls that define your modules and extension objects.
</li>
</ul>
<hr />
<p>PyCXX documentation is split into <a href="PyCXX-Python3.html">Python 3</a>
and <a href="PyCXX-Python2.html">Python 2</a> versions. The Python 3 documentation is the most accurate.</p>
<p>Latest PyCXX <a href="README.html">README</a> file.</p>
<hr />
<iframe src="README.html" width="100%" height="1024px"></iframe>
</body>
</html>
../Doc/Python3/style.css
\ No newline at end of file
if not "%1%2" == "" goto :build_%1_%2
:build_27_32
setlocal
call "%LOCALAPPDATA%\Programs\Common\Microsoft\Visual C++ for Python\9.0\vcvarsall.bat" x86
if exist c:\python27.win32\python.exe (
c:\python27.win32\python setup_makefile.py win32 win32.mak
nmake -f win32.mak clean all 2>&1 | c:\unxutils\tee tmp-win32-python27-build.log
nmake -f win32.mak test 2>&1 | c:\unxutils\tee tmp-win32-python27-test.log
)
endlocal
if not "%1%2" == "" goto :eof
:build_33_32
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
if exist c:\python33.win32\python.exe (
c:\python33.win32\python setup_makefile.py win32 win32.mak
nmake -f win32.mak clean all 2>&1 | c:\unxutils\tee tmp-win32-python33-build.log
nmake -f win32.mak test 2>&1 | c:\unxutils\tee tmp-win32-python33-test.log
)
endlocal
if not "%1%2" == "" goto :eof
:build_34_32
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
if exist c:\python34.win32\python.exe (
c:\python34.win32\python setup_makefile.py win32 win32.mak
nmake -f win32.mak clean all 2>&1 | c:\unxutils\tee tmp-win32-python34-build.log
nmake -f win32.mak test 2>&1 | c:\unxutils\tee tmp-win32-python34-test.log
)
endlocal
if not "%1%2" == "" goto :eof
:build_35_32
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
if exist c:\python35.win32\python.exe (
c:\python35.win32\python setup_makefile.py win32 win32.mak
nmake -f win32.mak clean all 2>&1 | c:\unxutils\tee tmp-win32-python35-build.log
nmake -f win32.mak test 2>&1 | c:\unxutils\tee tmp-win32-python35-test.log
)
endlocal
if not "%1%2" == "" goto :eof
:build_27_64
setlocal
call "%LOCALAPPDATA%\Programs\Common\Microsoft\Visual C++ for Python\9.0\vcvarsall.bat" x64
if exist c:\python27.win64\python.exe (
c:\python27.win64\python setup_makefile.py win64 win64.mak
nmake -f win64.mak clean all 2>&1 | c:\unxutils\tee tmp-win64-python27-build.log
nmake -f win64.mak test 2>&1 | c:\unxutils\tee tmp-win64-python27-test.log
)
endlocal
if not "%1%2" == "" goto :eof
:build_35_64
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
if exist c:\python35.win64\python.exe (
c:\python35.win64\python setup_makefile.py win64 win64.mak
nmake -f win64.mak clean all 2>&1 | c:\unxutils\tee tmp-win64-python35-build.log
nmake -f win64.mak test 2>&1 | c:\unxutils\tee tmp-win64-python35-test.log
)
endlocal
if not "%1%2" == "" goto :eof
......@@ -81,6 +81,10 @@ namespace Py
: BaseException( exception, reason )
{}
Exception( PyObject *exception, Object &reason )
: BaseException ( exception, reason )
{}
Exception( PyObject *exception, const std::string &reason )
: BaseException( exception, reason )
{}
......
......@@ -153,7 +153,9 @@ int &_Py_VerboseFlag();
void _XINCREF( PyObject *op );
void _XDECREF( PyObject *op );
# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API )
char *__Py_PackageContext();
#endif
}
#endif // __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
......@@ -183,11 +183,6 @@ namespace Py
bool readyType();
protected:
void init_sequence();
void init_mapping();
void init_number();
void init_buffer();
PyTypeObject *table;
PySequenceMethods *sequence_table;
PyMappingMethods *mapping_table;
......
......@@ -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
//
......
......@@ -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 )
{}
......
......@@ -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__" )
......
......@@ -246,10 +246,15 @@ namespace Py
#ifdef PYCXX_DEBUG
std::cout << "extension_object_new()" << std::endl;
#endif
PythonClassInstance *o = reinterpret_cast<PythonClassInstance *>( subtype->tp_alloc( subtype, 0 ) );
if( o == NULL )
#if defined( Py_LIMITED_API )
PyObject *object = reinterpret_cast<allocfunc>( 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<PythonClassInstance *>( object );
o->m_pycxx_object = NULL;
PyObject *self = reinterpret_cast<PyObject *>( 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<freefunc>( PyType_GetSlot( _self->ob_type, Py_tp_free ) );
fn( _self );
#else
_self->ob_type->tp_free( _self );
#endif
}
public:
......
......@@ -70,7 +70,7 @@ namespace Py
virtual void reinit( Tuple &args, Dict &kwds );
// object basics
#ifdef PYCXX_PYTHON_2TO3
#if defined( PYCXX_PYTHON_2TO3 ) && !defined( Py_LIMITED_API )
virtual int print( FILE *, int );
#endif
virtual Object getattr( const char * );
......@@ -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
......
......@@ -36,9 +36,9 @@
//-----------------------------------------------------------------------------
#ifndef __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
#define __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
# define __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
#include "CXX/WrapPython.h"
# include "CXX/WrapPython.h"
namespace Py
{
......@@ -49,11 +49,11 @@ bool InitialisePythonIndirectInterface();
//
PyObject * _Exc_BaseException();
#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \
# define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \
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
......@@ -78,9 +78,14 @@ bool _Class_Check( PyObject *op );
PyTypeObject * _Instance_Type();
bool _Instance_Check( PyObject *op );
# if !defined( Py_LIMITED_API )
PyTypeObject * _Method_Type();
bool _Method_Check( PyObject *op );
PyTypeObject * _Function_Type();
bool _Function_Check( PyObject *op );
# endif
PyTypeObject * _Complex_Type();
bool _Complex_Check( PyObject *op );
......@@ -96,9 +101,6 @@ bool _Float_Check( PyObject *op );
PyTypeObject * _Frame_Type();
bool _Frame_Check( PyObject *op );
PyTypeObject * _Function_Type();
bool _Function_Check( PyObject *op );
PyTypeObject * _Bool_Type();
bool _Boolean_Check( PyObject *op );
......@@ -138,18 +140,23 @@ bool _TraceBack_Check( PyObject *v );
PyTypeObject * _Tuple_Type();
bool _Tuple_Check( PyObject *op );
# if PY_MAJOR_VERSION == 2 || !defined( Py_LIMITED_API )
int &_Py_DebugFlag();
int &_Py_InteractiveFlag();
int &_Py_OptimizeFlag();
int &_Py_NoSiteFlag();
int &_Py_TabcheckFlag();
int &_Py_VerboseFlag();
int &_Py_UnicodeFlag();
# if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7
const char *__Py_PackageContext();
# else
char *__Py_PackageContext();
# endif
# endif
void _XINCREF( PyObject *op );
void _XDECREF( PyObject *op );
char *__Py_PackageContext();
};
#endif // __CXX_INDIRECT_PYTHON_INTERFACE__HXX__
......@@ -1008,6 +1008,8 @@ namespace Py
{
return pyob && Py::_Complex_Check( pyob );
}
#if !defined( Py_LIMITED_API )
// convert to Py_complex
operator Py_complex() const
{
......@@ -1019,6 +1021,8 @@ namespace Py
set( PyComplex_FromCComplex( v ), true );
return *this;
}
#endif // Py_LIMITED_API
// assign from a double
Complex &operator=( double v )
{
......@@ -1054,6 +1058,7 @@ namespace Py
return PyComplex_ImagAsDouble( ptr() );
}
};
// Sequences
// Sequences are here represented as sequences of items of type T.
// The base class SeqBase<T> represents that.
......@@ -1754,10 +1759,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<Py_UNICODE> unicodestring;
typedef std::basic_string<Py_UCS4> ucs4string;
extern Py_UNICODE unicode_null_string[1];
#endif
typedef std::basic_string<Py_UCS4> ucs4string;
extern Py_UCS4 ucs4_null_string[1];
class Byte: public Object
{
......@@ -1948,17 +1955,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_FromUnicode( const_cast<Py_UNICODE*>( v.data() ),1 ), true )
{
validate();
}
#endif
// Assignment acquires new ownership of pointer
Char &operator=( const Object &rhs )
......@@ -1973,32 +1984,55 @@ namespace Py
return *this;
}
#if !defined( Py_LIMITED_API )
Char &operator=( const unicodestring &v )
{
set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ), 1 ), true );
return *this;
}
#endif
#if !defined( Py_LIMITED_API )
Char &operator=( int v_ )
{
Py_UNICODE v( static_cast<Py_UNICODE>( v_ ) );
set( PyUnicode_FromUnicode( &v, 1 ), true );
return *this;
}
#endif
#if !defined( Py_LIMITED_API )
Char &operator=( Py_UNICODE v )
{
set( PyUnicode_FromUnicode( &v, 1 ), true );
return *this;
}
#endif
long ord()
{
if( PyUnicode_READY( ptr() ) == -1 )
#if !defined( Py_LIMITED_API )
return static_cast<long>( PyUnicode_ReadChar( ptr(), 0 ) );
#else
// we know that a Char() is 1 unicode code point
// that fits in 2 wchar_t on windows at worst
wchar_t buf[2];
Py_ssize_t num_elements = PyUnicode_AsWideChar( ptr(), buf, 2 );
// just one wchar_t that easy
if( num_elements == 1 )
{
return static_cast<long>( buf[0] );
}
// must be a pair of utf-16 surragates - convert to a code point
if( num_elements == 2 )
{
throw RuntimeError( "Char::ord() PyUnicode_READY() failed." );
// convert from utf-16 to a code-point
return static_cast<long>( ((buf[0]-0xd800)*0x400) + (buf[1]-0xdc00) + 0x10000);
}
return static_cast<long>( PyUnicode_READ_CHAR( ptr(), 0 ) );
return 0;
#endif
}
// Conversion
......@@ -2090,7 +2124,7 @@ namespace Py
validate();
}
#if !defined( Py_UNICODE_WIDE )
#if !defined( Py_LIMITED_API ) && !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 )
......@@ -2106,11 +2140,13 @@ namespace Py
}
#endif
#if !defined( Py_LIMITED_API )
String( const Py_UNICODE *s, int length )
: SeqBase<Char>( PyUnicode_FromUnicode( s, length ), true )
{
validate();
}
#endif
// Assignment acquires new ownership of pointer
String &operator=( const Object &rhs )
......@@ -2125,13 +2161,15 @@ namespace Py
return *this;
}
#if !defined( Py_LIMITED_API )
String &operator=( const unicodestring &v )
{
set( PyUnicode_FromUnicode( const_cast<Py_UNICODE *>( v.data() ), v.length() ), true );
return *this;
}
#endif
#if !defined( Py_UNICODE_WIDE )
#if !defined( Py_UNICODE_WIDE ) && !defined( Py_LIMITED_API )
String &operator=( const ucs4string &v )
{
set( PyUnicode_FromKindAndData( PyUnicode_4BYTE_KIND, reinterpret_cast<const Py_UCS4 *>( v.data() ), v.length() ), true );
......@@ -2144,22 +2182,27 @@ namespace Py
return Bytes( PyUnicode_AsEncodedString( ptr(), encoding, error ), true );
}
#if !defined( Py_LIMITED_API )
// Queries
virtual size_type size() const
{
return PyUnicode_GET_LENGTH( ptr() );
return PyUnicode_GetLength( ptr() );
}
#endif
#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_GET_SIZE( ptr() ) );
return unicodestring( unicode_data(), PyUnicode_GetLength( ptr() ) );
}
#endif
ucs4string as_ucs4string() const
{
Py_UCS4 *buf = new Py_UCS4[ size() ];
......
......@@ -38,6 +38,10 @@
#ifndef __CXX_PythonType__h
#define __CXX_PythonType__h
#if defined( Py_LIMITED_API )
#include <unordered_map>
#endif
namespace Py
{
class 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<int, void*> slots;
PyType_Spec *spec;
PyTypeObject *tp_object;
#else
PyTypeObject *table;
PySequenceMethods *sequence_table;
PyMappingMethods *mapping_table;
PyNumberMethods *number_table;
PyBufferProcs *buffer_table;
#endif
private:
//
......
......@@ -16,7 +16,11 @@ 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(MS_WINDOWS) && ((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
// Windows builds of python 3.5 do not export the symbol PyExc_StopAsyncIteration - need atleast 3.6
#if defined(MS_WINDOWS) && ((defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x03050000 && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6) || (!defined( Py_LIMITED_API ) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 5))
PYCXX_STANDARD_EXCEPTION( StopAsyncIteration, Exception )
#endif
PYCXX_STANDARD_EXCEPTION( ArithmeticError, Exception )
......@@ -35,6 +39,7 @@ PYCXX_STANDARD_EXCEPTION( MemoryError, Exception )