]> granicus.if.org Git - python/commitdiff
Add _PyErr_CreateException()
authorVictor Stinner <victor.stinner@gmail.com>
Mon, 22 Aug 2016 21:59:08 +0000 (23:59 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Mon, 22 Aug 2016 21:59:08 +0000 (23:59 +0200)
Issue #27809: Helper function optimized to create an exception: use fastcall
whenever possible.

Python/errors.c

index e151cab17cb56be1a38b9d5af46fa86adcf7083d..956e4fa583ae2f543169b3b0064491a108b3a560 100644 (file)
@@ -52,6 +52,20 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
     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
 PyErr_SetObject(PyObject *exception, PyObject *value)
 {
@@ -66,6 +80,7 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
                      exception);
         return;
     }
+
     Py_XINCREF(value);
     exc_value = tstate->exc_value;
     if (exc_value != NULL && exc_value != Py_None) {
@@ -73,28 +88,21 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
         Py_INCREF(exc_value);
         if (value == NULL || !PyExceptionInstance_Check(value)) {
             /* 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 */
             PyErr_Clear();
 
-            if (value == NULL || value == Py_None)
-                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);
+            fixed_value = _PyErr_CreateException(exception, value);
             Py_XDECREF(value);
-            if (fixed_value == NULL)
+            if (fixed_value == NULL) {
                 return;
+            }
+
             value = fixed_value;
         }
+
         /* Avoid reference cycles through the context chain.
            This is O(chain length) but context chains are
            usually very short. Sensitive readers may try
@@ -110,7 +118,8 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
                 o = context;
             }
             PyException_SetContext(value, exc_value);
-        } else {
+        }
+        else {
             Py_DECREF(exc_value);
         }
     }
@@ -258,25 +267,15 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
            class.
         */
         if (!inclass || !is_subclass) {
-            PyObject *args, *res;
+            PyObject *fixed_value;
 
-            if (value == Py_None)
-                args = PyTuple_New(0);
-            else if (PyTuple_Check(value)) {
-                Py_INCREF(value);
-                args = value;
+            fixed_value = _PyErr_CreateException(type, value);
+            if (fixed_value == NULL) {
+                goto finally;
             }
-            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);
-            value = res;
+            value = fixed_value;
         }
         /* if the class of the instance doesn't exactly match the
            class of the type, believe the instance