[Python-checkins] cpython: Add _PyErr_CreateException()

victor.stinner python-checkins at python.org
Mon Aug 22 18:32:46 EDT 2016


https://hg.python.org/cpython/rev/0c65a2089f00
changeset:   102847:0c65a2089f00
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Mon Aug 22 23:59:08 2016 +0200
summary:
  Add _PyErr_CreateException()

Issue #27809: Helper function optimized to create an exception: use fastcall
whenever possible.

files:
  Python/errors.c |  61 ++++++++++++++++++------------------
  1 files changed, 30 insertions(+), 31 deletions(-)


diff --git a/Python/errors.c b/Python/errors.c
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -52,6 +52,20 @@
     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 @@
                      exception);
         return;
     }
+
     Py_XINCREF(value);
     exc_value = tstate->exc_value;
     if (exc_value != NULL && exc_value != Py_None) {
@@ -73,28 +88,21 @@
         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;
+            fixed_value = _PyErr_CreateException(exception, value);
+            Py_XDECREF(value);
+            if (fixed_value == NULL) {
+                return;
             }
-            else
-                args = PyTuple_Pack(1, value);
-            fixed_value = args ?
-                PyEval_CallObject(exception, args) : NULL;
-            Py_XDECREF(args);
-            Py_XDECREF(value);
-            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 @@
                 o = context;
             }
             PyException_SetContext(value, exc_value);
-        } else {
+        }
+        else {
             Py_DECREF(exc_value);
         }
     }
@@ -258,25 +267,15 @@
            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

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list