Commit 77695702 authored by scoder's avatar scoder Committed by GitHub

Adapt to "exc_info" changes in CPython 3.11a4 (GH-4584)

Adapt to "exc_info" changes in CPython 3.11a4, where "->exc_type" and "->exc_traceback" are gone and now get inferred from "->exc_value".

Closes https://github.com/cython/cython/issues/4500
parent 9d038fb3
...@@ -601,6 +601,9 @@ static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *$local_tstate_cna ...@@ -601,6 +601,9 @@ static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *$local_tstate_cna
static CYTHON_INLINE static CYTHON_INLINE
void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) {
#if PY_VERSION_HEX >= 0x030B00a4
Py_CLEAR(exc_state->exc_value);
#else
PyObject *t, *v, *tb; PyObject *t, *v, *tb;
t = exc_state->exc_type; t = exc_state->exc_type;
v = exc_state->exc_value; v = exc_state->exc_value;
...@@ -613,6 +616,7 @@ void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { ...@@ -613,6 +616,7 @@ void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) {
Py_XDECREF(t); Py_XDECREF(t);
Py_XDECREF(v); Py_XDECREF(v);
Py_XDECREF(tb); Py_XDECREF(tb);
#endif
} }
#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) #define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL)
...@@ -718,14 +722,21 @@ PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, i ...@@ -718,14 +722,21 @@ PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, i
// - do not touch external frames and tracebacks // - do not touch external frames and tracebacks
exc_state = &self->gi_exc_state; exc_state = &self->gi_exc_state;
if (exc_state->exc_type) { if (exc_state->exc_value) {
#if CYTHON_COMPILING_IN_PYPY #if CYTHON_COMPILING_IN_PYPY
// FIXME: what to do in PyPy? // FIXME: what to do in PyPy?
#else #else
// Generators always return to their most recent caller, not // Generators always return to their most recent caller, not
// necessarily their creator. // necessarily their creator.
if (exc_state->exc_traceback) { PyObject *exc_tb;
PyTracebackObject *tb = (PyTracebackObject *) exc_state->exc_traceback; #if PY_VERSION_HEX >= 0x030B00a4
// owned reference!
exc_tb = PyException_GetTraceback(exc_state->exc_value);
#else
exc_tb = exc_state->exc_traceback;
#endif
if (exc_tb) {
PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
PyFrameObject *f = tb->tb_frame; PyFrameObject *f = tb->tb_frame;
assert(f->f_back == NULL); assert(f->f_back == NULL);
...@@ -737,6 +748,9 @@ PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, i ...@@ -737,6 +748,9 @@ PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, i
Py_XINCREF(tstate->frame); Py_XINCREF(tstate->frame);
f->f_back = tstate->frame; f->f_back = tstate->frame;
#endif #endif
#if PY_VERSION_HEX >= 0x030B00a4
Py_DECREF(exc_tb);
#endif
} }
#endif #endif
} }
...@@ -778,17 +792,28 @@ static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStr ...@@ -778,17 +792,28 @@ static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStr
// Don't keep the reference to f_back any longer than necessary. It // Don't keep the reference to f_back any longer than necessary. It
// may keep a chain of frames alive or it could create a reference // may keep a chain of frames alive or it could create a reference
// cycle. // cycle.
PyObject *exc_tb = exc_state->exc_traceback;
if (likely(exc_tb)) {
#if CYTHON_COMPILING_IN_PYPY #if CYTHON_COMPILING_IN_PYPY
// FIXME: what to do in PyPy? // FIXME: what to do in PyPy?
#else #else
PyObject *exc_tb;
#if PY_VERSION_HEX >= 0x030B00a4
if (!exc_state->exc_value) return;
// owned reference!
exc_tb = PyException_GetTraceback(exc_state->exc_value);
#else
exc_tb = exc_state->exc_traceback;
#endif
if (likely(exc_tb)) {
PyTracebackObject *tb = (PyTracebackObject *) exc_tb; PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
PyFrameObject *f = tb->tb_frame; PyFrameObject *f = tb->tb_frame;
Py_CLEAR(f->f_back); Py_CLEAR(f->f_back);
#endif #if PY_VERSION_HEX >= 0x030B00a4
Py_DECREF(exc_tb);
#endif
} }
#endif
} }
static CYTHON_INLINE static CYTHON_INLINE
...@@ -1133,9 +1158,13 @@ static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { ...@@ -1133,9 +1158,13 @@ static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
} }
static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) {
#if PY_VERSION_HEX >= 0x030B00a4
Py_VISIT(exc_state->exc_value);
#else
Py_VISIT(exc_state->exc_type); Py_VISIT(exc_state->exc_type);
Py_VISIT(exc_state->exc_value); Py_VISIT(exc_state->exc_value);
Py_VISIT(exc_state->exc_traceback); Py_VISIT(exc_state->exc_traceback);
#endif
return 0; return 0;
} }
...@@ -1432,9 +1461,13 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( ...@@ -1432,9 +1461,13 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
gen->resume_label = 0; gen->resume_label = 0;
gen->classobj = NULL; gen->classobj = NULL;
gen->yieldfrom = NULL; gen->yieldfrom = NULL;
#if PY_VERSION_HEX >= 0x030B00a4
gen->gi_exc_state.exc_value = NULL;
#else
gen->gi_exc_state.exc_type = NULL; gen->gi_exc_state.exc_type = NULL;
gen->gi_exc_state.exc_value = NULL; gen->gi_exc_state.exc_value = NULL;
gen->gi_exc_state.exc_traceback = NULL; gen->gi_exc_state.exc_traceback = NULL;
#endif
#if CYTHON_USE_EXC_INFO_STACK #if CYTHON_USE_EXC_INFO_STACK
gen->gi_exc_state.previous_item = NULL; gen->gi_exc_state.previous_item = NULL;
#endif #endif
...@@ -2171,7 +2204,7 @@ static void __Pyx__ReturnWithStopIteration(PyObject* value) { ...@@ -2171,7 +2204,7 @@ static void __Pyx__ReturnWithStopIteration(PyObject* value) {
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
__Pyx_PyThreadState_assign __Pyx_PyThreadState_assign
#if CYTHON_USE_EXC_INFO_STACK #if CYTHON_USE_EXC_INFO_STACK
if (!$local_tstate_cname->exc_info->exc_type) if (!$local_tstate_cname->exc_info->exc_value)
#else #else
if (!$local_tstate_cname->exc_type) if (!$local_tstate_cname->exc_type)
#endif #endif
......
...@@ -339,7 +339,7 @@ static _PyErr_StackItem * ...@@ -339,7 +339,7 @@ static _PyErr_StackItem *
__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) __Pyx_PyErr_GetTopmostException(PyThreadState *tstate)
{ {
_PyErr_StackItem *exc_info = tstate->exc_info; _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->previous_item != NULL)
{ {
exc_info = exc_info->previous_item; exc_info = exc_info->previous_item;
...@@ -405,12 +405,21 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) ...@@ -405,12 +405,21 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
#if CYTHON_USE_EXC_INFO_STACK #if CYTHON_USE_EXC_INFO_STACK
{ {
_PyErr_StackItem *exc_info = tstate->exc_info; _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_type = exc_info->exc_type;
tmp_value = exc_info->exc_value; tmp_value = exc_info->exc_value;
tmp_tb = exc_info->exc_traceback; tmp_tb = exc_info->exc_traceback;
exc_info->exc_type = local_type; exc_info->exc_type = local_type;
exc_info->exc_value = local_value; exc_info->exc_value = local_value;
exc_info->exc_traceback = local_tb; exc_info->exc_traceback = local_tb;
#endif
} }
#else #else
tmp_type = tstate->exc_type; tmp_type = tstate->exc_type;
...@@ -450,35 +459,44 @@ static CYTHON_INLINE void __Pyx_ReraiseException(void) { ...@@ -450,35 +459,44 @@ static CYTHON_INLINE void __Pyx_ReraiseException(void) {
PyObject *type = NULL, *value = NULL, *tb = NULL; PyObject *type = NULL, *value = NULL, *tb = NULL;
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
PyThreadState *tstate = PyThreadState_GET(); PyThreadState *tstate = PyThreadState_GET();
#if CYTHON_USE_EXC_INFO_STACK #if CYTHON_USE_EXC_INFO_STACK
_PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
type = exc_info->exc_type;
value = exc_info->exc_value; 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 #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; type = tstate->exc_type;
value = tstate->exc_value; value = tstate->exc_value;
tb = tstate->exc_traceback; tb = tstate->exc_traceback;
#endif Py_XINCREF(type);
Py_XINCREF(value);
Py_XINCREF(tb);
#endif
#else #else
PyErr_GetExcInfo(&type, &value, &tb); PyErr_GetExcInfo(&type, &value, &tb);
#endif #endif
if (!type || type == Py_None) { if (unlikely(!type || type == Py_None)) {
#if !CYTHON_FAST_THREAD_STATE
Py_XDECREF(type); Py_XDECREF(type);
Py_XDECREF(value); Py_XDECREF(value);
Py_XDECREF(tb); Py_XDECREF(tb);
#endif
// message copied from Py3 // message copied from Py3
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"No active exception to reraise"); "No active exception to reraise");
} else { } else {
#if CYTHON_FAST_THREAD_STATE
Py_INCREF(type);
Py_XINCREF(value);
Py_XINCREF(tb);
#endif
PyErr_Restore(type, value, tb); PyErr_Restore(type, value, tb);
} }
} }
...@@ -504,24 +522,49 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject ...@@ -504,24 +522,49 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { 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); _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
*type = exc_info->exc_type; *type = exc_info->exc_type;
*value = exc_info->exc_value; *value = exc_info->exc_value;
*tb = exc_info->exc_traceback; *tb = exc_info->exc_traceback;
#else Py_XINCREF(*type);
Py_XINCREF(*value);
Py_XINCREF(*tb);
#else
*type = tstate->exc_type; *type = tstate->exc_type;
*value = tstate->exc_value; *value = tstate->exc_value;
*tb = tstate->exc_traceback; *tb = tstate->exc_traceback;
#endif
Py_XINCREF(*type); Py_XINCREF(*type);
Py_XINCREF(*value); Py_XINCREF(*value);
Py_XINCREF(*tb); Py_XINCREF(*tb);
#endif
} }
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { 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; PyObject *tmp_type, *tmp_value, *tmp_tb;
#if CYTHON_USE_EXC_INFO_STACK #if CYTHON_USE_EXC_INFO_STACK
_PyErr_StackItem *exc_info = tstate->exc_info; _PyErr_StackItem *exc_info = tstate->exc_info;
tmp_type = exc_info->exc_type; tmp_type = exc_info->exc_type;
...@@ -541,6 +584,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject ...@@ -541,6 +584,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
Py_XDECREF(tmp_type); Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value); Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb); Py_XDECREF(tmp_tb);
#endif
} }
#endif #endif
...@@ -560,8 +604,22 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, ...@@ -560,8 +604,22 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb; PyObject *tmp_type, *tmp_value, *tmp_tb;
#if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4
#if CYTHON_USE_EXC_INFO_STACK _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; _PyErr_StackItem *exc_info = tstate->exc_info;
tmp_type = exc_info->exc_type; tmp_type = exc_info->exc_type;
tmp_value = exc_info->exc_value; tmp_value = exc_info->exc_value;
...@@ -570,7 +628,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject * ...@@ -570,7 +628,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject *
exc_info->exc_type = *type; exc_info->exc_type = *type;
exc_info->exc_value = *value; exc_info->exc_value = *value;
exc_info->exc_traceback = *tb; exc_info->exc_traceback = *tb;
#else #else
tmp_type = tstate->exc_type; tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value; tmp_value = tstate->exc_value;
tmp_tb = tstate->exc_traceback; tmp_tb = tstate->exc_traceback;
...@@ -578,7 +636,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject * ...@@ -578,7 +636,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject *
tstate->exc_type = *type; tstate->exc_type = *type;
tstate->exc_value = *value; tstate->exc_value = *value;
tstate->exc_traceback = *tb; tstate->exc_traceback = *tb;
#endif #endif
*type = tmp_type; *type = tmp_type;
*value = tmp_value; *value = tmp_value;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment