815 lines
27 KiB
C
815 lines
27 KiB
C
|
// Exception raising code
|
||
|
//
|
||
|
// Exceptions are raised by __Pyx_Raise() and stored as plain
|
||
|
// type/value/tb in PyThreadState->curexc_*. When being caught by an
|
||
|
// 'except' statement, curexc_* is moved over to exc_* by
|
||
|
// __Pyx_GetException()
|
||
|
|
||
|
|
||
|
/////////////// PyThreadStateGet.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_PyThreadState_declare PyThreadState *$local_tstate_cname;
|
||
|
#define __Pyx_PyThreadState_assign $local_tstate_cname = __Pyx_PyThreadState_Current;
|
||
|
#define __Pyx_PyErr_Occurred() $local_tstate_cname->curexc_type
|
||
|
#else
|
||
|
#define __Pyx_PyThreadState_declare
|
||
|
#define __Pyx_PyThreadState_assign
|
||
|
#define __Pyx_PyErr_Occurred() PyErr_Occurred()
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/////////////// PyErrExceptionMatches.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState($local_tstate_cname, err)
|
||
|
static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err);
|
||
|
#else
|
||
|
#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err)
|
||
|
#endif
|
||
|
|
||
|
/////////////// PyErrExceptionMatches ///////////////
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) {
|
||
|
Py_ssize_t i, n;
|
||
|
n = PyTuple_GET_SIZE(tuple);
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
// the tighter subtype checking in Py3 allows faster out-of-order comparison
|
||
|
for (i=0; i<n; i++) {
|
||
|
if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
|
||
|
}
|
||
|
#endif
|
||
|
for (i=0; i<n; i++) {
|
||
|
if (__Pyx_PyErr_GivenExceptionMatches(exc_type, PyTuple_GET_ITEM(tuple, i))) return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) {
|
||
|
PyObject *exc_type = tstate->curexc_type;
|
||
|
if (exc_type == err) return 1;
|
||
|
if (unlikely(!exc_type)) return 0;
|
||
|
if (unlikely(PyTuple_Check(err)))
|
||
|
return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err);
|
||
|
return __Pyx_PyErr_GivenExceptionMatches(exc_type, err);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/////////////// PyErrFetchRestore.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL)
|
||
|
#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb)
|
||
|
#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb)
|
||
|
#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState($local_tstate_cname, type, value, tb)
|
||
|
#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState($local_tstate_cname, type, value, tb)
|
||
|
static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); /*proto*/
|
||
|
static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
|
||
|
#if CYTHON_COMPILING_IN_CPYTHON
|
||
|
#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL))
|
||
|
#else
|
||
|
#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
|
||
|
#endif
|
||
|
|
||
|
#else
|
||
|
#define __Pyx_PyErr_Clear() PyErr_Clear()
|
||
|
#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
|
||
|
#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb)
|
||
|
#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb)
|
||
|
#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb)
|
||
|
#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb)
|
||
|
#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb)
|
||
|
#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb)
|
||
|
#endif
|
||
|
|
||
|
/////////////// PyErrFetchRestore ///////////////
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
tmp_type = tstate->curexc_type;
|
||
|
tmp_value = tstate->curexc_value;
|
||
|
tmp_tb = tstate->curexc_traceback;
|
||
|
tstate->curexc_type = type;
|
||
|
tstate->curexc_value = value;
|
||
|
tstate->curexc_traceback = tb;
|
||
|
Py_XDECREF(tmp_type);
|
||
|
Py_XDECREF(tmp_value);
|
||
|
Py_XDECREF(tmp_tb);
|
||
|
}
|
||
|
|
||
|
static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
|
||
|
*type = tstate->curexc_type;
|
||
|
*value = tstate->curexc_value;
|
||
|
*tb = tstate->curexc_traceback;
|
||
|
tstate->curexc_type = 0;
|
||
|
tstate->curexc_value = 0;
|
||
|
tstate->curexc_traceback = 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/////////////// RaiseException.proto ///////////////
|
||
|
|
||
|
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
|
||
|
|
||
|
/////////////// RaiseException ///////////////
|
||
|
//@requires: PyErrFetchRestore
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
// The following function is based on do_raise() from ceval.c. There
|
||
|
// are separate versions for Python2 and Python3 as exception handling
|
||
|
// has changed quite a lot between the two versions.
|
||
|
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
|
||
|
CYTHON_UNUSED PyObject *cause) {
|
||
|
__Pyx_PyThreadState_declare
|
||
|
/* 'cause' is only used in Py3 */
|
||
|
Py_XINCREF(type);
|
||
|
if (!value || value == Py_None)
|
||
|
value = NULL;
|
||
|
else
|
||
|
Py_INCREF(value);
|
||
|
|
||
|
if (!tb || tb == Py_None)
|
||
|
tb = NULL;
|
||
|
else {
|
||
|
Py_INCREF(tb);
|
||
|
if (!PyTraceBack_Check(tb)) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"raise: arg 3 must be a traceback or None");
|
||
|
goto raise_error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (PyType_Check(type)) {
|
||
|
/* instantiate the type now (we don't know when and how it will be caught) */
|
||
|
#if CYTHON_COMPILING_IN_PYPY
|
||
|
/* PyPy can't handle value == NULL */
|
||
|
if (!value) {
|
||
|
Py_INCREF(Py_None);
|
||
|
value = Py_None;
|
||
|
}
|
||
|
#endif
|
||
|
PyErr_NormalizeException(&type, &value, &tb);
|
||
|
|
||
|
} else {
|
||
|
/* Raising an instance. The value should be a dummy. */
|
||
|
if (value) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"instance exception may not have a separate value");
|
||
|
goto raise_error;
|
||
|
}
|
||
|
/* Normalize to raise <class>, <instance> */
|
||
|
value = type;
|
||
|
type = (PyObject*) Py_TYPE(type);
|
||
|
Py_INCREF(type);
|
||
|
if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"raise: exception class must be a subclass of BaseException");
|
||
|
goto raise_error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
__Pyx_PyThreadState_assign
|
||
|
__Pyx_ErrRestore(type, value, tb);
|
||
|
return;
|
||
|
raise_error:
|
||
|
Py_XDECREF(value);
|
||
|
Py_XDECREF(type);
|
||
|
Py_XDECREF(tb);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#else /* Python 3+ */
|
||
|
|
||
|
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
|
||
|
PyObject* owned_instance = NULL;
|
||
|
if (tb == Py_None) {
|
||
|
tb = 0;
|
||
|
} else if (tb && !PyTraceBack_Check(tb)) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"raise: arg 3 must be a traceback or None");
|
||
|
goto bad;
|
||
|
}
|
||
|
if (value == Py_None)
|
||
|
value = 0;
|
||
|
|
||
|
if (PyExceptionInstance_Check(type)) {
|
||
|
if (value) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"instance exception may not have a separate value");
|
||
|
goto bad;
|
||
|
}
|
||
|
value = type;
|
||
|
type = (PyObject*) Py_TYPE(value);
|
||
|
} else if (PyExceptionClass_Check(type)) {
|
||
|
// make sure value is an exception instance of type
|
||
|
PyObject *instance_class = NULL;
|
||
|
if (value && PyExceptionInstance_Check(value)) {
|
||
|
instance_class = (PyObject*) Py_TYPE(value);
|
||
|
if (instance_class != type) {
|
||
|
int is_subclass = PyObject_IsSubclass(instance_class, type);
|
||
|
if (!is_subclass) {
|
||
|
instance_class = NULL;
|
||
|
} else if (unlikely(is_subclass == -1)) {
|
||
|
// error on subclass test
|
||
|
goto bad;
|
||
|
} else {
|
||
|
// believe the instance
|
||
|
type = instance_class;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!instance_class) {
|
||
|
// instantiate the type now (we don't know when and how it will be caught)
|
||
|
// assuming that 'value' is an argument to the type's constructor
|
||
|
// not using PyErr_NormalizeException() to avoid ref-counting problems
|
||
|
PyObject *args;
|
||
|
if (!value)
|
||
|
args = PyTuple_New(0);
|
||
|
else if (PyTuple_Check(value)) {
|
||
|
Py_INCREF(value);
|
||
|
args = value;
|
||
|
} else
|
||
|
args = PyTuple_Pack(1, value);
|
||
|
if (!args)
|
||
|
goto bad;
|
||
|
owned_instance = PyObject_Call(type, args, NULL);
|
||
|
Py_DECREF(args);
|
||
|
if (!owned_instance)
|
||
|
goto bad;
|
||
|
value = owned_instance;
|
||
|
if (!PyExceptionInstance_Check(value)) {
|
||
|
PyErr_Format(PyExc_TypeError,
|
||
|
"calling %R should have returned an instance of "
|
||
|
"BaseException, not %R",
|
||
|
type, Py_TYPE(value));
|
||
|
goto bad;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"raise: exception class must be a subclass of BaseException");
|
||
|
goto bad;
|
||
|
}
|
||
|
|
||
|
if (cause) {
|
||
|
PyObject *fixed_cause;
|
||
|
if (cause == Py_None) {
|
||
|
// raise ... from None
|
||
|
fixed_cause = NULL;
|
||
|
} else if (PyExceptionClass_Check(cause)) {
|
||
|
fixed_cause = PyObject_CallObject(cause, NULL);
|
||
|
if (fixed_cause == NULL)
|
||
|
goto bad;
|
||
|
} else if (PyExceptionInstance_Check(cause)) {
|
||
|
fixed_cause = cause;
|
||
|
Py_INCREF(fixed_cause);
|
||
|
} else {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"exception causes must derive from "
|
||
|
"BaseException");
|
||
|
goto bad;
|
||
|
}
|
||
|
PyException_SetCause(value, fixed_cause);
|
||
|
}
|
||
|
|
||
|
PyErr_SetObject(type, value);
|
||
|
|
||
|
if (tb) {
|
||
|
#if CYTHON_COMPILING_IN_PYPY
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb);
|
||
|
Py_INCREF(tb);
|
||
|
PyErr_Restore(tmp_type, tmp_value, tb);
|
||
|
Py_XDECREF(tmp_tb);
|
||
|
#else
|
||
|
PyThreadState *tstate = __Pyx_PyThreadState_Current;
|
||
|
PyObject* tmp_tb = tstate->curexc_traceback;
|
||
|
if (tb != tmp_tb) {
|
||
|
Py_INCREF(tb);
|
||
|
tstate->curexc_traceback = tb;
|
||
|
Py_XDECREF(tmp_tb);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bad:
|
||
|
Py_XDECREF(owned_instance);
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/////////////// GetTopmostException.proto ///////////////
|
||
|
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate);
|
||
|
#endif
|
||
|
|
||
|
/////////////// GetTopmostException ///////////////
|
||
|
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
// Copied from errors.c in CPython.
|
||
|
static _PyErr_StackItem *
|
||
|
__Pyx_PyErr_GetTopmostException(PyThreadState *tstate)
|
||
|
{
|
||
|
_PyErr_StackItem *exc_info = tstate->exc_info;
|
||
|
while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
|
||
|
exc_info->previous_item != NULL)
|
||
|
{
|
||
|
exc_info = exc_info->previous_item;
|
||
|
}
|
||
|
return exc_info;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/////////////// GetException.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_GetException(type, value, tb) __Pyx__GetException($local_tstate_cname, type, value, tb)
|
||
|
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
#else
|
||
|
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
#endif
|
||
|
|
||
|
/////////////// GetException ///////////////
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb)
|
||
|
#else
|
||
|
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
|
||
|
#endif
|
||
|
{
|
||
|
PyObject *local_type, *local_value, *local_tb;
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
local_type = tstate->curexc_type;
|
||
|
local_value = tstate->curexc_value;
|
||
|
local_tb = tstate->curexc_traceback;
|
||
|
tstate->curexc_type = 0;
|
||
|
tstate->curexc_value = 0;
|
||
|
tstate->curexc_traceback = 0;
|
||
|
#else
|
||
|
PyErr_Fetch(&local_type, &local_value, &local_tb);
|
||
|
#endif
|
||
|
PyErr_NormalizeException(&local_type, &local_value, &local_tb);
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
if (unlikely(tstate->curexc_type))
|
||
|
#else
|
||
|
if (unlikely(PyErr_Occurred()))
|
||
|
#endif
|
||
|
goto bad;
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
if (local_tb) {
|
||
|
if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
|
||
|
goto bad;
|
||
|
}
|
||
|
#endif
|
||
|
// traceback may be NULL for freshly raised exceptions
|
||
|
Py_XINCREF(local_tb);
|
||
|
// exception state may be temporarily empty in parallel loops (race condition)
|
||
|
Py_XINCREF(local_type);
|
||
|
Py_XINCREF(local_value);
|
||
|
*type = local_type;
|
||
|
*value = local_value;
|
||
|
*tb = local_tb;
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
{
|
||
|
_PyErr_StackItem *exc_info = tstate->exc_info;
|
||
|
tmp_type = exc_info->exc_type;
|
||
|
tmp_value = exc_info->exc_value;
|
||
|
tmp_tb = exc_info->exc_traceback;
|
||
|
exc_info->exc_type = local_type;
|
||
|
exc_info->exc_value = local_value;
|
||
|
exc_info->exc_traceback = local_tb;
|
||
|
}
|
||
|
#else
|
||
|
tmp_type = tstate->exc_type;
|
||
|
tmp_value = tstate->exc_value;
|
||
|
tmp_tb = tstate->exc_traceback;
|
||
|
tstate->exc_type = local_type;
|
||
|
tstate->exc_value = local_value;
|
||
|
tstate->exc_traceback = local_tb;
|
||
|
#endif
|
||
|
// Make sure tstate is in a consistent state when we XDECREF
|
||
|
// these objects (DECREF may run arbitrary code).
|
||
|
Py_XDECREF(tmp_type);
|
||
|
Py_XDECREF(tmp_value);
|
||
|
Py_XDECREF(tmp_tb);
|
||
|
#else
|
||
|
PyErr_SetExcInfo(local_type, local_value, local_tb);
|
||
|
#endif
|
||
|
return 0;
|
||
|
bad:
|
||
|
*type = 0;
|
||
|
*value = 0;
|
||
|
*tb = 0;
|
||
|
Py_XDECREF(local_type);
|
||
|
Py_XDECREF(local_value);
|
||
|
Py_XDECREF(local_tb);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/////////////// ReRaiseException.proto ///////////////
|
||
|
|
||
|
static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/
|
||
|
|
||
|
/////////////// ReRaiseException ///////////////
|
||
|
//@requires: GetTopmostException
|
||
|
|
||
|
static CYTHON_INLINE void __Pyx_ReraiseException(void) {
|
||
|
PyObject *type = NULL, *value = NULL, *tb = NULL;
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
PyThreadState *tstate = PyThreadState_GET();
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
_PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
|
||
|
type = exc_info->exc_type;
|
||
|
value = exc_info->exc_value;
|
||
|
tb = exc_info->exc_traceback;
|
||
|
#else
|
||
|
type = tstate->exc_type;
|
||
|
value = tstate->exc_value;
|
||
|
tb = tstate->exc_traceback;
|
||
|
#endif
|
||
|
#else
|
||
|
PyErr_GetExcInfo(&type, &value, &tb);
|
||
|
#endif
|
||
|
if (!type || type == Py_None) {
|
||
|
#if !CYTHON_FAST_THREAD_STATE
|
||
|
Py_XDECREF(type);
|
||
|
Py_XDECREF(value);
|
||
|
Py_XDECREF(tb);
|
||
|
#endif
|
||
|
// message copied from Py3
|
||
|
PyErr_SetString(PyExc_RuntimeError,
|
||
|
"No active exception to reraise");
|
||
|
} else {
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
Py_INCREF(type);
|
||
|
Py_XINCREF(value);
|
||
|
Py_XINCREF(tb);
|
||
|
|
||
|
#endif
|
||
|
PyErr_Restore(type, value, tb);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////// SaveResetException.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave($local_tstate_cname, type, value, tb)
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset($local_tstate_cname, type, value, tb)
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); /*proto*/
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb)
|
||
|
#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb)
|
||
|
#endif
|
||
|
|
||
|
/////////////// SaveResetException ///////////////
|
||
|
//@requires: GetTopmostException
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
_PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
|
||
|
*type = exc_info->exc_type;
|
||
|
*value = exc_info->exc_value;
|
||
|
*tb = exc_info->exc_traceback;
|
||
|
#else
|
||
|
*type = tstate->exc_type;
|
||
|
*value = tstate->exc_value;
|
||
|
*tb = tstate->exc_traceback;
|
||
|
#endif
|
||
|
Py_XINCREF(*type);
|
||
|
Py_XINCREF(*value);
|
||
|
Py_XINCREF(*tb);
|
||
|
}
|
||
|
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
_PyErr_StackItem *exc_info = tstate->exc_info;
|
||
|
tmp_type = exc_info->exc_type;
|
||
|
tmp_value = exc_info->exc_value;
|
||
|
tmp_tb = exc_info->exc_traceback;
|
||
|
exc_info->exc_type = type;
|
||
|
exc_info->exc_value = value;
|
||
|
exc_info->exc_traceback = tb;
|
||
|
#else
|
||
|
tmp_type = tstate->exc_type;
|
||
|
tmp_value = tstate->exc_value;
|
||
|
tmp_tb = tstate->exc_traceback;
|
||
|
tstate->exc_type = type;
|
||
|
tstate->exc_value = value;
|
||
|
tstate->exc_traceback = tb;
|
||
|
#endif
|
||
|
Py_XDECREF(tmp_type);
|
||
|
Py_XDECREF(tmp_value);
|
||
|
Py_XDECREF(tmp_tb);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/////////////// SwapException.proto ///////////////
|
||
|
//@substitute: naming
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap($local_tstate_cname, type, value, tb)
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
#else
|
||
|
static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
|
||
|
#endif
|
||
|
|
||
|
/////////////// SwapException ///////////////
|
||
|
|
||
|
#if CYTHON_FAST_THREAD_STATE
|
||
|
static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
|
||
|
#if CYTHON_USE_EXC_INFO_STACK
|
||
|
_PyErr_StackItem *exc_info = tstate->exc_info;
|
||
|
tmp_type = exc_info->exc_type;
|
||
|
tmp_value = exc_info->exc_value;
|
||
|
tmp_tb = exc_info->exc_traceback;
|
||
|
|
||
|
exc_info->exc_type = *type;
|
||
|
exc_info->exc_value = *value;
|
||
|
exc_info->exc_traceback = *tb;
|
||
|
#else
|
||
|
tmp_type = tstate->exc_type;
|
||
|
tmp_value = tstate->exc_value;
|
||
|
tmp_tb = tstate->exc_traceback;
|
||
|
|
||
|
tstate->exc_type = *type;
|
||
|
tstate->exc_value = *value;
|
||
|
tstate->exc_traceback = *tb;
|
||
|
#endif
|
||
|
|
||
|
*type = tmp_type;
|
||
|
*value = tmp_value;
|
||
|
*tb = tmp_tb;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
|
||
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||
|
PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
|
||
|
PyErr_SetExcInfo(*type, *value, *tb);
|
||
|
*type = tmp_type;
|
||
|
*value = tmp_value;
|
||
|
*tb = tmp_tb;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/////////////// WriteUnraisableException.proto ///////////////
|
||
|
|
||
|
static void __Pyx_WriteUnraisable(const char *name, int clineno,
|
||
|
int lineno, const char *filename,
|
||
|
int full_traceback, int nogil); /*proto*/
|
||
|
|
||
|
/////////////// WriteUnraisableException ///////////////
|
||
|
//@requires: PyErrFetchRestore
|
||
|
//@requires: PyThreadStateGet
|
||
|
|
||
|
static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
|
||
|
CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
|
||
|
int full_traceback, CYTHON_UNUSED int nogil) {
|
||
|
PyObject *old_exc, *old_val, *old_tb;
|
||
|
PyObject *ctx;
|
||
|
__Pyx_PyThreadState_declare
|
||
|
#ifdef WITH_THREAD
|
||
|
PyGILState_STATE state;
|
||
|
if (nogil)
|
||
|
state = PyGILState_Ensure();
|
||
|
/* initalize to suppress warning */
|
||
|
else state = (PyGILState_STATE)0;
|
||
|
#endif
|
||
|
__Pyx_PyThreadState_assign
|
||
|
__Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
|
||
|
if (full_traceback) {
|
||
|
Py_XINCREF(old_exc);
|
||
|
Py_XINCREF(old_val);
|
||
|
Py_XINCREF(old_tb);
|
||
|
__Pyx_ErrRestore(old_exc, old_val, old_tb);
|
||
|
PyErr_PrintEx(1);
|
||
|
}
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
ctx = PyString_FromString(name);
|
||
|
#else
|
||
|
ctx = PyUnicode_FromString(name);
|
||
|
#endif
|
||
|
__Pyx_ErrRestore(old_exc, old_val, old_tb);
|
||
|
if (!ctx) {
|
||
|
PyErr_WriteUnraisable(Py_None);
|
||
|
} else {
|
||
|
PyErr_WriteUnraisable(ctx);
|
||
|
Py_DECREF(ctx);
|
||
|
}
|
||
|
#ifdef WITH_THREAD
|
||
|
if (nogil)
|
||
|
PyGILState_Release(state);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/////////////// CLineInTraceback.proto ///////////////
|
||
|
|
||
|
#ifdef CYTHON_CLINE_IN_TRACEBACK /* 0 or 1 to disable/enable C line display in tracebacks at C compile time */
|
||
|
#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0)
|
||
|
#else
|
||
|
static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line);/*proto*/
|
||
|
#endif
|
||
|
|
||
|
/////////////// CLineInTraceback ///////////////
|
||
|
//@requires: ObjectHandling.c::PyObjectGetAttrStr
|
||
|
//@requires: ObjectHandling.c::PyDictVersioning
|
||
|
//@requires: PyErrFetchRestore
|
||
|
//@substitute: naming
|
||
|
|
||
|
#ifndef CYTHON_CLINE_IN_TRACEBACK
|
||
|
static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) {
|
||
|
PyObject *use_cline;
|
||
|
PyObject *ptype, *pvalue, *ptraceback;
|
||
|
#if CYTHON_COMPILING_IN_CPYTHON
|
||
|
PyObject **cython_runtime_dict;
|
||
|
#endif
|
||
|
|
||
|
if (unlikely(!${cython_runtime_cname})) {
|
||
|
// Very early error where the runtime module is not set up yet.
|
||
|
return c_line;
|
||
|
}
|
||
|
|
||
|
__Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback);
|
||
|
|
||
|
#if CYTHON_COMPILING_IN_CPYTHON
|
||
|
cython_runtime_dict = _PyObject_GetDictPtr(${cython_runtime_cname});
|
||
|
if (likely(cython_runtime_dict)) {
|
||
|
__PYX_PY_DICT_LOOKUP_IF_MODIFIED(
|
||
|
use_cline, *cython_runtime_dict,
|
||
|
__Pyx_PyDict_GetItemStr(*cython_runtime_dict, PYIDENT("cline_in_traceback")))
|
||
|
} else
|
||
|
#endif
|
||
|
{
|
||
|
PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
|
||
|
if (use_cline_obj) {
|
||
|
use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True;
|
||
|
Py_DECREF(use_cline_obj);
|
||
|
} else {
|
||
|
PyErr_Clear();
|
||
|
use_cline = NULL;
|
||
|
}
|
||
|
}
|
||
|
if (!use_cline) {
|
||
|
c_line = 0;
|
||
|
// No need to handle errors here when we reset the exception state just afterwards.
|
||
|
(void) PyObject_SetAttr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"), Py_False);
|
||
|
}
|
||
|
else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) {
|
||
|
c_line = 0;
|
||
|
}
|
||
|
__Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback);
|
||
|
return c_line;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/////////////// AddTraceback.proto ///////////////
|
||
|
|
||
|
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
||
|
int py_line, const char *filename); /*proto*/
|
||
|
|
||
|
/////////////// AddTraceback ///////////////
|
||
|
//@requires: ModuleSetupCode.c::CodeObjectCache
|
||
|
//@requires: CLineInTraceback
|
||
|
//@substitute: naming
|
||
|
|
||
|
#include "compile.h"
|
||
|
#include "frameobject.h"
|
||
|
#include "traceback.h"
|
||
|
#if PY_VERSION_HEX >= 0x030b00a6
|
||
|
#ifndef Py_BUILD_CORE
|
||
|
#define Py_BUILD_CORE 1
|
||
|
#endif
|
||
|
#include "internal/pycore_frame.h"
|
||
|
#endif
|
||
|
|
||
|
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
||
|
const char *funcname, int c_line,
|
||
|
int py_line, const char *filename) {
|
||
|
PyCodeObject *py_code = NULL;
|
||
|
PyObject *py_funcname = NULL;
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
PyObject *py_srcfile = NULL;
|
||
|
|
||
|
py_srcfile = PyString_FromString(filename);
|
||
|
if (!py_srcfile) goto bad;
|
||
|
#endif
|
||
|
|
||
|
if (c_line) {
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line);
|
||
|
if (!py_funcname) goto bad;
|
||
|
#else
|
||
|
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line);
|
||
|
if (!py_funcname) goto bad;
|
||
|
funcname = PyUnicode_AsUTF8(py_funcname);
|
||
|
if (!funcname) goto bad;
|
||
|
#endif
|
||
|
}
|
||
|
else {
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
py_funcname = PyString_FromString(funcname);
|
||
|
if (!py_funcname) goto bad;
|
||
|
#endif
|
||
|
}
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
py_code = __Pyx_PyCode_New(
|
||
|
0, /*int argcount,*/
|
||
|
0, /*int kwonlyargcount,*/
|
||
|
0, /*int nlocals,*/
|
||
|
0, /*int stacksize,*/
|
||
|
0, /*int flags,*/
|
||
|
$empty_bytes, /*PyObject *code,*/
|
||
|
$empty_tuple, /*PyObject *consts,*/
|
||
|
$empty_tuple, /*PyObject *names,*/
|
||
|
$empty_tuple, /*PyObject *varnames,*/
|
||
|
$empty_tuple, /*PyObject *freevars,*/
|
||
|
$empty_tuple, /*PyObject *cellvars,*/
|
||
|
py_srcfile, /*PyObject *filename,*/
|
||
|
py_funcname, /*PyObject *name,*/
|
||
|
py_line, /*int firstlineno,*/
|
||
|
$empty_bytes /*PyObject *lnotab*/
|
||
|
);
|
||
|
Py_DECREF(py_srcfile);
|
||
|
#else
|
||
|
py_code = PyCode_NewEmpty(filename, funcname, py_line);
|
||
|
#endif
|
||
|
Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline
|
||
|
return py_code;
|
||
|
bad:
|
||
|
Py_XDECREF(py_funcname);
|
||
|
#if PY_MAJOR_VERSION < 3
|
||
|
Py_XDECREF(py_srcfile);
|
||
|
#endif
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
||
|
int py_line, const char *filename) {
|
||
|
PyCodeObject *py_code = 0;
|
||
|
PyFrameObject *py_frame = 0;
|
||
|
PyThreadState *tstate = __Pyx_PyThreadState_Current;
|
||
|
PyObject *ptype, *pvalue, *ptraceback;
|
||
|
|
||
|
if (c_line) {
|
||
|
c_line = __Pyx_CLineForTraceback(tstate, c_line);
|
||
|
}
|
||
|
|
||
|
// Negate to avoid collisions between py and c lines.
|
||
|
py_code = $global_code_object_cache_find(c_line ? -c_line : py_line);
|
||
|
if (!py_code) {
|
||
|
__Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback);
|
||
|
py_code = __Pyx_CreateCodeObjectForTraceback(
|
||
|
funcname, c_line, py_line, filename);
|
||
|
if (!py_code) {
|
||
|
/* If the code object creation fails, then we should clear the
|
||
|
fetched exception references and propagate the new exception */
|
||
|
Py_XDECREF(ptype);
|
||
|
Py_XDECREF(pvalue);
|
||
|
Py_XDECREF(ptraceback);
|
||
|
goto bad;
|
||
|
}
|
||
|
__Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback);
|
||
|
$global_code_object_cache_insert(c_line ? -c_line : py_line, py_code);
|
||
|
}
|
||
|
py_frame = PyFrame_New(
|
||
|
tstate, /*PyThreadState *tstate,*/
|
||
|
py_code, /*PyCodeObject *code,*/
|
||
|
$moddict_cname, /*PyObject *globals,*/
|
||
|
0 /*PyObject *locals*/
|
||
|
);
|
||
|
if (!py_frame) goto bad;
|
||
|
__Pyx_PyFrame_SetLineNumber(py_frame, py_line);
|
||
|
PyTraceBack_Here(py_frame);
|
||
|
bad:
|
||
|
Py_XDECREF(py_code);
|
||
|
Py_XDECREF(py_frame);
|
||
|
}
|