summaryrefslogtreecommitdiff
path: root/Cython/Utility/Exceptions.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Utility/Exceptions.c')
-rw-r--r--Cython/Utility/Exceptions.c187
1 files changed, 154 insertions, 33 deletions
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index 87d3a5cdd..abf95afda 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -6,6 +6,49 @@
// __Pyx_GetException()
+/////////////// AssertionsEnabled.init ///////////////
+__Pyx_init_assertions_enabled();
+
+/////////////// AssertionsEnabled.proto ///////////////
+
+#define __Pyx_init_assertions_enabled()
+
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
+ #define __pyx_assertions_enabled() (1)
+#elif PY_VERSION_HEX < 0x03080000 || CYTHON_COMPILING_IN_PYPY || defined(Py_LIMITED_API)
+ #define __pyx_assertions_enabled() (!Py_OptimizeFlag)
+#elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030900A6
+ // Py3.8+ has PyConfig from PEP 587, but only Py3.9 added read access to it.
+ // Py_OptimizeFlag is deprecated in Py3.12+
+ static int __pyx_assertions_enabled_flag;
+ #define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag)
+
+ #undef __Pyx_init_assertions_enabled
+ static void __Pyx_init_assertions_enabled(void) {
+ __pyx_assertions_enabled_flag = ! _PyInterpreterState_GetConfig(__Pyx_PyThreadState_Current->interp)->optimization_level;
+ }
+#else
+ #define __pyx_assertions_enabled() (!Py_OptimizeFlag)
+#endif
+
+
+/////////////// ErrOccurredWithGIL.proto ///////////////
+static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
+
+/////////////// ErrOccurredWithGIL ///////////////
+static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
+ int err;
+ #ifdef WITH_THREAD
+ PyGILState_STATE _save = PyGILState_Ensure();
+ #endif
+ err = !!PyErr_Occurred();
+ #ifdef WITH_THREAD
+ PyGILState_Release(_save);
+ #endif
+ return err;
+}
+
+
/////////////// PyThreadStateGet.proto ///////////////
//@substitute: naming
@@ -127,9 +170,9 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
// 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) {
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
__Pyx_PyThreadState_declare
+ CYTHON_UNUSED_VAR(cause);
/* 'cause' is only used in Py3 */
Py_XINCREF(type);
if (!value || value == Py_None)
@@ -310,19 +353,19 @@ bad:
/////////////// GetTopmostException.proto ///////////////
-#if CYTHON_USE_EXC_INFO_STACK
+#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE
static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate);
#endif
/////////////// GetTopmostException ///////////////
-#if CYTHON_USE_EXC_INFO_STACK
+#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE
// 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) &&
+ while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) &&
exc_info->previous_item != NULL)
{
exc_info = exc_info->previous_item;
@@ -388,12 +431,21 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
#if CYTHON_USE_EXC_INFO_STACK
{
_PyErr_StackItem *exc_info = tstate->exc_info;
+ #if PY_VERSION_HEX >= 0x030B00a4
+ tmp_value = exc_info->exc_value;
+ exc_info->exc_value = local_value;
+ tmp_type = NULL;
+ tmp_tb = NULL;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_tb);
+ #else
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;
+ #endif
}
#else
tmp_type = tstate->exc_type;
@@ -433,35 +485,44 @@ 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
+ #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;
+ #if PY_VERSION_HEX >= 0x030B00a4
+ if (unlikely(value == Py_None)) {
+ value = NULL;
+ } else if (value) {
+ Py_INCREF(value);
+ type = (PyObject*) Py_TYPE(value);
+ Py_INCREF(type);
+ tb = PyException_GetTraceback(value);
+ }
#else
+ type = exc_info->exc_type;
+ tb = exc_info->exc_traceback;
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ #endif
+ #else
type = tstate->exc_type;
value = tstate->exc_value;
tb = tstate->exc_traceback;
- #endif
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ #endif
#else
PyErr_GetExcInfo(&type, &value, &tb);
#endif
- if (!type || type == Py_None) {
-#if !CYTHON_FAST_THREAD_STATE
+ if (unlikely(!type || type == Py_None)) {
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);
}
}
@@ -487,24 +548,49 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
#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
+ #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4
+ _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
+ PyObject *exc_value = exc_info->exc_value;
+ if (exc_value == NULL || exc_value == Py_None) {
+ *value = NULL;
+ *type = NULL;
+ *tb = NULL;
+ } else {
+ *value = exc_value;
+ Py_INCREF(*value);
+ *type = (PyObject*) Py_TYPE(exc_value);
+ Py_INCREF(*type);
+ *tb = PyException_GetTraceback(exc_value);
+ }
+ #elif 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
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+ #else
*type = tstate->exc_type;
*value = tstate->exc_value;
*tb = tstate->exc_traceback;
- #endif
Py_XINCREF(*type);
Py_XINCREF(*value);
Py_XINCREF(*tb);
+ #endif
}
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
+ #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ PyObject *tmp_value = exc_info->exc_value;
+ exc_info->exc_value = value;
+ Py_XDECREF(tmp_value);
+ // TODO: avoid passing these at all
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ #else
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;
@@ -524,6 +610,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
+ #endif
}
#endif
@@ -543,8 +630,22 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
#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
+ #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ tmp_value = exc_info->exc_value;
+ exc_info->exc_value = *value;
+ if (tmp_value == NULL || tmp_value == Py_None) {
+ Py_XDECREF(tmp_value);
+ tmp_value = NULL;
+ tmp_type = NULL;
+ tmp_tb = NULL;
+ } else {
+ // TODO: avoid swapping these at all
+ tmp_type = (PyObject*) Py_TYPE(tmp_value);
+ Py_INCREF(tmp_type);
+ tmp_tb = PyException_GetTraceback(tmp_value);
+ }
+ #elif CYTHON_USE_EXC_INFO_STACK
_PyErr_StackItem *exc_info = tstate->exc_info;
tmp_type = exc_info->exc_type;
tmp_value = exc_info->exc_value;
@@ -553,7 +654,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject *
exc_info->exc_type = *type;
exc_info->exc_value = *value;
exc_info->exc_traceback = *tb;
- #else
+ #else
tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value;
tmp_tb = tstate->exc_traceback;
@@ -561,7 +662,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject *
tstate->exc_type = *type;
tstate->exc_value = *value;
tstate->exc_traceback = *tb;
- #endif
+ #endif
*type = tmp_type;
*value = tmp_value;
@@ -590,9 +691,9 @@ static void __Pyx_WriteUnraisable(const char *name, int clineno,
//@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) {
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback, int nogil) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
__Pyx_PyThreadState_declare
@@ -600,9 +701,14 @@ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
PyGILState_STATE state;
if (nogil)
state = PyGILState_Ensure();
- /* initalize to suppress warning */
+ /* arbitrary, to suppress warning */
else state = (PyGILState_STATE)0;
#endif
+ CYTHON_UNUSED_VAR(clineno);
+ CYTHON_UNUSED_VAR(lineno);
+ CYTHON_UNUSED_VAR(filename);
+ CYTHON_MAYBE_UNUSED_VAR(nogil);
+
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
if (full_traceback) {
@@ -639,19 +745,21 @@ static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line);/*proto*/
#endif
/////////////// CLineInTraceback ///////////////
-//@requires: ObjectHandling.c::PyObjectGetAttrStr
+//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: ObjectHandling.c::PyDictVersioning
//@requires: PyErrFetchRestore
//@substitute: naming
#ifndef CYTHON_CLINE_IN_TRACEBACK
-static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) {
+static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) {
PyObject *use_cline;
PyObject *ptype, *pvalue, *ptraceback;
#if CYTHON_COMPILING_IN_CPYTHON
PyObject **cython_runtime_dict;
#endif
+ CYTHON_MAYBE_UNUSED_VAR(tstate);
+
if (unlikely(!${cython_runtime_cname})) {
// Very early error where the runtime module is not set up yet.
return c_line;
@@ -668,7 +776,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li
} else
#endif
{
- PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
+ PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(${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);
@@ -710,6 +818,17 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
#include "internal/pycore_frame.h"
#endif
+#if CYTHON_COMPILING_IN_LIMITED_API
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ if (c_line) {
+ // Avoid "unused" warning as long as we don't use this.
+ (void) $cfilenm_cname;
+ (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line);
+ }
+ _PyTraceback_Add(funcname, filename, py_line);
+}
+#else
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
const char *funcname, int c_line,
int py_line, const char *filename) {
@@ -742,6 +861,7 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
#if PY_MAJOR_VERSION < 3
py_code = __Pyx_PyCode_New(
0, /*int argcount,*/
+ 0, /*int posonlyargcount,*/
0, /*int kwonlyargcount,*/
0, /*int nlocals,*/
0, /*int stacksize,*/
@@ -812,3 +932,4 @@ bad:
Py_XDECREF(py_code);
Py_XDECREF(py_frame);
}
+#endif