PyCXX: update to version 6.3.0
This commit is contained in:
@@ -117,7 +117,7 @@ if(PYCXX_FOUND)
|
||||
${PYCXX_SOURCE_DIR}/cxxsupport.cxx
|
||||
${PYCXX_SOURCE_DIR}/IndirectPythonInterface.cxx
|
||||
)
|
||||
if(NOT ${PYCXX_VERSION} VERSION_LESS 7.0.0)
|
||||
if(NOT ${PYCXX_VERSION} VERSION_LESS 6.3.0)
|
||||
list(APPEND PYCXX_SOURCES
|
||||
${PYCXX_SOURCE_DIR}/cxx_exceptions.cxx)
|
||||
add_definitions(-DPYCXX_6_2_COMPATIBILITY)
|
||||
|
||||
@@ -71,11 +71,16 @@
|
||||
// Which C++ standard is in use?
|
||||
//
|
||||
#if defined( _MSC_VER )
|
||||
|
||||
# if _MSC_VER <= 1200
|
||||
// MSVC++ 6.0
|
||||
# define PYCXX_ISO_CPP_LIB 0
|
||||
# define STR_STREAM <strstream>
|
||||
# define TEMPLATE_TYPENAME class
|
||||
# else
|
||||
# define PYCXX_ISO_CPP_LIB 1
|
||||
# define STR_STREAM <sstream>
|
||||
# define TEMPLATE_TYPENAME typename
|
||||
|
||||
# endif
|
||||
#elif defined( __GNUC__ )
|
||||
# if __GNUC__ >= 3
|
||||
# define PYCXX_ISO_CPP_LIB 1
|
||||
|
||||
@@ -62,200 +62,58 @@ namespace Py
|
||||
|
||||
explicit Exception ()
|
||||
{}
|
||||
|
||||
|
||||
// This overloaded constructor will be removed in future PyCXX versions
|
||||
//Exception (const std::string &reason)
|
||||
//{
|
||||
// PyErr_SetString( Py::_Exc_RuntimeError(), reason.c_str() );
|
||||
//}
|
||||
|
||||
|
||||
Exception( PyObject *exception, const std::string &reason )
|
||||
{
|
||||
PyErr_SetString( exception, reason.c_str() );
|
||||
}
|
||||
|
||||
Exception( PyObject *exception, Object &reason );
|
||||
|
||||
Exception( PyObject *exception, Object &reason );
|
||||
|
||||
void clear() // clear the error
|
||||
// technically but not philosophically const
|
||||
{
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
// is the exception this specific exception 'exc'
|
||||
bool matches( ExtensionExceptionType &exc );
|
||||
};
|
||||
|
||||
|
||||
|
||||
// for user defined exceptions to be made know to pycxx
|
||||
typedef void (*throw_exception_func_t)( void );
|
||||
void addPythonException( ExtensionExceptionType &py_exc_type, throw_exception_func_t throw_func );
|
||||
|
||||
// Abstract
|
||||
class PYCXX_EXPORT StandardError: public Exception
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
explicit StandardError()
|
||||
{}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT LookupError: public StandardError
|
||||
{
|
||||
protected:
|
||||
explicit LookupError()
|
||||
{}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT ArithmeticError: public StandardError
|
||||
{
|
||||
protected:
|
||||
explicit ArithmeticError()
|
||||
{}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT EnvironmentError: public StandardError
|
||||
{
|
||||
protected:
|
||||
explicit EnvironmentError()
|
||||
{}
|
||||
};
|
||||
|
||||
// Concrete
|
||||
|
||||
class PYCXX_EXPORT TypeError: public StandardError
|
||||
{
|
||||
public:
|
||||
TypeError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_TypeError(),reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT IndexError: public LookupError
|
||||
{
|
||||
public:
|
||||
IndexError (const std::string& reason)
|
||||
: LookupError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_IndexError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT AttributeError: public StandardError
|
||||
{
|
||||
public:
|
||||
AttributeError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_AttributeError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT NameError: public StandardError
|
||||
{
|
||||
public:
|
||||
NameError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_NameError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT RuntimeError: public StandardError
|
||||
{
|
||||
public:
|
||||
RuntimeError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_RuntimeError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class NotImplementedError: public StandardError
|
||||
{
|
||||
public:
|
||||
NotImplementedError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString (Py::_Exc_NotImplementedError(), reason.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT SystemError: public StandardError
|
||||
{
|
||||
public:
|
||||
SystemError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_SystemError(),reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT KeyError: public LookupError
|
||||
{
|
||||
public:
|
||||
KeyError (const std::string& reason)
|
||||
: LookupError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_KeyError(),reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PYCXX_EXPORT ValueError: public StandardError
|
||||
{
|
||||
public:
|
||||
ValueError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_ValueError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT OverflowError: public ArithmeticError
|
||||
{
|
||||
public:
|
||||
OverflowError (const std::string& reason)
|
||||
: ArithmeticError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_OverflowError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT ZeroDivisionError: public ArithmeticError
|
||||
{
|
||||
public:
|
||||
ZeroDivisionError (const std::string& reason)
|
||||
: ArithmeticError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_ZeroDivisionError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT FloatingPointError: public ArithmeticError
|
||||
{
|
||||
public:
|
||||
FloatingPointError (const std::string& reason)
|
||||
: ArithmeticError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_FloatingPointError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT MemoryError: public StandardError
|
||||
{
|
||||
public:
|
||||
MemoryError (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_MemoryError(), reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
class PYCXX_EXPORT SystemExit: public StandardError
|
||||
{
|
||||
public:
|
||||
SystemExit (const std::string& reason)
|
||||
: StandardError()
|
||||
{
|
||||
PyErr_SetString( Py::_Exc_SystemExit(),reason.c_str() );
|
||||
}
|
||||
};
|
||||
|
||||
#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \
|
||||
class PYCXX_EXPORT eclass : public bclass \
|
||||
{ \
|
||||
public: \
|
||||
eclass() {} \
|
||||
eclass( const char *reason ) { PyErr_SetString( _Exc_##eclass(), reason ); } \
|
||||
eclass( const std::string &reason ) { PyErr_SetString( _Exc_##eclass(), reason.c_str() ); } \
|
||||
~eclass() {} \
|
||||
\
|
||||
static void throwFunc() { throw eclass(); } \
|
||||
static PyObject *exceptionType() { return _Exc_##eclass(); } \
|
||||
}; \
|
||||
|
||||
#include <CXX/Python3/cxx_standard_exceptions.hxx>
|
||||
|
||||
#undef PYCXX_STANDARD_EXCEPTION
|
||||
}// Py
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
namespace Py
|
||||
{
|
||||
void ifPyErrorThrowCxxException();
|
||||
|
||||
typedef Py_ssize_t sequence_index_type; // type of an index into a sequence
|
||||
PYCXX_EXPORT Py_ssize_t numeric_limits_max();
|
||||
|
||||
@@ -3169,7 +3171,7 @@ namespace Py
|
||||
PyObject *result = PyObject_CallObject( ptr(), args.ptr() );
|
||||
if( result == NULL )
|
||||
{
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
}
|
||||
return asObject( result );
|
||||
}
|
||||
@@ -3184,7 +3186,7 @@ namespace Py
|
||||
#endif
|
||||
if( result == NULL )
|
||||
{
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
}
|
||||
return asObject( result );
|
||||
}
|
||||
|
||||
72
src/CXX/Python3/cxx_exceptions.cxx
Normal file
72
src/CXX/Python3/cxx_exceptions.cxx
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// cxx_exceptions.cxx
|
||||
//
|
||||
#include <CXX/Exception.hxx>
|
||||
#include <CXX/Extensions.hxx>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Py
|
||||
{
|
||||
typedef void (*throw_exception_func_t)( void );
|
||||
|
||||
std::map<void *, throw_exception_func_t> py_exc_type_to_exc_func;
|
||||
|
||||
void addPythonException( ExtensionExceptionType &py_exc_type, throw_exception_func_t func )
|
||||
{
|
||||
py_exc_type_to_exc_func.insert( std::make_pair( py_exc_type.ptr(), func ) );
|
||||
}
|
||||
|
||||
void addPythonException( PyObject *py_exc_type, throw_exception_func_t func )
|
||||
{
|
||||
py_exc_type_to_exc_func.insert( std::make_pair( py_exc_type, func ) );
|
||||
}
|
||||
|
||||
void ifPyErrorThrowCxxException()
|
||||
{
|
||||
if( PyErr_Occurred() )
|
||||
{
|
||||
PyObject *ptype, *pvalue, *ptrace;
|
||||
PyErr_Fetch( &ptype, &pvalue, &ptrace );
|
||||
PyErr_Restore( ptype, pvalue, ptrace );
|
||||
|
||||
Object q( ptype );
|
||||
|
||||
std::map<void *, throw_exception_func_t>::iterator func = py_exc_type_to_exc_func.find( ptype );
|
||||
if( func != py_exc_type_to_exc_func.end() )
|
||||
{
|
||||
#ifdef PYCXX_DEBUG
|
||||
std::cout << "ifPyErrorThrowCxxException found throwFunc: " << q << std::endl;
|
||||
#endif
|
||||
(func->second)();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PYCXX_DEBUG
|
||||
std::cout << "ifPyErrorThrowCxxException no throwFunc: " << q << std::endl;
|
||||
#endif
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initExceptions()
|
||||
{
|
||||
static bool init_done = false;
|
||||
if( init_done )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#define PYCXX_STANDARD_EXCEPTION( eclass, bclass ) \
|
||||
addPythonException( eclass::exceptionType(), eclass::throwFunc );
|
||||
|
||||
#include <CXX/Python3/cxx_standard_exceptions.hxx>
|
||||
|
||||
#undef PYCXX_STANDARD_EXCEPTION
|
||||
|
||||
init_done = true;
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Py
|
||||
@@ -36,6 +36,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "CXX/Extensions.hxx"
|
||||
#include "CXX/Exception.hxx"
|
||||
#include "CXX/Objects.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -77,10 +78,10 @@ void Object::validate()
|
||||
}
|
||||
#endif
|
||||
release();
|
||||
if( PyErr_Occurred() )
|
||||
{ // Error message already set
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
// If error message already set
|
||||
ifPyErrorThrowCxxException();
|
||||
|
||||
// Better error message if RTTI available
|
||||
#if defined( _CPPRTTI ) || defined( __GNUG__ )
|
||||
throw TypeError( s );
|
||||
@@ -183,8 +184,13 @@ public:
|
||||
ExtensionModuleBase *module;
|
||||
};
|
||||
|
||||
void initExceptions();
|
||||
|
||||
void ExtensionModuleBase::initialize( const char *module_doc )
|
||||
{
|
||||
// init the exception code
|
||||
initExceptions();
|
||||
|
||||
memset( &m_module_def, 0, sizeof( m_module_def ) );
|
||||
|
||||
m_module_def.m_name = const_cast<char *>( m_module_name.c_str() );
|
||||
@@ -1644,6 +1650,12 @@ void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::strin
|
||||
set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
|
||||
}
|
||||
|
||||
// is the exception this specific exception 'exc'
|
||||
bool Exception::matches( ExtensionExceptionType &exc )
|
||||
{
|
||||
return PyErr_ExceptionMatches( exc.ptr() ) != 0;
|
||||
}
|
||||
|
||||
ExtensionExceptionType::~ExtensionExceptionType()
|
||||
{
|
||||
}
|
||||
|
||||
21
src/CXX/Python3/cxx_standard_exceptions.hxx
Normal file
21
src/CXX/Python3/cxx_standard_exceptions.hxx
Normal file
@@ -0,0 +1,21 @@
|
||||
#if !defined( PYCXX_STANDARD_EXCEPTION )
|
||||
#pragma error( "define PYCXX_STANDARD_EXCEPTION before including" )
|
||||
#endif
|
||||
|
||||
PYCXX_STANDARD_EXCEPTION( LookupError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( ArithmeticError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( EnvironmentError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( TypeError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( IndexError, LookupError )
|
||||
PYCXX_STANDARD_EXCEPTION( AttributeError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( NameError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( RuntimeError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( NotImplementedError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( SystemError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( KeyError, LookupError )
|
||||
PYCXX_STANDARD_EXCEPTION( ValueError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( OverflowError, ArithmeticError )
|
||||
PYCXX_STANDARD_EXCEPTION( ZeroDivisionError, ArithmeticError )
|
||||
PYCXX_STANDARD_EXCEPTION( FloatingPointError, ArithmeticError )
|
||||
PYCXX_STANDARD_EXCEPTION( MemoryError, StandardError )
|
||||
PYCXX_STANDARD_EXCEPTION( SystemExit, StandardError )
|
||||
@@ -91,48 +91,42 @@ String Bytes::decode( const char *encoding, const char *error )
|
||||
bool operator==( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_EQ );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
bool operator!=( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_NE );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
bool operator>=( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_GE );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
bool operator<=( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_LE );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
bool operator<( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_LT );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
bool operator>( const Object &o1, const Object &o2 )
|
||||
{
|
||||
int k = PyObject_RichCompareBool( *o1, *o2, Py_GT );
|
||||
if( PyErr_Occurred() )
|
||||
throw Exception();
|
||||
ifPyErrorThrowCxxException();
|
||||
return k != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#define __PyCXX_version_hxx__
|
||||
|
||||
#define PYCXX_VERSION_MAJOR 6
|
||||
#define PYCXX_VERSION_MINOR 2
|
||||
#define PYCXX_VERSION_PATCH 8
|
||||
#define PYCXX_VERSION_MINOR 3
|
||||
#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 )
|
||||
#endif
|
||||
|
||||
7
src/CXX/cxx_exceptions.cxx
Normal file
7
src/CXX/cxx_exceptions.cxx
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "CXX/WrapPython.h"
|
||||
|
||||
#if PY_MAJOR_VERSION == 2
|
||||
#include "Python2/cxx_exceptions.cxx"
|
||||
#else
|
||||
#include "Python3/cxx_exceptions.cxx"
|
||||
#endif
|
||||
Reference in New Issue
Block a user