mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Add _PyErr_CreateException()
Issue #27809: Helper function optimized to create an exception: use fastcall whenever possible.
This commit is contained in:
parent
463b86a881
commit
3a84097291
1 changed files with 29 additions and 30 deletions
|
@ -52,6 +52,20 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
|
||||||
Py_XDECREF(oldtraceback);
|
Py_XDECREF(oldtraceback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
_PyErr_CreateException(PyObject *exception, PyObject *value)
|
||||||
|
{
|
||||||
|
if (value == NULL || value == Py_None) {
|
||||||
|
return _PyObject_CallNoArg(exception);
|
||||||
|
}
|
||||||
|
else if (PyTuple_Check(value)) {
|
||||||
|
return PyObject_Call(exception, value, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return _PyObject_CallArg1(exception, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PyErr_SetObject(PyObject *exception, PyObject *value)
|
PyErr_SetObject(PyObject *exception, PyObject *value)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +80,7 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
||||||
exception);
|
exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_XINCREF(value);
|
Py_XINCREF(value);
|
||||||
exc_value = tstate->exc_value;
|
exc_value = tstate->exc_value;
|
||||||
if (exc_value != NULL && exc_value != Py_None) {
|
if (exc_value != NULL && exc_value != Py_None) {
|
||||||
|
@ -73,28 +88,21 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
||||||
Py_INCREF(exc_value);
|
Py_INCREF(exc_value);
|
||||||
if (value == NULL || !PyExceptionInstance_Check(value)) {
|
if (value == NULL || !PyExceptionInstance_Check(value)) {
|
||||||
/* We must normalize the value right now */
|
/* We must normalize the value right now */
|
||||||
PyObject *args, *fixed_value;
|
PyObject *fixed_value;
|
||||||
|
|
||||||
/* Issue #23571: PyEval_CallObject() must not be called with an
|
/* Issue #23571: functions must not be called with an
|
||||||
exception set */
|
exception set */
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
||||||
if (value == NULL || value == Py_None)
|
fixed_value = _PyErr_CreateException(exception, value);
|
||||||
args = PyTuple_New(0);
|
|
||||||
else if (PyTuple_Check(value)) {
|
|
||||||
Py_INCREF(value);
|
|
||||||
args = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
args = PyTuple_Pack(1, value);
|
|
||||||
fixed_value = args ?
|
|
||||||
PyEval_CallObject(exception, args) : NULL;
|
|
||||||
Py_XDECREF(args);
|
|
||||||
Py_XDECREF(value);
|
Py_XDECREF(value);
|
||||||
if (fixed_value == NULL)
|
if (fixed_value == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
value = fixed_value;
|
value = fixed_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid reference cycles through the context chain.
|
/* Avoid reference cycles through the context chain.
|
||||||
This is O(chain length) but context chains are
|
This is O(chain length) but context chains are
|
||||||
usually very short. Sensitive readers may try
|
usually very short. Sensitive readers may try
|
||||||
|
@ -110,7 +118,8 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
||||||
o = context;
|
o = context;
|
||||||
}
|
}
|
||||||
PyException_SetContext(value, exc_value);
|
PyException_SetContext(value, exc_value);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Py_DECREF(exc_value);
|
Py_DECREF(exc_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,25 +267,15 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
|
||||||
class.
|
class.
|
||||||
*/
|
*/
|
||||||
if (!inclass || !is_subclass) {
|
if (!inclass || !is_subclass) {
|
||||||
PyObject *args, *res;
|
PyObject *fixed_value;
|
||||||
|
|
||||||
if (value == Py_None)
|
fixed_value = _PyErr_CreateException(type, value);
|
||||||
args = PyTuple_New(0);
|
if (fixed_value == NULL) {
|
||||||
else if (PyTuple_Check(value)) {
|
goto finally;
|
||||||
Py_INCREF(value);
|
|
||||||
args = value;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
args = PyTuple_Pack(1, value);
|
|
||||||
|
|
||||||
if (args == NULL)
|
|
||||||
goto finally;
|
|
||||||
res = PyEval_CallObject(type, args);
|
|
||||||
Py_DECREF(args);
|
|
||||||
if (res == NULL)
|
|
||||||
goto finally;
|
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = res;
|
value = fixed_value;
|
||||||
}
|
}
|
||||||
/* if the class of the instance doesn't exactly match the
|
/* if the class of the instance doesn't exactly match the
|
||||||
class of the type, believe the instance
|
class of the type, believe the instance
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue