Skip to content

Commit

Permalink
PyCXX: update to version 6.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Aug 1, 2022
1 parent c6ddc47 commit 0461579
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 194 deletions.
2 changes: 1 addition & 1 deletion cMake/FindPyCXX.cmake
Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions src/CXX/Python3/Config.hxx
Expand Up @@ -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
Expand Down
200 changes: 29 additions & 171 deletions src/CXX/Python3/Exception.hxx
Expand Up @@ -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
6 changes: 4 additions & 2 deletions src/CXX/Python3/Objects.hxx
Expand Up @@ -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();

Expand Down Expand Up @@ -3169,7 +3171,7 @@ namespace Py
PyObject *result = PyObject_CallObject( ptr(), args.ptr() );
if( result == NULL )
{
throw Exception();
ifPyErrorThrowCxxException();
}
return asObject( result );
}
Expand All @@ -3184,7 +3186,7 @@ namespace Py
#endif
if( result == NULL )
{
throw Exception();
ifPyErrorThrowCxxException();
}
return asObject( result );
}
Expand Down
72 changes: 72 additions & 0 deletions src/CXX/Python3/cxx_exceptions.cxx
@@ -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

0 comments on commit 0461579

Please sign in to comment.