8000 Add _PyErr_CreateException() · python/cpython@3a84097 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 /div>

Commit 3a84097

Browse files
committed
Add _PyErr_CreateException()
Issue #27809: Helper function optimized to create an exception: use fastcall whenever possible.
1 parent 463b86a commit 3a84097

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

Python/errors.c

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
5252
Py_XDECREF(oldtraceback);
5353
}
5454

55+
static PyObject*
56+
_PyErr_CreateException(PyObject *exception, PyObject *value)
57+
{
58+
if (value == NULL || value == Py_None) {
59+
return _PyObject_CallNoArg(exception);
60+
}
61+
else if (PyTuple_Check(value)) {
62+
return PyObject_Call(exception, value, NULL);
63+
}
64+
else {
65+
return _PyObject_CallArg1(exception, value);
66+
}
67+
}
68+
5569
void
5670
PyErr_SetObject(PyObject *exception, PyObject *value)
5771
{
@@ -66,35 +80,29 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
6680
exception);
6781
return;
6882
}
83+
6984
Py_XINCREF(value);
7085
exc_value = tstate->exc_value;
7186
if (exc_value != NULL && exc_value != Py_None) {
7287
/* Implicit exception chaining */
7388
Py_INCREF(exc_value);
7489
if (value == NULL || !PyExceptionInstance_Check(value)) {
7590
/* We must normalize the va 10000 lue right now */
76-
PyObject *args, *fixed_value;
91+
PyObject *fixed_value;
7792

78-
/* Issue #23571: PyEval_CallObject() must not be called with an
93+
/* Issue #23571: functions must not be called with an
7994
exception set */
8095
PyErr_Clear();
8196

82-
if (value == NULL || value == Py_None)
83-
args = PyTuple_New(0);
84-
else if (PyTuple_Check(value)) {
85-
Py_INCREF(value);
86-
args = value;
87-
}
88-
else
89-
args = PyTuple_Pack(1, value);
90-
fixed_value = args ?
91-
PyEval_CallObject(exception, args) : NULL;
92-
Py_XDECREF(args);
97+
fixed_value = _PyErr_CreateException(exception, value);
9398
Py_XDECREF(value);
94-
if (fixed_value == NULL)
99+
if (fixed_value == NULL) {
95100
return;
101+
}
102+
96103
value = fixed_value;
97104
}
105+
98106
/* Avoid reference cycles through the context chain.
99107
This is O(chain length) but context chains are
100108
usually very short. Sensitive readers may try
@@ -110,7 +118,8 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
110118
o = context;
111119
}
112120
PyException_SetContext(value, exc_value);
113-
} else {
121+
}
122+
else {
114123
Py_DECREF(exc_value);
115124
}
116125
}
@@ -258,25 +267,15 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
258267
class.
259268
*/
260269
if (!inclass || !is_subclass) {
261-
PyObject *args, *res;
270+
PyObject *fixed_value;
262271

263-
if (value == Py_None)
264-
args = PyTuple_New(0);
265-
else if (PyTuple_Check(value)) {
266-
Py_INCREF(value);
267-
args = value;
272+
fixed_value = _PyErr_CreateException(type, value);
273+
if (fixed_value == NULL) {
274+
goto finally;
268275
}
269-
else
270-
args = PyTuple_Pack(1, value);
271276

272-
if (args == NULL)
273-
goto finally;
274-
res = PyEval_CallObject(type, args);
275-
Py_DECREF(args);
276-
if (res == NULL)
277-
goto finally;
278277
Py_DECREF(value);
279-
value = res;
278+
value = fixed_value;
280279
}
281280
/* if the class of the instance doesn't exactly match the
282281
class of the type, believe the instance

0 commit comments

Comments
 (0)
0