]> granicus.if.org Git - python/commitdiff
Use _PyObject_CallMethodIdObjArgs() in _ctypes
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 9 Dec 2016 14:18:31 +0000 (15:18 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Fri, 9 Dec 2016 14:18:31 +0000 (15:18 +0100)
Issue #28915: Replace _PyObject_CallMethodId() with
_PyObject_CallMethodIdObjArgs() in unpickle(). _PyObject_CallMethodIdObjArgs()
avoids the creation of a temporary tuple and doesn't have to parse a format
string.

Replace _PyObject_CallMethodId() with _PyObject_GetAttrId()+PyObject_Call() for
the second call since it requires to "unpack" a tuple.

Add also a check in the type of the second parameter (state): it must be a
tuple.

Modules/_ctypes/callproc.c

index 7d542fb50d876705acac452039c2f2bd360930cf..f408fd33ee2bc05b48d8330e8d8596f652e58a89 100644 (file)
@@ -1631,25 +1631,33 @@ resize(PyObject *self, PyObject *args)
 static PyObject *
 unpickle(PyObject *self, PyObject *args)
 {
-    PyObject *typ;
-    PyObject *state;
-    PyObject *result;
-    PyObject *tmp;
+    PyObject *typ, *state, *meth, *obj, *result;
     _Py_IDENTIFIER(__new__);
     _Py_IDENTIFIER(__setstate__);
 
-    if (!PyArg_ParseTuple(args, "OO", &typ, &state))
+    if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state))
         return NULL;
-    result = _PyObject_CallMethodId(typ, &PyId___new__, "O", typ);
-    if (result == NULL)
-        return NULL;
-    tmp = _PyObject_CallMethodId(result, &PyId___setstate__, "O", state);
-    if (tmp == NULL) {
-        Py_DECREF(result);
+    obj = _PyObject_CallMethodIdObjArgs(typ, &PyId___new__, typ, NULL);
+    if (obj == NULL)
         return NULL;
+
+    meth = _PyObject_GetAttrId(obj, &PyId___setstate__);
+    if (meth == NULL) {
+        goto error;
     }
-    Py_DECREF(tmp);
-    return result;
+
+    result = PyObject_Call(meth, state, NULL);
+    Py_DECREF(meth);
+    if (result == NULL) {
+        goto error;
+    }
+    Py_DECREF(result);
+
+    return obj;
+
+error:
+    Py_DECREF(obj);
+    return NULL;
 }
 
 static PyObject *