PyCXX: update to version 6.3.0

This commit is contained in:
wmayer
2022-08-01 14:53:23 +02:00
parent a45a787b4e
commit 739b59ff2d
10 changed files with 165 additions and 194 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 );
}

View 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

View File

@@ -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()
{
}

View 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 )

View File

@@ -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;
}

View File

@@ -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

View 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