summaryrefslogtreecommitdiffstats
path: root/Objects/call.c
diff options
context:
space:
mode:
authorINADA Naoki <methane@users.noreply.github.com>2017-03-14 09:00:59 (GMT)
committerGitHub <noreply@github.com>2017-03-14 09:00:59 (GMT)
commitaa289a59ff6398110e1122877c073c9354ee53db (patch)
tree9861df74503cb7556be87ec43642efb5c4790748 /Objects/call.c
parent7e2a54cdd977078b40b82182e46b201f8163f659 (diff)
downloadcpython-aa289a59ff6398110e1122877c073c9354ee53db.zip
cpython-aa289a59ff6398110e1122877c073c9354ee53db.tar.gz
cpython-aa289a59ff6398110e1122877c073c9354ee53db.tar.bz2
bpo-29548: Recommend PyObject_Call APIs over PyEval_Call APIs. (GH-75)
PyEval_Call* APIs are not documented and they doesn't respect PY_SSIZE_T_CLEAN. So add comment block which recommends PyObject_Call* APIs to ceval.h. This commit also changes PyEval_CallMethod and PyEval_CallFunction implementation same to PyObject_CallMethod and PyObject_CallFunction to reduce future maintenance cost. Optimization to avoid temporary tuple are copied too. PyEval_CallFunction(callable, "i", (int)i) now calls callable(i) instead of raising TypeError. But accepting this edge case is backward compatible.
Diffstat (limited to 'Objects/call.c')
-rw-r--r--Objects/call.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/Objects/call.c b/Objects/call.c
index a4af816..f1b1408 100644
--- a/Objects/call.c
+++ b/Objects/call.c
@@ -940,25 +940,20 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...)
}
+/* PyEval_CallFunction is exact copy of PyObject_CallFunction.
+ * This function is kept for backward compatibility.
+ */
PyObject *
PyEval_CallFunction(PyObject *callable, const char *format, ...)
{
- va_list vargs;
- PyObject *args;
- PyObject *res;
-
- va_start(vargs, format);
-
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
-
- if (args == NULL)
- return NULL;
+ va_list va;
+ PyObject *result;
- res = PyEval_CallObject(callable, args);
- Py_DECREF(args);
+ va_start(va, format);
+ result = _PyObject_CallFunctionVa(callable, format, va, 0);
+ va_end(va);
- return res;
+ return result;
}
@@ -1015,33 +1010,29 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
}
+/* PyEval_CallMethod is exact copy of PyObject_CallMethod.
+ * This function is kept for backward compatibility.
+ */
PyObject *
PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...)
{
- va_list vargs;
- PyObject *meth;
- PyObject *args;
- PyObject *res;
-
- meth = PyObject_GetAttrString(obj, name);
- if (meth == NULL)
- return NULL;
-
- va_start(vargs, format);
+ va_list va;
+ PyObject *callable, *retval;
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
+ if (obj == NULL || name == NULL) {
+ return null_error();
+ }
- if (args == NULL) {
- Py_DECREF(meth);
+ callable = PyObject_GetAttrString(obj, name);
+ if (callable == NULL)
return NULL;
- }
- res = PyEval_CallObject(meth, args);
- Py_DECREF(meth);
- Py_DECREF(args);
+ va_start(va, format);
+ retval = callmethod(callable, format, va, 0);
+ va_end(va);
- return res;
+ Py_DECREF(callable);
+ return retval;
}