mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
bpo-45711: Change exc_info related APIs to derive type and traceback from the exception instance (GH-29780)
This commit is contained in:
parent
af8c8caaf5
commit
8a45ca542a
7 changed files with 103 additions and 35 deletions
|
@ -470,6 +470,33 @@ PyErr_Clear(void)
|
|||
_PyErr_Clear(tstate);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_exc_type(PyObject *exc_value) /* returns a borrowed ref */
|
||||
{
|
||||
if (exc_value == NULL || exc_value == Py_None) {
|
||||
return Py_None;
|
||||
}
|
||||
else {
|
||||
assert(PyExceptionInstance_Check(exc_value));
|
||||
PyObject *type = PyExceptionInstance_Class(exc_value);
|
||||
assert(type != NULL);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_exc_traceback(PyObject *exc_value) /* returns a borrowed ref */
|
||||
{
|
||||
if (exc_value == NULL || exc_value == Py_None) {
|
||||
return Py_None;
|
||||
}
|
||||
else {
|
||||
assert(PyExceptionInstance_Check(exc_value));
|
||||
PyObject *tb = PyException_GetTraceback(exc_value);
|
||||
Py_XDECREF(tb);
|
||||
return tb ? tb : Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_PyErr_GetExcInfo(PyThreadState *tstate,
|
||||
|
@ -477,18 +504,9 @@ _PyErr_GetExcInfo(PyThreadState *tstate,
|
|||
{
|
||||
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
|
||||
|
||||
*p_type = get_exc_type(exc_info->exc_value);
|
||||
*p_value = exc_info->exc_value;
|
||||
*p_traceback = exc_info->exc_traceback;
|
||||
|
||||
if (*p_value == NULL || *p_value == Py_None) {
|
||||
assert(exc_info->exc_type == NULL || exc_info->exc_type == Py_None);
|
||||
*p_type = Py_None;
|
||||
}
|
||||
else {
|
||||
assert(PyExceptionInstance_Check(*p_value));
|
||||
assert(exc_info->exc_type == PyExceptionInstance_Class(*p_value));
|
||||
*p_type = PyExceptionInstance_Class(*p_value);
|
||||
}
|
||||
*p_traceback = get_exc_traceback(exc_info->exc_value);
|
||||
|
||||
Py_XINCREF(*p_type);
|
||||
Py_XINCREF(*p_value);
|
||||
|
@ -504,7 +522,7 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
|
|||
}
|
||||
|
||||
void
|
||||
PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
|
||||
PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
|
||||
{
|
||||
PyObject *oldtype, *oldvalue, *oldtraceback;
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
@ -513,9 +531,16 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
|
|||
oldvalue = tstate->exc_info->exc_value;
|
||||
oldtraceback = tstate->exc_info->exc_traceback;
|
||||
|
||||
tstate->exc_info->exc_type = p_type;
|
||||
tstate->exc_info->exc_value = p_value;
|
||||
tstate->exc_info->exc_traceback = p_traceback;
|
||||
|
||||
tstate->exc_info->exc_type = get_exc_type(value);
|
||||
Py_XINCREF(tstate->exc_info->exc_type);
|
||||
tstate->exc_info->exc_value = value;
|
||||
tstate->exc_info->exc_traceback = get_exc_traceback(value);
|
||||
Py_XINCREF(tstate->exc_info->exc_traceback);
|
||||
|
||||
/* These args are no longer used, but we still need to steal a ref */
|
||||
Py_XDECREF(type);
|
||||
Py_XDECREF(traceback);
|
||||
|
||||
Py_XDECREF(oldtype);
|
||||
Py_XDECREF(oldvalue);
|
||||
|
@ -527,22 +552,19 @@ PyObject*
|
|||
_PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
|
||||
{
|
||||
PyObject *exc_value = err_info->exc_value;
|
||||
if (exc_value == NULL) {
|
||||
exc_value = Py_None;
|
||||
}
|
||||
|
||||
assert(exc_value == Py_None || PyExceptionInstance_Check(exc_value));
|
||||
assert(exc_value == NULL ||
|
||||
exc_value == Py_None ||
|
||||
PyExceptionInstance_Check(exc_value));
|
||||
|
||||
PyObject *exc_type = PyExceptionInstance_Check(exc_value) ?
|
||||
PyExceptionInstance_Class(exc_value) :
|
||||
Py_None;
|
||||
PyObject *exc_type = get_exc_type(exc_value);
|
||||
PyObject *exc_traceback = get_exc_traceback(exc_value);
|
||||
|
||||
return Py_BuildValue(
|
||||
"(OOO)",
|
||||
exc_type,
|
||||
exc_value,
|
||||
err_info->exc_traceback != NULL ?
|
||||
err_info->exc_traceback : Py_None);
|
||||
exc_type ? exc_type : Py_None,
|
||||
exc_value ? exc_value : Py_None,
|
||||
exc_traceback ? exc_traceback : Py_None);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue