Kaydet (Commit) 3a840972 authored tarafından Victor Stinner's avatar Victor Stinner

Add _PyErr_CreateException()

Issue #27809: Helper function optimized to create an exception: use fastcall
whenever possible.
üst 463b86a8
...@@ -52,6 +52,20 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
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